在R语言NSE中使用quos处理空参数的技术问题
解决分组数据框中带可选参数的NSE Gather函数问题
首先,我们来拆解你遇到的报错原因:当...没有传入任何参数时,quos(..., .ignore_empty = "all")会返回一个空的quosure列表。这时候你的gather调用就变成了-c(!!!grouping_vars), -c(),而tidyselect不允许对空向量使用负号排除操作,这就是报错的根源。
关于.ignore_empty的用法,它的作用是忽略那些空的quosure对象(比如传入NULL或者未定义的参数),但无法处理...完全没有输入的情况——这种情况下quos()本身就返回空列表,没有可忽略的元素。
解决方案:合并排除列列表
我们可以把分组列和可选排除列合并成一个统一的quosure列表,这样不管...有没有参数,排除列表至少包含分组列,不会出现空排除的情况。修改后的函数如下:
library(tidyverse) test_dots <- function(df, ...) { grouping_vars <- groups(df) # 合并分组列和传入的可选排除列 exclude_vars <- c(grouping_vars, quos(..., .ignore_empty = "all")) df %>% gather(key = variable, value = value, -c(!!!exclude_vars)) }
验证效果
- 传入可选参数的情况:
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 %>% select(-region) %>% group_by(town) %>% test_dots()
现在可以正常运行,输出如下(截取部分):
#> # A tibble: 20 x 3 #> # Groups: town [4] #> town variable value #> <chr> <chr> <dbl> #> 1 East Haven Asian 1123 #> 2 Hamden Asian 3285 #> 3 New Haven Asian 6042 #> 4 West Haven Asian 2214 #> 5 East Haven Black 693 #> # ... with 15 more rows
额外说明
如果你需要更灵活的处理(比如允许...传入空参数但不报错),.ignore_empty = "all"会帮你过滤掉这些空值。例如:
df %>% group_by(town) %>% test_dots(NULL, region) %>% head()
这里的NULL会被忽略,实际排除的列还是town和region,函数依然正常运行。
内容的提问来源于stack exchange,提问作者camille
相关产品推荐
相关产品推荐

