rang()无法识别列名参数

Ely*_*kim 4 r dplyr

在R中,我使用dplyr,更具体地说arrange()。该arrange功能某种程度上无法按预期工作。

在下面的示例中,首先存储列的名称,然后将该变量作为参数传递给名为“ my_function”的自定义函数。

target_column = 'mean_age'

# below the function
my_function <- function(target_column, number){
    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_column) 
    df1 %>% summarise(rank = nth(target_column, number))        
}
Run Code Online (Sandbox Code Playgroud)

当由于输入以下内容而调用“ my_function”时,R返回错误arrange()

“ range_impl(.data,点)中的错误:位置1处的大小(1)不正确,预期为4000”

当将列名直接放入时arrange(),它会接受参数,而不是引用字符串的变量(如上述示例)。

df %>% group_by(state) %>% arrange(mean_age) 
Run Code Online (Sandbox Code Playgroud)

我如何以一种更好的方式将列名的参数传递给“ my_function”,这样arrange()才能识别它?

avi*_*seR 5

您需要首先将字符串参数解析为quosure,然后用取消引用!!

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)
Run Code Online (Sandbox Code Playgroud)

如果希望能够提供target_column不带引号的列名,则可以enquo改用:

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)
Run Code Online (Sandbox Code Playgroud)

注意:

通常,它enquo也适用于字符串参数,但arrange本身不允许这样做,因此以下示例不适用于第二个示例:

my_function('mean_age', 10)
Run Code Online (Sandbox Code Playgroud)

以下是一个玩具示例,用以说明我的意思,因为OP的问题不可重现:

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)
}
Run Code Online (Sandbox Code Playgroud)

结果:

> 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()
Run Code Online (Sandbox Code Playgroud)

Arrange_impl(.data,点)中的错误:位置1处的尺寸(1)不正确,预期为:32