R语言如何将按组存储的学生宽表转换为每行对应单个学生的长表?
实现宽表转指定长表的两种常用方案
方案1:tidyverse(tidyr)包的pivot_longer(推荐用法)
这是目前R生态中处理长宽表转换的主流方案,代码可读性更高:
# 未安装包先运行 install.packages("tidyr") library(tidyr) newData <- pivot_longer( dat, cols = -Group, # 除Group分组列外,其余所有列参与转换 names_to = c(".value", "student_seq"), # 拆分原始列名:前半段作为新列名,后半段为组内学生序号 names_pattern = "(.*)(\\d)$" # 正则匹配列名结构:任意前缀+结尾数字 ) # 不需要保留组内学生序号可以直接删除该列 newData$student_seq <- NULL
运行后即可得到每行对应一名学生的目标格式。
方案2:base R原生reshape函数(无需安装第三方包)
如果不想依赖第三方扩展包,可以直接用R自带的reshape函数实现:
newData <- reshape( dat, idvar = "Group", varying = list( c("Student1", "Student2"), c("Age1", "Age2"), c("Grade1", "Grade2") ), v.names = c("Student", "Age", "Grade"), direction = "long" ) # 转换后默认生成的time列是组内学生序号,不需要可删除 newData$time <- NULL rownames(newData) <- NULL
之前代码运行不符合预期的原因
- 调用melt时
id.vars = c("id")指定的分组列名和实际列名Group不符 - 基础melt调用没有处理「多组列分别对应同一个属性的不同记录」的逻辑,只会把所有非id列堆叠到同一列,自然无法拆分出Student、Age、Grade三个独立列。
内容的提问来源于stack exchange,提问作者Will.S89
相关产品推荐
相关产品推荐

