R语言数据框基于列透视/自连接 长表转指定格式宽表实现
R数据框长转宽实现方案
用pivot_wider未得到预期结果,核心原因是缺少分组内的行序号标识:目标结果里scale_1/scale_2/scale_3、price_1/price_2/price_3的数字后缀,本质是每个item_number分组下按顺序排列的行编号,先给分组内数据加上这个序号,再做长宽转换即可得到正确结果。
方法1:tidyverse 方案(代码简洁易读)
先加载依赖包,按步骤处理:
library(dplyr) library(tidyr) df_result <- df %>% # 按商品编号分组,为每组内的行生成1、2、3的顺序编号 group_by(item_number) %>% mutate(row_id = row_number()) %>% ungroup() %>% # 将规格、价格两列统一转为长格式,方便拼接列名 pivot_longer(cols = c(scales, prices), names_to = "col_category") %>% mutate(final_col = case_when( col_category == "scales" ~ paste0("scale_", row_id), col_category == "prices" ~ paste0("price_", row_id) )) %>% # 移除中间列,转为宽格式 select(-col_category, -row_id) %>% pivot_wider(names_from = final_col, values_from = value) %>% # 调整列顺序,和目标结构对齐 select(item_number, scale_1, scale_2, scale_3, price_1, price_2, price_3, product_name)
运行后输出结果完全匹配预期:
# A tibble: 2 × 8 item_number scale_1 scale_2 scale_3 price_1 price_2 price_3 product_name <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr> 1 1 1 5 10 1 1.5 2 Cheese 2 2 2 15 20 3 4.0 5 Ham
方法2:data.table 方案(性能更强,适合百万行级大数据量)
library(data.table) # 转为data.table格式 setDT(df) # 按商品编号分组生成行序号 df[, row_id := rowid(item_number)] # 直接转宽表 df_result <- dcast( df, item_number + product_name ~ row_id, value.var = c("scales", "prices"), sep = "_" ) # 调整列名和列顺序 setnames(df_result, old = c("scales_1","scales_2","scales_3","prices_1","prices_2","prices_3"), new = c("scale_1","scale_2","scale_3","price_1","price_2","price_3")) setcolorder(df_result, c("item_number", "scale_1", "scale_2", "scale_3", "price_1", "price_2", "price_3", "product_name"))
补充说明:如果不同商品对应的规格/价格档位数量不固定(比如部分商品只有2档、部分有4档),上述代码会自动按最大档位数量生成对应列,不需要手动写死列数。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

