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

如何在多变量聚合下将长格式转宽格式并保留原始重复行

解决长格式转宽格式并保留重复行的问题

嘿,我来帮你搞定这个长转宽还得保留原始重复行的需求!先把你的测试数据完整跑出来,方便我们后续操作:

# 构建测试数据
id = c(rep(1,5), rep(2,5))
type = factor(c(1L, 1L, 2L, 2L, 2L, 2L, 2L, 1L, 1L, 1L), labels = c('pay','inv'))
lett = c('a', 'b', 'a_inv','a_inv', 'b_inv', 'c', 'c', 'd', 'd', NA)
numb = c(30, 30, -10, -20, -30, -20, -20, 20, 20, NA)
abs_numb = abs(numb)
test = data.frame(id, type, lett, numb, abs_numb)

你的核心诉求是在多变量聚合的前提下转宽格式,但要保留原始的重复行——普通的pivot_wider(或者旧版的spread)会自动对相同分组的行做聚合操作,这显然不符合你的要求。所以关键在于:先给每个分组内的重复行添加唯一标识,这样转宽时就能精准保留每一行的原始信息。

下面是具体的解决方案,用dplyr+tidyr就能轻松实现:

library(dplyr)
library(tidyr)

test_wide <- test %>%
  # 按id和type分组,给每组内的行添加序号,用来区分重复项
  group_by(id, type) %>%
  mutate(row_id = row_number()) %>%
  ungroup() %>%
  # 转宽格式:把type拆成pay/inv列,对应保留lett、numb、abs_numb的取值
  pivot_wider(
    id_cols = c(id, row_id),  # 用id+row_id作为唯一标识
    names_from = type,
    values_from = c(lett, numb, abs_numb),
    names_sep = "_"  # 列名用下划线区分类型和原始列名
  ) %>%
  # 调整列顺序,让结构更清晰(可选操作)
  select(id, starts_with("pay"), starts_with("inv"), row_id)

# 查看最终结果
print(test_wide)

结果说明

生成的宽格式数据里,每个原始的重复行都被完整保留了:

  • row_id用来标记同一id下同一type内的行序号,确保转宽时不会合并重复行
  • 列名比如pay_lett、inv_numb清晰对应原始长格式里的字段和类型
  • 如果不需要row_id,在最后一步加上select(-row_id)即可删除

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 06:21:24