如何用R基础函数将长格式数据转为指定宽格式(值长度不同)
长格式转宽格式数据(优先使用R基础函数)
原始数据
提供的长格式数据定义如下:
df_long <- data.frame( indiv_id = c(rep(1,2), rep(2,6), rep(3,4)), value = c(sample(x = 2), sample(x = 6), sample(x = 4)), field_id = c("A", "B", "A", "C", "D", "E", "G", "F", "B", "D", "E", "F") )
数据预览:
indiv_id value field_id 1 1 1 A 2 1 2 B 3 2 6 A 4 2 1 C 5 2 5 D 6 2 4 E 7 2 2 G 8 2 3 F 9 3 4 B 10 3 1 D 11 3 2 E 12 3 3 F
期望输出
转换后仅保留A、B、D、E、F这几个字段,宽格式结果如下:
indiv_id A B D E F 1 1 1 2 NA NA NA 2 2 6 NA 5 4 3 3 3 NA 4 1 2 3
解决方案(R基础函数实现)
1. 过滤无关字段
首先筛选出需要保留的field_id,排除C和G:
target_fields <- c("A", "B", "D", "E", "F") df_filtered <- df_long[df_long$field_id %in% target_fields, ]
2. 使用reshape函数转宽格式
利用R基础包的reshape完成长转宽,指定分组ID、时间变量和转换方向:
df_wide <- reshape(df_filtered, idvar = "indiv_id", timevar = "field_id", direction = "wide")
3. 调整列名(可选)
默认生成的列名带value.前缀,可通过正则替换去掉:
colnames(df_wide) <- gsub("value\\.", "", colnames(df_wide))
最终结果
执行上述代码后,df_wide即为目标格式:
> df_wide indiv_id A B D E F 1 1 1 2 NA NA NA 3 2 6 NA 5 4 3 9 3 NA 4 1 2 3
补充说明
之前用spread或acast未达预期,大概率是没提前过滤无关字段。如果允许使用tidyverse工具,也可以用spread实现:
library(tidyr) df_wide_tidy <- df_filtered %>% spread(key = field_id, value = value)
但按要求优先使用基础函数,reshape是最优方案。
内容的提问来源于stack exchange,提问作者Jamman
相关产品推荐
相关产品推荐

