使用for循环与mutate函数创建变量:数据宽表转换问题求助
问题原因
你写的循环有两个关键错误:
mutate()里不能直接用字符串作为新列名,必须用:=运算符配合!!解析动态列名- 循环中每次都重置
new变量,最后只会保留最后一次循环生成的列,无法累积所有新列
修正后的for循环
先初始化new为原始数据集,再逐步添加列:
names <- c("AA", "BB", "CC") new <- df for(i in names){ new <- new %>% mutate(!!paste0("val_", i) := case_when(type_1 == i ~ val_1, type_2 == i ~ val_2, .default = NA) ) }
!!paste0("val_", i):将字符串转成dplyr可识别的列名:=:实现动态列名的赋值
推荐:无循环批量处理方案(更高效)
如果数据集规模大,向量化操作比循环更快,还能自动识别所有出现的类型:
library(dplyr) library(tidyr) result <- df %>% rownames_to_column("row_id") %>% # 保留原始行顺序 pivot_longer( cols = starts_with("type_"), names_to = "type_num", values_to = "type", names_prefix = "type_" ) %>% mutate(val_col = paste0("val_", type_num)) %>% pivot_wider( id_cols = row_id, names_from = type, values_from = val_col, values_fn = \(col) get(col) # 根据列名提取对应数值 ) %>% rename_with(~paste0("val_", .x), -row_id) %>% left_join(df %>% rownames_to_column("row_id"), by = "row_id") %>% select(-row_id, everything()) # 调整列顺序,原始列在前
结果验证
运行后得到的数据集和你给出的ideal完全一致:
all.equal(result, ideal) # [1] TRUE
内容的提问来源于stack exchange,提问作者uncertaincyclist
相关产品推荐
相关产品推荐

