arrange() doesn't recognize column name parameter

后端 未结 2 1998
闹比i
闹比i 2021-01-03 06:02

Within R, I use dplyr and more specifically arrange(). Somehow the arrange function doesn\'t work as expected.

In the example

相关标签:
2条回答
  • 2021-01-03 06:51

    An update is necessary to the good answer by @avid_useR because 'rlang::parse_quosure' is deprecated now.

    To give a short answer to the question how to make 'dplyr::arrange' accept a string or variable containing a string for the column name to sort, you can do:

    target_column = rlang::sym('mean_age')
    df %>% group_by(state) %>% arrange(!!target_column)
    

    OR as one-liner (if you only need to use it once):

    df %>% group_by(state) %>% arrange(!!rlang::sym(target_column))
    
    0 讨论(0)
  • 2021-01-03 07:03

    You need to first parse your string argument to a quosure, then unquote it with !!:

    library(dplyr)
    library(rlang)
    
    target_column = 'mean_age'
    
    my_function <- function(target_column, number){
        target_quo = parse_quosure(target_column)
    
        df <- read.csv('file.csv', stringsAsFactors=FALSE)
        df <- df[, c(1,4,10)]
        names(df) <-  c('place','state','mean_age')
        df1 <- df %>% group_by(state) %>% arrange(!!target_quo) 
        df1 %>% summarise(rank = nth(target_column, number))        
    }
    
    my_function('mean_age', 10)
    

    If you want to be able to supply target_column as an unquoted column name, you can use enquo instead:

    my_function <- function(target_column, number){
        target_quo = enquo(target_column)
    
        df <- read.csv('file.csv', stringsAsFactors=FALSE)
        df <- df[, c(1,4,10)]
        names(df) <-  c('place','state','mean_age')
        df1 <- df %>% group_by(state) %>% arrange(!!target_quo) 
        df1 %>% summarise(rank = nth(target_column, number))        
    }
    
    my_function(mean_age, 10)
    

    Note:

    Normally, enquo will also work for string arguments, but arrange itself does not allow it, so the following does not work for the second example:

    my_function('mean_age', 10)
    

    Below is a toy example to demonstrate what I mean, since OP's question is not reproducible:

    library(dplyr)
    library(rlang)
    
    test_func = function(var){
        var_quo = parse_quosure(var)
        mtcars %>%
          select(!!var_quo) %>%
          arrange(!!var_quo)
    }
    
    test_func2 = function(var){
      var_quo = enquo(var)
      mtcars %>%
        select(!!var_quo) %>%
        arrange(!!var_quo)
    }
    

    Results:

    > test_func("mpg") %>%
    +   head()
       mpg
    1 10.4
    2 10.4
    3 13.3
    4 14.3
    5 14.7
    6 15.0
    
    > test_func2(mpg) %>%
    +   head()
       mpg
    1 10.4
    2 10.4
    3 13.3
    4 14.3
    5 14.7
    6 15.0
    
    > test_func2("mpg") %>%
    +   head()
    

    Error in arrange_impl(.data, dots) : incorrect size (1) at position 1, expecting : 32

    0 讨论(0)
提交回复
热议问题