如何用dplyr/tidyverse基于factor重排DataFrame列并转宽格式?
解决方案(基于tidyverse)
可以用tidyverse中的pivot_wider函数快速完成长宽表转换,完美匹配你的需求:
library(tidyverse) # 生成原始数据 exp <- as.factor(c(rep('UT',3),rep('NC',3),rep('PC',3))) fact <- as.factor(rep(c('A','B','C'),3)) set.seed(10) avg <- rnorm(9,10,1) sd <- rnorm(9,2,0.5) df <- data.frame(exp,fact,avg,sd) # 转换为目标格式 df_wide <- df %>% pivot_wider( id_cols = exp, # 按exp分组,每行对应一个实验处理 names_from = fact, # 用fact的A/B/C作为列名前缀 values_from = c(avg, sd), # 展开avg和sd两列 names_glue = "{fact}.{.value}"# 拼接列名,生成A.avg、A.sd格式 ) %>% select(exp, A.avg, A.sd, B.avg, B.sd, C.avg, C.sd) # 强制指定列顺序 # 查看结果 print(df_wide)
代码说明
pivot_wider核心参数:id_cols = exp:确定行的唯一标识,保证最终每行对应一个实验处理(UT/NC/PC)names_from = fact:将fact列的类别(A/B/C)提取为新列名的一部分values_from = c(avg, sd):指定需要从长表展开为宽表的数值列names_glue:用模板字符串自定义列名格式,{fact}对应A/B/C,{.value}对应avg/sd,正好生成你需要的X.avg/X.sd格式
select强制列顺序:
虽然pivot_wider默认会按因子顺序生成列,但用select手动指定列顺序可以确保完全符合你的需求,避免因数据因子顺序变化导致列错位。
输出结果
# A tibble: 3 × 7 exp A.avg A.sd B.avg B.sd C.avg C.sd <fct> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> 1 UT 9.34 1.65 9.72 2.20 9.79 1.81 2 NC 10.2 2.14 10.3 1.87 10.8 1.74 3 PC 9.84 2.30 11.3 2.03 10.6 2.33
内容的提问来源于stack exchange,提问作者threadofmotion
相关产品推荐
相关产品推荐

