如何让含tidy选择的dplyr函数在列不存在时不报错?
解决方法
要在保留tidy选择功能的同时,避免except参数包含不存在的列时报错,可以借助tidyselect::eval_select的strict参数忽略无效列,具体实现如下:
library(dplyr) library(rlang) library(tidyselect) rename_upper <- function(data, except = NULL) { # 捕获传入的tidy选择表达式 except_expr <- enquo(except) # 获取需要排除的列(自动忽略不存在的列) except_pos <- eval_select( !!except_expr, data = data, strict = FALSE ) except_cols <- names(except_pos) # 对除排除列外的所有列名转大写 rename_with( data, toupper, .cols = -all_of(except_cols) ) }
测试示例
- 正常排除存在的列:
df <- tibble(a = 1, b = 2, c = 3) rename_upper(df, except = b) # 输出结果: # # A tibble: 1 × 3 # A B C # <dbl> <dbl> <dbl> # 1 1 2 3
- 排除包含不存在的列:
rename_upper(df, except = c(b, d)) # 结果同上,不存在的列`d`被自动忽略,仅排除`b`
- 使用tidy选择器(存在匹配列):
rename_upper(df, except = starts_with("a")) # 输出结果: # # A tibble: 1 × 3 # a B C # <dbl> <dbl> <dbl> # 1 1 2 3
- 使用tidy选择器(无匹配列):
rename_upper(df, except = starts_with("z")) # 输出所有列名转大写: # # A tibble: 1 × 3 # A B C # <dbl> <dbl> <dbl> # 1 1 2 3
核心逻辑说明
- 用
enquo捕获except参数的表达式,保留starts_with/contains等tidy选择器的语法支持。 eval_select的strict = FALSE是核心:当选择器包含不存在的列时,不会抛出错误,仅返回存在的匹配列。- 最后通过
-all_of(except_cols)指定不需要转换的列,其余列名通过rename_with转成大写。
内容的提问来源于stack exchange,提问作者Dan Chaltiel
相关产品推荐
相关产品推荐

