如何将列名作为参数传递给dplyr动词函数?

7
我不知道为什么从自定义函数传递参数到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) %>%

不过,在函数中硬编码列名是没有意义的。


这篇帖子中的所有答案都应该有效 - https://dev59.com/91YM5IYBdhLWcg3w5zQg - Ronak Shah
4个回答

6

这里有另一种使它工作的方法。您可以使用.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

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

4

我相信你只需要用 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 时,会显示错误:_Problem with mutate() input ..1. x Config file config.yml not found in current working directory or parent directories i Input ..1 is get(colName)_。无论如何,您的解决方案在闪亮的应用程序之外都可以正常工作。 - mustafa00

3

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

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

foo(quakes, stations)
foo(quakes, "stations")

2

使用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年5月4日创建


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接