我想发布一些表,以给出观察结果的数量,并按两个变量分组。此代码工作正常。但是,在尝试将其转换为函数时遇到了问题。
我正在使用dplyr_0.7.2
使用mtcars的示例:
library(tidyverse)
tab1 <- mtcars %>% count(cyl) %>% rename(Total = n)
tab2 <- mtcars %>%
group_by(cyl, gear) %>% count %>%
spread(gear, n)
tab <- full_join(tab1, tab2, by = "cyl")
tab
# This is the output (which is what I want)
A tibble: 3 x 5
cyl Total `3` `4` `5`
<dbl> <int> <int> <int> <int>
1 4 11 1 8 2
2 6 7 2 4 1
3 8 14 12 NA 2
tab1的功能:可行
count_by_two_groups_A <- function(df, var1){
var1 <- enquo(var1)
tab1 <- df %>% count(!!var1) %>% rename(Total = n)
tab1
}
count_by_two_groups_A(mtcars, cyl)
A tibble: 3 x 2
cyl Total
<dbl> <int>
1 4 11
2 6 7
3 8 14
tab2的第一部分的功能:到现在为止都有效,但是...
count_by_two_groups_B <- function(df, var1, var2){
var1 <- enquo(var1)
var2 <- enquo(var2)
tab2 <- df %>% group_by((!!var1), (!!var2)) %>% count
tab2
}
count_by_two_groups_B(mtcars, cyl, gear)
A tibble: 8 x 3
Groups: (cyl), (gear) [8]
`(cyl)` `(gear)` n
<dbl> <dbl> <int>
1 4 3 1
2 4 4 8
3 4 5 2
4 6 3 2
5 6 4 4
6 6 5 1
7 8 3 12
8 8 5 2
列名称已更改为(cyl)和(gear)。既然列名已更改,我似乎无法弄清楚如何继续使用spread()和full_join()(或使用新列名的其他任何内容)。即我无法弄清楚如何以tidyeval方式指定新的列名,以便继续进行。我尝试了各种事情,但没有成功。
在tidyeval上下文中设置名称的通常方法是使用定义运算符:=
。它看起来像这样:
df %>%
group_by(
!! nm1 := !! var1,
!! nm2 := !! var2
) %>%
count()
为此,你需要提取nm1
的var1
。不幸的是,我还没有一种简单的方法来去除括号。我认为在即将到来的功能中执行此操作是有意义的ensym()
(如果您提供呼叫,它会捕获符号而不是保证金并发出错误)。我已经在这里提交了票证:https : //github.com/tidyverse/rlang/issues/223
幸运的是,这里有两个简单的解决方案。首先请注意,您不需要使用括号。仅当其他运算符涉及捕获的表达式时才需要它们。例如在这些情况下:
(!! var) / avg
(!! var) < value
在这种情况下,如果省略括号,!!
将尝试取消整个表达式的引用,而不仅仅是一个符号。另一方面,您的函数中没有运算符,因此您可以安全地取消引用而无需将其括起来:
count_by_two_groups_B <- function(df, var1, var2) {
var1 <- enquo(var1)
var2 <- enquo(var2)
df %>%
group_by(!! var1, !! var2) %>%
count()
}
最后,可以通过允许可变数量的参数来使函数更通用。由于点被转发,因此这甚至更容易实现,因此无需捕获和取消引用。只需将它们传递给group_by()
:
count_by <- function(df, ...) {
df %>%
group_by(...) %>%
count()
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句