使用dplyr将长格式数据转为宽格式:更优雅的实现方案?
优雅实现长格式转指定宽格式的tidyverse方案
嘿,我来给你分享一个更简洁优雅的tidyverse实现方案,用现在官方推荐的pivot_longer()和pivot_wider()函数来处理,比旧版的gather()+spread()组合更直观易读,逻辑也更清晰:
第一步:准备原始数据
先把你的示例数据转换成可操作的 tibble:
library(tidyverse) # 原始长格式数据 ds <- tibble( ID = c(1,1,2,2,3,3), value1 = c(4.333333, 4.333333, 4.583333, 3.916667, 4.500000, 4.333333), value2 = c(3.833333, 3.333333, 5.500000, 3.750000, 4.666667, 4.500000) )
第二步:核心转换代码
这里的关键是先给每个ID下的行添加一个分组标记(A/B),再通过两次 pivot 操作完成转换:
ds_wide <- ds %>% # 给每个ID内的行添加分组后缀(A、B) group_by(ID) %>% mutate(group = c("A", "B")) %>% ungroup() %>% # 把value1、value2转成长格式,保留ID和group pivot_longer(cols = starts_with("value"), names_to = "variable", values_to = "value") %>% # 把变量名和分组后缀组合,转回宽格式 pivot_wider(names_from = c(variable, group), values_from = value) %>% # 调整列顺序(可选,匹配你想要的输出顺序) select(ID, value1_A, value1_B, value2_A, value2_B)
第三步:查看结果
运行后得到的ds_wide就是你想要的宽格式:
# A tibble: 3 × 5 ID value1_A value1_B value2_A value2_B <dbl> <dbl> <dbl> <dbl> <dbl> 1 1 4.33 4.33 3.83 3.33 2 2 4.58 3.92 5.5 3.75 3 3 4.5 4.33 4.67 4.5
这个方案的优势在于:
- 用
pivot_longer()和pivot_wider()是tidyverse当前的标准函数,语法更清晰,扩展性更强(比如后续有更多value列也能轻松处理) - 分组标记的添加逻辑明确,不容易出错
- 代码可读性高,别人接手也能快速理解转换逻辑
内容的提问来源于stack exchange,提问作者pablom
相关产品推荐
相关产品推荐

