【问题标题】:Passing argument from custom function to group_by doesn't work将参数从自定义函数传递给 group_by 不起作用
【发布时间】:2021-05-04 09:26:20
【问题描述】:

我不知道为什么将自定义函数的参数传递给group_by 不起作用。我只是从数据集中传递了一个colName,当我运行我自己的函数时,就会出现错误:必须按.data 中的变量分组。 未找到列 'colName'。 在下面的示例中,我使用 R 环境中可用的 quakes 数据集:

foo <- function(data, colName) {
  
  result <- data %>%
   group_by(colName) %>%
   summarise(count = n()) 

  return(result)
}

foo(quakes, "stations")

# I also tried passing w/o commas but it is not working too:
# foo(quakes, stations)

我注意到,当我将列名显式传递给 group_by 时,它会起作用:

group_by(stations) %>%

但是,在函数中硬编码列名没有意义..

【问题讨论】:

标签: r dplyr


【解决方案1】:

这是使它工作的另一种方法。您可以将.data[[var]] 构造用于存储为字符串的列名:

foo <- function(data, colName) {
  
  result <- data %>%
    group_by(.data[[colName]]) %>%
    summarise(count = n()) 
  
  return(result)
}

foo(quakes, "stations")

# A tibble: 102 x 2
   stations count
      <int> <int>
 1       10    20
 2       11    28
 3       12    25
 4       13    21
 5       14    39
 6       15    34
 7       16    35
 8       17    38
 9       18    33
10       19    29
# ... with 92 more rows

如果您决定不将 ColName 作为字符串传递,您可以在函数内用一对花括号将其包裹起来以获得类似的结果:

foo <- function(data, colName) {
  
  result <- data %>%
    group_by({{ colName }}) %>%
    summarise(count = n()) 
  
  return(result)
}

foo(quakes, stations)

# A tibble: 102 x 2
   stations count
      <int> <int>
 1       10    20
 2       11    28
 3       12    25
 4       13    21
 5       14    39
 6       15    34
 7       16    35
 8       17    38
 9       18    33
10       19    29
# ... with 92 more rows

【讨论】:

  • 由于某些原因,您的解决方案在我的情况下效果最好。我写了一个模块化的闪亮应用程序,不知道为什么get(colName) 不起作用,但您的解决方案可以。谢谢
  • 欢迎您。 get 是检索对象值的一个非常有用的函数,但是,我想如果你要使用 tidyevaluation 编写函数,你需要使用 @Peter 先生的解决方案或我提到的那些。这些非常有用,如果您想了解更多信息,可以在控制台中输入 vignette("programming") 并阅读文档。
【解决方案2】:

我相信您只需将变量名包装在get 中。

foo <- function(data, colName) {
  
  result <- data %>%
   dplyr::group_by(get(colName)) %>%
   dplyr::summarise(count = n()) 

  return(result)
}
> foo(quakes, "stations")
# A tibble: 102 x 2
   `get(colName)` count
            <int> <int>
 1             10    20
 2             11    28
 3             12    25
 4             13    21
 5             14    39
 6             15    34
 7             16    35
 8             17    38
 9             18    33
10             19    29

【讨论】:

  • 我开发了闪亮的应用程序,不知道这是否是一个原因,但是当我使用get 时,会显示错误:问题与 mutate() 输入 ..1。 x 在当前工作目录或父目录中找不到配置文件 config.yml i 输入 ..1 是 get(colName)。无论如何,您的解决方案在闪亮的应用程序之外运行良好。
【解决方案3】:

用 dplyr 试试:

library(dplyr)

foo <- function(data, colName) {

  colName = sym(colName)
  
    result <- data %>%
    group_by(!!colName) %>%
    summarise(count = n()) 
  
  return(result)
}


foo(quakes, "stations")
#> # A tibble: 102 x 2
#>    stations count
#>       <int> <int>
#>  1       10    20
#>  2       11    28
#>  3       12    25
#>  4       13    21
#>  5       14    39
#>  6       15    34
#>  7       16    35
#>  8       17    38
#>  9       18    33
#> 10       19    29
#> # ... with 92 more rows

reprex package (v2.0.0) 于 2021-05-04 创建

【讨论】:

    【解决方案4】:

    还有一个选项是使用 ensym 并评估 (!!) 以便它可以接受带引号和不带引号的参数

    foo <- function(data, colName) {
           data %>%
             dplyr::group_by(!! rlang::ensym(colName)) %>%
             dplyr::summarise(count = n())
      }
    
    foo(quakes, stations)
    foo(quakes, "stations")
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-18
      • 1970-01-01
      • 2011-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多