r - 使用 dplyr 和 group_by 编写自己的函数 - 如何继续更改列名

标签 r dplyr rlang tidyeval

我想制作表格以提供观察次数,并按两个变量分组。这个代码工作正常。但是,我在尝试将其转换为函数时遇到了问题。

我正在使用 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() (或使用新列名的任何其他内容)。 IE。我不知道如何以整齐的方式指定新的列名,以便能够继续。我尝试了各种方法,但都没有成功。

最佳答案

在潮汐上下文中设置名称的常用方法是使用定义运算符 :=。它看起来像这样:

df %>%
  group_by(
    !! nm1 := !! var1,
    !! nm2 := !! var2
  ) %>%
  count()

为此,您需要从 var1 中提取 nm1。不幸的是,我还没有一种简单的方法来去除括号中的内容。我认为在即将到来的函数 ensym() 中这样做是有意义的(它捕获符号而不是 quosures 并在您提供调用时发出错误)。我在这里提交了一张票: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()
}

关于r - 使用 dplyr 和 group_by 编写自己的函数 - 如何继续更改列名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45407316/

相关文章:

python - 如何像使用 R hist 函数一样使用 Python 制作直方图

r - 如何旋转 r 基础包图形中的绘图?

r - 使用组大小 (`group_size` ) 在 `summarise` 在 `dplyr`

返回 tibble : how to vectorize with case_when?

r - 如何将字符串公式传递给 R 的 lm 并查看摘要中的公式?

r - 将数据从 R 传输到特定工作表和 XLSX 文件的特定范围

删除 R 中列的最后一个下划线之后的所有内容

r - 使用 tidy_eval/rlang 上下文将函数作为参数传递

r - Dplyr,非标准评估和海象算子和 curl curl

rlang::hash 无法区分箭头查询