我正在尝试将dplyr\count()与动态变量名称而不是列名称一起使用。以前,我会使用count_(),但现在已弃用。最好的替代品是什么?
最小可重现示例:
\n\nlibrary(dplyr)\ndf <- data.frame(id = 1:10, city = sample(c("London","Paris","Amsterdam"), 10, replace=TRUE))\ncolname <- "city"\nRun Code Online (Sandbox Code Playgroud)\n\n这是我尝试过的:
\n\ndf %>% count( city ) # desired output (works but isn\'t dynamic)\ndf %>% count( !!colname ) # doesn\'t work, makes it literally "city"\ndf %>% count( vars(colname) ) # doesn\'t work\ndf %>% count( eval(colname) ) #\xc2\xa0doesn\'t work either\ndf %>% count( eval(parse(text=colname)) ) # works, but is not \'dplyr\' ?\ndf %>% count( eval(sym(colname)) ) # works, but using `sym` from \'rlang\'\ndf %>% count( !!as.name(colname) ) # works, but using `as.name` from \'base\'\ndf %>% count_( colname ) # works, but is deprecated\nRun Code Online (Sandbox Code Playgroud)\n\n不确定上述方法是否是首选方法,或者是否完全不同?
\n\n提前致谢!
\n\n附言。我在这里as.name()找到了解决方案。
在即将在 CRAN 上发布的 1.0 版的开发版本dplyr中,该函数似乎是合适的选择:across
df %>% count(across(colname))
Run Code Online (Sandbox Code Playgroud)
在当前的 CRAN 版本中dplyr,该group_by_at()函数可以接受一个字符串,所以你可以这样做:
df %>% group_by_at(colname) %>% tally
Run Code Online (Sandbox Code Playgroud)
如果有一个count_at便利函数,自然类似的事情就是:
df %>% count_at(colname)
Run Code Online (Sandbox Code Playgroud)
但dplyr没有count_at功能,所以不起作用。
group_by_at与 一起使用时还可以使用字符串和名称的混合vars,因此您可以这样做:
colname = "cyl"
mtcars %>% group_by_at(vars(colname, vs)) %>% tally
Run Code Online (Sandbox Code Playgroud)
group_by_at将继续在 1.0 中工作,因此您可以根据需要dplyr创建自己的函数。count_at这适用于字符串、名称,甚至两者的混合:
count_at = function(data, ...) {
data %>% group_by_at(vars(...)) %>% tally
}
colname="city"
df %>% count_at(colname)
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)city n * <fct> <int> 1 Amsterdam 3 2 London 3 3 Paris 4
mtcars %>% count_at("cyl", vs)
Run Code Online (Sandbox Code Playgroud)
Run Code Online (Sandbox Code Playgroud)cyl vs n <dbl> <dbl> <int> 1 4 0 1 2 4 1 10 3 6 0 3 4 6 1 4 5 8 0 14
!!仅仅取消引用变量名称是不够的dplyr,您还需要rlang::sym
df %>% count( !!rlang::sym(colname))
# A tibble: 3 x 2
city n
<fct> <int>
1 Amsterdam 2
2 London 7
3 Paris 1
Run Code Online (Sandbox Code Playgroud)
如果您想了解更多关于 SE 与 NSE 的内容,您可以查看我写的关于该主题的博客文章dplyr