自定义pivot_wider并合并行:DataFrame按ID重构为宽表需求
长表转宽表并实现聚合规则的解决方案
针对你的需求,结合dplyr分组聚合和tidyr::pivot_wider可以完美实现,核心是先处理好聚合逻辑再转宽:
1. 加载所需R包
library(dplyr) library(tidyr) library(stringr) # 用于列名拼接
2. 预处理数据:按ID和Feature聚合
先分组计算Quantity总和,同时按照规则处理Quality和Condition:
aggregated_df <- original_df %>% group_by(ID, Feature) %>% summarise( # 对Quantity求和,忽略NA Quantity = sum(Quantity, na.rm = TRUE), # 若总和>1,Quality设为空;否则取组内第一个非空值 Quality = if (Quantity > 1) NA else first(Quality[!is.na(Quality)]), # 同理处理Condition Condition = if (Quantity > 1) NA else first(Condition[!is.na(Condition)]), .groups = "drop" # 取消分组状态 )
3. 转换为宽表
用pivot_wider展开Feature对应的属性,通过names_glue生成目标格式的列名:
wide_result <- aggregated_df %>% pivot_wider( id_cols = ID, # 以ID作为行标识 names_from = Feature, # 按Feature展开列 values_from = c(Quantity, Quality, Condition), # 要展开的字段 # 拼接列名:Feature名 + 字段缩写 names_glue = "{Feature}{str_replace_all(.value, c( 'Quantity' = 'Quant', 'Quality' = 'Qual', 'Condition' = 'Cond' ))}" )
最终结果
运行后得到的wide_result结构与你预期完全一致:
| ID | ShedQuant | ShedQual | ShedCond | MasonryQuant | MasonryQual | MasonryCond |
|---|---|---|---|---|---|---|
| 21 | 1 | A | AV | NA | NA | NA |
| 72 | 1 | D | AV | 1 | NA | NA |
补充说明:如果不想依赖stringr,可以用基础R的switch函数手动映射列名:
names_glue = "{Feature}{switch(.value, Quantity = 'Quant', Quality = 'Qual', Condition = 'Cond' )}"
内容的提问来源于stack exchange,提问作者Rachel
相关产品推荐
相关产品推荐

