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

R语言如何按code分组转name多列 避免left_join产生重复行

R实现长表转宽表:按分组将同一列值拆分为多列

问题说明

现有存储code与对应name字段的dataframe,code为业务唯一标识,但单个code可能对应多个name值。为避免后续执行left_join()操作时产生重复行,需要重构表结构:按code分组,将关联的多个name值拆分为name1/name2/...格式的独立列存储,无匹配值的位置可填充NA、空字符串等自定义值。

输入样例

df <- data.frame(
  code = c(1,1,2),
  name = c("a", "b", "c")
)

期望输出样例

resdf <- data.frame(
  code = c(1,2),
  name1 = c("a", "c"),
  name2 = c("b", "")
)

可行实现方案

方案1:tidyverse 实现(日常分析推荐,代码简洁易读)

核心逻辑是先按code分组,给每个分组内的name按顺序生成列名序号,再通过宽表转换函数完成结构重组,缺失值可自定义填充规则:

library(dplyr)
library(tidyr)

resdf <- df %>%
  group_by(code) %>%
  # 为分组内每个name生成name1/name2...的列标识
  mutate(col_id = paste0("name", row_number())) %>%
  ungroup() %>%
  # 长转宽,values_fill参数控制缺失值填充内容,填NA就写values_fill = NA
  pivot_wider(
    names_from = col_id,
    values_from = name,
    values_fill = ""
  )

运行结果与期望输出完全一致,即使单个code对应更多name值(比如3个、4个),代码也会自动生成对应数量的name列,不需要手动提前指定列数。

方案2:基础R实现(无需安装第三方包)

如果不想加载第三方依赖,用基础R的reshape函数搭配分组序号生成即可实现:

# 按code分组,为每个name生成对应的列序号
df$col_id <- paste0("name", with(df, ave(code, code, FUN = seq_along)))
# 执行长表转宽表操作
resdf <- reshape(
  df,
  idvar = "code",
  timevar = "col_id",
  direction = "wide"
)
# 清理自动生成的列名前缀
colnames(resdf) <- gsub("name\\.", "", colnames(resdf))
# 可选:将NA替换为空字符串,不需要可注释掉该行
resdf[is.na(resdf)] <- ""

内容的提问来源于stack exchange,提问作者Gmichael

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 17:27:32