使用mutate_at/across动态变量名应用if_else自定义函数报错解决
问题解决
报错原因
你用get()时传了长度大于1的参数,根源是函数里的Col是整列的数值向量(而非列名)。str_replace(Col, "Score", "")会处理每一个列值(这里都是NA),生成一堆无效字符串,paste0后得到字符串向量,而get()只能处理单个对象,因此触发报错。
修正方案
核心是获取当前处理的列名而非列值,用dplyr的cur_column()函数即可拿到当前列名,再用.data代词动态引用目标列(比get()更适合向量操作)。另外mutate_at已被淘汰,推荐用across批量处理列。
修正后的自定义函数
library(dplyr) library(stringr) retraitement <- function(Taille) { # 获取当前正在处理的列名 col_name <- cur_column() # 提取Score后的数字部分(如Score1提取为"1") num_part <- str_replace(col_name, "Score", "") # 拼接目标列名(如1_PE) target_col <- paste0(num_part, "_", Taille) # 根据TAILLE列的值替换对应目标列内容 if_else(.data$TAILLE == Taille, .data[[target_col]], .data[[col_name]]) }
数据处理代码
# 构造测试数据(匹配你的示例) df <- tibble( Score1 = NA_integer_, `1_PE` = c(12,14), `1_MGE` = c(28,32), TAILLE = c("MGE", "PE") ) columnsToAdd <- c("Score1", "Score13", "Score49") # 初始化目标列为NA df[, columnsToAdd] <- NA # 用across批量处理指定列 df <- df %>% mutate(across(all_of(columnsToAdd), ~retraitement("PE"))) %>% mutate(across(all_of(columnsToAdd), ~retraitement("MGE")))
处理结果
以示例中的Score1列为例,处理后的数据符合预期:
| Score1 | 1_PE | 1_MGE | TAILLE |
|---|---|---|---|
| 28 | 12 | 28 | MGE |
| 14 | 14 | 32 | PE |
补充说明
.data[[target_col]]可以安全动态引用列,支持向量操作,不会出现长度不匹配问题。- 若
TAILLE还有其他取值(如"GE"),只需新增一行mutate(across(all_of(columnsToAdd), ~retraitement("GE")))即可。
内容的提问来源于stack exchange,提问作者Rgrvkfer
相关产品推荐
相关产品推荐

