You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用for循环与mutate函数创建变量:数据宽表转换问题求助

问题原因

你写的循环有两个关键错误:

  1. mutate()里不能直接用字符串作为新列名,必须用:=运算符配合!!解析动态列名
  2. 循环中每次都重置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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 18:42:41