You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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))
}

验证效果

  1. 传入可选参数的情况:
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
  1. 不传入可选参数的情况:
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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 07:09:11