如何在R中将不同长度长格式非平衡面板数据转为宽格式并补全NA
非平衡面板长格式转宽格式实现方案
需求说明
需要将因time变量长度不一致的长格式非平衡面板数据转换为宽格式,x变量的缺失观测位置按对应time填充NA,最终列名格式为x.time{时间序号}。
示例数据生成代码
set.seed(63) # 生成包含id、time、x的子数据框函数 func1 <- function (size=5) { x=sample(c(0,1), 1) data.frame(time=1:size, x=x)} # 按行合并生成平衡面板 func2 <- do.call("rbind", Map(function(x,y) { data.frame(id=x, func1(y)) }, 1:5, 5)) # 抽样生成非平衡面板数据 dd <- func2[sample(nrow(func2), 10), ] fd <- dd[with(dd, order(id, time)),]
示例数据fd内容如下:
id time x 1 1 1 0 2 1 2 0 3 1 3 0 4 1 4 0 5 1 5 0 10 2 5 1 13 3 3 0 17 4 2 0 18 4 3 0 21 5 1 0
预期输出效果
id x.time1 x.time2 x.time3 x.time4 x.time5 1 0 0 0 0 0 2 NA NA NA NA 1 3 NA NA 0 NA NA 4 NA 0 0 NA NA 5 0 NA NA NA NA
实现方法
方法1:tidyverse套件pivot_wider(最易用,推荐)
使用tidyr包的长转宽函数直接实现,代码可读性最高:
library(tidyr) # 长转宽 fd_wide <- pivot_wider( data = fd, id_cols = id, names_from = time, values_from = x, names_prefix = "x.time" ) # 转为普通数据框(可选,默认返回tibble格式) fd_wide <- as.data.frame(fd_wide)
方法2:基础R reshape函数(无需安装第三方包)
使用R内置函数实现,无需额外依赖:
fd_wide <- reshape( data = fd, idvar = "id", timevar = "time", direction = "wide", sep = ".time" ) # 去掉reshape自动生成的row.names属性(可选) row.names(fd_wide) <- NULL
方法3:data.table dcast函数(大数据量场景效率更高)
针对超大数据量时优先使用,运算速度远高于前两种方法:
library(data.table) # 转换为data.table格式 setDT(fd) # 长转宽 fd_wide <- dcast( data = fd, id ~ paste0("x.time", time), value.var = "x" ) # 转为普通数据框(可选) fd_wide <- as.data.frame(fd_wide)
以上三种方法均可得到符合预期的输出结果。
内容的提问来源于stack exchange,提问作者cliu
相关产品推荐
相关产品推荐

