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!
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 .
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.
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.
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.
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))
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