在R NSE中使用带有空参数的quos

时间:2018-05-10 19:18:38

标签: r dplyr rlang nse

我试图找出如何在tidyverse工作流程中的NSE函数中使用可选参数。这是一个我希望能够建立起来的小玩具功能。我希望能够在分组数据框架上操作;在这个例子中,我想收集df,排除df分组的任何列(通过groups(df)成功获得这些列)以及通过...进入的任何其他可选列。 quos有一个参数.ignore_empty,但我不确定如何正确使用它。我可能会误解.ignore_empty的作用。

我知道我可以通过检查缺少的参数来启动该函数,然后设置两组不同的管道操作,以确定是否有其他参数,但我更喜欢将它保存在单个管道流中。

数据和玩具功能:

library(tidyverse)

df <- structure(list(
    town = c("East Haven", "Hamden", "New Haven","West Haven"), 
    region = c("Inner Ring", "Inner Ring", "New Haven", "Inner Ring"),
    Asian = c(1123, 3285, 6042, 2214), 
    Black = c(693,13209, 42970, 10677), 
    Latino = c(3820, 6450, 37231, 10977), 
    Total = c(29015,61476, 130405, 54972), 
    White = c(22898, 37043, 40164, 28864)), 
    class = c("tbl_df","tbl", "data.frame"), row.names = c(NA, -4L))

test_dots <- function(df, ...) {
    grouping_vars <- groups(df)
    gather_vars <- quos(..., .ignore_empty = "all")

    df %>%
        gather(key = variable, value = value, -c(!!!grouping_vars), -c(!!!gather_vars))
}

将分组的df和列名称收到...

df %>%
    group_by(town) %>%
    test_dots(region) %>%
    head()
#> # A tibble: 6 x 4
#> # Groups:   town [4]
#>   town       region     variable value
#>   <chr>      <chr>      <chr>    <dbl>
#> 1 East Haven Inner Ring Asian     1123
#> 2 Hamden     Inner Ring Asian     3285
#> 3 New Haven  New Haven  Asian     6042
#> 4 West Haven Inner Ring Asian     2214
#> 5 East Haven Inner Ring Black      693
#> 6 Hamden     Inner Ring Black    13209

使用分组df但没有任何内容进入...

df %>%
    select(-region) %>%
    group_by(town) %>%
    test_dots()
#> Error in -x: invalid argument to unary operator

reprex package(v0.2.0)创建于2018-05-10。

提前致谢!

1 个答案:

答案 0 :(得分:3)

我认为问题是你试图否定一个空的向量。如果您确定总会有至少一个分组或收集变量,那么您可以执行

test_dots <- function(df, ...) {
  grouping_vars <- groups(df)
  gather_vars <- quos(...)
  vars <- quos(c(!!!grouping_vars), c(!!!gather_vars))

  df %>%
    gather(key = variable, value = value, -c(!!!vars))
}

我不认为.ignore_empty与它有任何关系,因为这似乎只能控制quos的工作方式,而不是gather()