假设我有这个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