Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use dplyr::arrange(desc()) when using a string as column name?

Tags:

r

dplyr

How can I use dplyr::arrange(dplyr::desc()) and pass in a string as the column name?

Here is a sample dataset:

df <- data.frame(a = 1:3, b = 3:1)

Examples that work:

df %>% dplyr::arrange(b)
df %>% dplyr::arrange_("b")
df %>% dplyr::arrange(dplyr::desc(b))

But I can't seem to use a string with both arrange and desc, these are the two version I tried that don't work:

df %>% dplyr::arrange(dplyr::desc("b"))
df %>% dplyr::arrange_(dplyr::desc("b"))

Thanks!

like image 858
DeanAttali Avatar asked Nov 20 '14 08:11

DeanAttali


People also ask

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

arrange() orders the rows of a data frame by the values of selected columns. Unlike other dplyr verbs, arrange() largely ignores grouping; you need to explicitly mention grouping variables (or use .

How do I arrange DESC 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 in ascending order in R dplyr?

By default, dplyr arrange() function orders in ascending order however, you can change this in R and arrange the dataframe in descending/decreasing order by using desc() function.

What is 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.


1 Answers

tl;dr : df %>% arrange(desc(!!sym("b")))

First of all the standard evaluations of dplyr verbs are deprecated, so instead of:

library(dplyr)
x <- "b"
df %>% arrange_(x)

it is now recommended to type:

library(dplyr)
library(rlang)
df %>% arrange(!!sym(x))

See ?arrange_ , it links to a help topic named Deprecated SE versions of main verbs. and offers some details.

From there to sort descending it is straightforward to adapt the new formulation :

df %>% arrange(desc(!!sym(x)))

These work as well if your data is not grouped:

df %>% arrange(desc(.[[x]]))
df %>% arrange(desc(.data[[x]]))

FYI, to make it work with arrange_ we could have done the following, better use the approach above however!

df %>% arrange_(paste0("desc(",x,")"))

Which can be simplified if we have numeric variables like in OP's example:

df %>% arrange_(paste0("-",x))

Or using lazyeval::interp

df %>% arrange_(interp(~desc(y),y=as.name(x)))

Or as @shyam-saladi proposes:

desc_ <- function(x) lazyeval::interp(~desc(var), var = as.name(x))
# or just
# desc_ <- function(x) paste0("desc(",x,")")
df %>% arrange_(desc_(x))
like image 66
Moody_Mudskipper Avatar answered Sep 29 '22 20:09

Moody_Mudskipper