Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

User supplied arguments for ordering a data.frame using arrange

Tags:

r

plyr

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.

like image 724
user1701545 Avatar asked Mar 19 '14 23:03

user1701545


People also ask

What does arrange () do in R?

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.

What is the use of Arrange () with dplyr package?

arrange() orders the rows of a data frame by the values of selected columns.

How do you arrange data in ascending order in R?

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.

How do you arrange a DataFrame in ascending order in Python?

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.


1 Answers

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
like image 176
mnel Avatar answered Sep 24 '22 19:09

mnel