R语言中用for循环结合case_when批量重编码变量报错求助
解决R语言批量填充缺失值的循环报错问题
错误原因
你遇到的语法错误,是因为在mutate()里直接用VEC_1[i] = ...赋值——R会把VEC_1[i]当成一个字面变量名,而不是解析成你想要的test1、test2这类字符串对应的列名。另外原代码每次循环都从df1重新生成df2,会导致前面的修改全部丢失,最后只保留最后一次循环的结果。
修正循环写法
下面是修复后的循环代码,解决了动态变量名解析和数据覆盖的问题:
library(dplyr) VEC_1 <- c("test1","test2","test3","test4","test5","test6","test7","test8","test9") VEC_2 <- c("test1.v1","test2.v1","test3.v1","test4.v1","test5.v1","test6.v1","test7.v1","test8.v1","test9.v1") # 初始化df2为原始数据框 df2 <- df1 for (i in 1:(min(length(VEC_1), length(VEC_2)))){ # 跳过数据框中不存在的变量对,避免报错 if (!VEC_1[i] %in% colnames(df2) || !VEC_2[i] %in% colnames(df2)) next df2 <- df2 %>% mutate( # 用!!和:=解析动态变量名,完成赋值 !!VEC_1[i] := case_when( # 用.data[[变量名]]引用数据框中的列 is.na(.data[[VEC_1[i]]]) & !is.na(.data[[VEC_2[i]]]) ~ .data[[VEC_2[i]]], TRUE ~ .data[[VEC_1[i]]] ) ) }
关键说明:
!!VEC_1[i] :=:!!把字符串转成R能识别的变量符号,:=是dplyr中用于动态变量名赋值的语法.data[[var]]:明确引用数据框内的列,避免和环境中的同名变量混淆- 先初始化
df2 <- df1,再循环更新,保留每一次的修改结果
更简洁的非循环写法
如果不想用循环,推荐用dplyr的across()函数,自动匹配所有符合规则的变量对,代码更简洁:
library(dplyr) library(stringr) df2 <- df1 %>% mutate( # 匹配所有以test开头、不以.v1结尾的列 across(starts_with("test") & !ends_with(".v1"), ~case_when( # 自动拼接对应的.v1列名,用get()获取列值 is.na(.) & !is.na(get(str_c(cur_column(), ".v1"))) ~ get(str_c(cur_column(), ".v1")), TRUE ~ . )) )
这个方法不需要手动定义VEC_1和VEC_2,直接通过变量名规则匹配,适合批量处理同类型的变量对。
内容的提问来源于stack exchange,提问作者Curbice
相关产品推荐
相关产品推荐

