假设我有这个data.frame

df = data.frame(strain=c("I","I","R","R"),sex=c("M","F","M","F"),age=c("8d","8d","64d","64d"))


用户提供的data.frame定义了如何订购df。例如:

order.df = data.frame(column = c("age","sex","strain"),order = c("+","-","+"))


我想使用arrange包的plyr根据df定义的顺序对order.df进行排序。如果不是用户提供的,我将这样做:

arrange(df, age, desc(sex), strain)


所以我的问题是我如何使用order.df做到这一点?或适用于存储用户提供的订单定义的任何数据结构,以便可以与安排一起使用。

最佳答案

这是两种可能使@hadley杀死一些小猫的方法...

# make sure that order.df contain character not factors
r <- lapply(order.df, as.character)
# create a list of names refering the columns
rl <- lapply(r[['column']],function(x)list(column = as.name(x)))
# create the appropriate list of arguments
rexp <- unname(Map (f=function(order,column){
  cm <- force(column)
  if (order =='-'){rn <-substitute(desc(column),cm)} else {
  rn <- substitute(column,cm)}
  rn
}, order=r[['order']],column = rl))



do.call(arrange, c(alist(df=df),rexp))
#  strain sex age
#1      R   M 64d
#2      R   F 64d
#3      I   M  8d
#4      I   F  8d



#alternatively, use as.quoted...
fmts <- ifelse(r[['order']]=='-', 'desc(%s)','%s')
rexp2 <- lapply(unname(Map(fmt = fmts, f= sprintf,r[['column']])),
                function(x) as.quoted(x)[[1]])

do.call(arrange, c(alist(df=df),rexp2))
#  strain sex age
#1      R   M 64d
#2      R   F 64d
#3      I   M  8d
#4      I   F  8d

07-24 09:52
查看更多