使用dplyr的mutate()动态生成新变量时cur_column()报错求助
解决合并数据集生成无后缀变量的报错问题
问题场景
合并两个数据集后得到包含多组.x/.y后缀变量对的数据集(如piip.x/piip.y),需要保留原变量的同时生成无后缀新变量,规则为:
- 优先取对应
.y变量的值 - 若
.y缺失,则取.x变量的值 - 两者均缺失时,新变量为NA
原代码执行时触发报错:cur_column()必须仅在across()内部使用。
报错原因
原代码中cur_column()被嵌套在.data[[...]]及case_when的上下文里,超出了across()允许直接调用cur_column()的范围,导致触发上下文检查报错。
解决方案
方案一:用coalesce简化逻辑(推荐)
dplyr::coalesce的核心功能就是按顺序返回第一个非缺失值,完美匹配需求逻辑,代码更简洁且避免报错:
library(dplyr) library(stringr) data_merged_ex_t <- data_merged_ex %>% mutate(across( .cols = ends_with(".x"), .fns = ~ coalesce(.data[[str_replace(.col, "\\.x$", ".y")]], .), .names = "{str_remove(.col, '\\.x$')}" ))
.col:在across()的.fns中直接获取当前处理的.x列名str_replace(.col, "\\.x$", ".y"):将.x列名转换为对应的.y列名coalesce(y_col, .):优先取.y列的值,若缺失则取当前.x列的值(.代表当前列)
方案二:修正cur_column()的调用上下文
如果需要保留case_when的写法,可将cur_column()的调用放在across()的直接函数体内,避免嵌套:
data_merged_ex_t <- data_merged_ex %>% mutate(across( .cols = ends_with(".x"), .fns = function(x) { col_x <- cur_column() col_y <- str_replace(col_x, "\\.x$", ".y") case_when( !is.na(.data[[col_y]]) ~ .data[[col_y]], !is.na(x) ~ x, TRUE ~ NA_real_ ) }, .names = "{str_remove(.col, '\\.x$')}" ))
运行结果
处理后的数据集会保留原变量,并新增无后缀的合并变量:
data_merged_ex_t # A tibble: 5 × 11 seqg cyl piip.x piip.y dalo.x dalo.y tcct.x tcct.y piip dalo tcct <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 7894 0 1.1 1.1 2.7 NA 242 NA 1.1 2.7 242 2 1597 2 NA NA NA 2.7 NA 196 NA 2.7 196 3 2586 1 0.7 0.7 2.2 4.3 161 NA 0.7 4.3 161 4 4679 0 0.6 NA 1.4 2.2 239 NA 0.6 2.2 239 5 8371 0 0.5 1.3 1.6 NA 206 NA 1.3 1.6 206
内容的提问来源于stack exchange,提问作者Ronaldo Filho
相关产品推荐
相关产品推荐

