如何在R中对DataFrame分组后转置(transpose)并合并(rbind)分组?
问题描述
我用dplyr创建了如下数据框:
library(dplyr) sample.df <- data.frame(group.column = c("first_a","first_b","first_c","first_d", "second_a","second_b","second_c","second_d", "third_a","third_b","third_c","third_d"), value.column.first = 1:12, value.column.second = 13:24)
尝试用以下代码处理但未得到预期结果:
sample.df %>% mutate(buffer = `group.column` %>% strsplit(split="_") %>% lapply(function(x) {x[1]}) %>% unlist) %>% group_by(buffer) %>% t %>% rbind
希望得到如下格式的表格:
| A header | a.1 | a.2 | b.1 | b.2 | c.1 | c.2 | d.1 | d.2 |
|---|---|---|---|---|---|---|---|---|
| first | 1 | 13 | 2 | 14 | 3 | 15 | 4 | 16 |
| second | 5 | 17 | 6 | 18 | 7 | 19 | 8 | 20 |
| third | 9 | 21 | 10 | 22 | 11 | 23 | 12 | 24 |
解决方案
你之前的代码问题在于用t()转置分组后的data frame,会破坏数据结构。正确做法是拆分分组列后,将数据重塑为宽格式,用dplyr配合tidyr包实现更高效:
步骤1:拆分分组列
用separate把group.column拆分为主分组(first/second/third)和子分组(a/b/c/d):
library(dplyr) library(tidyr) sample_processed <- sample.df %>% separate(group.column, into = c("main_group", "sub_group"), sep = "_")
步骤2:重塑为目标宽格式
用pivot_wider将子分组与数值列组合成新列名,同时指定值来源:
final_df <- sample_processed %>% pivot_wider( id_cols = main_group, names_from = sub_group, values_from = c(value.column.first, value.column.second), names_glue = "{sub_group}.{gsub('value.column.', '', .value)}" ) %>% rename(`A header` = main_group)
最终效果
运行后final_df即为目标格式:
print(final_df) # # A tibble: 3 × 9 # `A header` a.1 a.2 b.1 b.2 c.1 c.2 d.1 d.2 # <chr> <int> <int> <int> <int> <int> <int> <int> <int> # 1 first 1 13 2 14 3 15 4 16 # 2 second 5 17 6 18 7 19 8 20 # 3 third 9 21 10 22 11 23 12 24
原代码无效原因
group_by(buffer) %>% t %>% rbind的操作,分组后转置会将data frame转为矩阵,丢失列名逻辑,无法正确对应子分组与数值列的关系,因此得不到预期的宽表结构。
内容的提问来源于stack exchange,提问作者versatile_programmer
相关产品推荐
相关产品推荐

