Conditional filtering based on R factor level

I would like to clean up the following code. Specifically I'm wondering if I can combine the three filter statements so that I end up with a final data.frame (rind ()) file that contains the "spring" data string if it exists, the data string to "fall" if "spring" does not exist, and finally the data string if neither "spring" nor "fall" exist. The code below seems very clunky and inefficient. I'm trying to get rid of for (), so hopefully the solution won't be related to that. Can this be done with dplyr?

# define a %not% to be the opposite of %in%
library(dplyr)
`%not%` <- Negate(`%in%`)
f <- c("a","a","a","b","b","c")
s <- c("fall","spring","other", "fall", "other", "other")
v <- c(3,5,1,4,5,2)
(dat0 <- data.frame(f, s, v))
sp.tmp <- filter(dat0, s == "spring")
fl.tmp <- filter(dat0, f %not% sp.tmp$f, s == "fall")
ot.tmp <- filter(dat0, f %not% sp.tmp$f, f %not% fl.tmp$f, s == "other")
rbind(sp.tmp,fl.tmp,ot.tmp)

      

+1


source to share


1 answer


It looks like in each group f

you want to extract the row in descending order of preference spring

, fall

or other

.

If you first place your order of preference by the actual ordering of factors:

dat0$s <- factor(dat0$s, levels=c("spring", "fall", "other"))

      



Then you can use this dplyr solution to get the minimum row (relative to that ratio) in each group:

newdat <- dat0 %.% group_by(f) %.% filter(rank(s) == 1)

      

+3


source







All Articles