如何在R中将带rank的长格式data.frame转换为宽格式?
解决长转宽格式问题
核心问题说明
你之前的代码失败的原因是没有给每个组内的观测添加序号标记,转宽时无法区分同一组内的第1/2/3/4个观测,导致列名和值的对应关系混乱。下面分别用reshape2和data.table实现两种目标格式。
格式一:分开展示x和r的宽表
使用reshape2包
library(reshape2) # 给每个组内的观测添加序号(1-4) d2$id <- ave(1:nrow(d2), d2$g, FUN = seq_along) # 先转长再转宽,按g分组,以variable+id作为列名 format1 <- dcast(melt(d2, id.vars = c("g", "id")), g ~ variable + id) # 调整列顺序,让x1/r1、x2/r2依次排列 format1 <- format1[, c("g", paste(rep(c("x", "r"), each=4), 1:4, sep=""))] print(format1)
使用data.table包
library(data.table) setDT(d2) # 组内生成序号 d2[, id := seq_len(.N), by = g] # 直接转宽,指定value.var为x和r,按id拆分列 format1_dt <- dcast(d2, g ~ id, value.var = c("x", "r")) # 调整列名和顺序,匹配目标格式 setcolorder(format1_dt, c("g", paste(rep(c("x", "r"), each=4), 1:4, sep=""))) setnames(format1_dt, paste(c("x", "r"), rep(1:4, each=2), sep="_"), paste(c("x", "r"), rep(1:4, each=2), sep="")) print(format1_dt)
格式二:合并x和r的紧凑宽表
使用reshape2包
library(reshape2) # 合并x和r为"x(r)"格式的字符串 d2$xr <- paste0(d2$x, "(", d2$r, ")") # 添加组内序号 d2$id <- ave(1:nrow(d2), d2$g, FUN = seq_along) # 转宽生成xr1-xr4列 format2 <- dcast(d2, g ~ paste0("xr", id), value.var = "xr") print(format2)
使用data.table包
library(data.table) setDT(d2) # 合并x和r d2[, xr := paste0(x, "(", r, ")")] # 组内生成序号 d2[, id := seq_len(.N), by = g] # 转宽 format2_dt <- dcast(d2, g ~ paste0("xr", id), value.var = "xr") print(format2_dt)
内容的提问来源于stack exchange,提问作者John Stone
相关产品推荐
相关产品推荐

