Suppose I have this data.frame
:
df = data.frame(strain=c("I","I","R","R"),sex=c("M","F","M","F"),age=c("8d","8d","64d","64d"))
and a user supplied data.frame
that defines how to order df
. For example:
order.df = data.frame(column = c("age","sex","strain"),order = c("+","-","+"))
I would like to use arrange
of plyr
package to order df
according to the order defined by order.df
. If it wasn't user supplied I would just do:
arrange(df, age, desc(sex), strain)
So my question is how do I achieve that with order.df? or what ever data structure is appropriate to store the user supplied order definition so it can work with arrange.
What is the arrange() function in R? The arrange() function in R programming is used to reorder the rows of a data frame/table by using column names. These columns are passed as the expression in the function.
arrange() orders the rows of a data frame by the values of selected columns.
To sort a data frame in R, use the order( ) function. By default, sorting is ASCENDING. Prepend the sorting variable by a minus sign to indicate DESCENDING order.
To sort the DataFrame based on the values in a single column, you'll use . sort_values() . By default, this will return a new DataFrame sorted in ascending order.
Here are two approach that will probably make @hadley kill some kittens...
# 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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With