如何在R语言中同时整合两组不同列(宽表转长表)
将宽格式问题数据转换为长格式
需求说明
现有宽格式DataFrame,包含参与者姓名、各题得分(1=正确,0=错误)及对应答案,需转换为长格式:每行对应单个参与者的单个问题,包含Name、Question(问题名称)、Answer(具体答案)、Score(得分)四列。
示例输入数据
Name <- c("Jon", "Bill", "Maria", "Ben", "Tina") Question1 <- c(1, 0, 1, 1, 0) Question1_answer <- c(22, 35, 22, 22, 90) Question2 <- c(1, 0, 0, 0, 1) Question2_answer <- c(75, 72, 11, 43, 75) Question3 <- c(0,0,1,0,1) Question3_answer <- c(16, 18, 19, 27, 19) df <- data.frame(Name, Question1, Question1_answer, Question2, Question2_answer, Question3, Question3_answer) print(df)
目标输出格式
Name <- rep(c("Jon", "Bill", "Maria", "Ben", "Tina"), 3) Question <- rep(c("Question1", "Question2", "Question3"), each=5) Answer <- c(22, 35, 22, 22, 90, 75, 72, 11, 43, 75, 16, 18, 19, 27, 19) Score <- c(1, 0, 1, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1) df2 <- data.frame(Name, Question, Answer, Score) print(df2)
一步转换方案
使用tidyr包的pivot_longer函数,通过正则匹配列名实现分组转换,一步得到目标格式:
# 加载tidyverse包(包含tidyr) library(tidyverse) df2 <- df %>% # 对除Name外的所有列执行长表转换 pivot_longer( cols = -Name, # 正则匹配列名:拆分出问题名称(如Question1)和数据类型(answer或空) names_pattern = "(Question\\d+)_(answer)?", # 将拆分出的第一部分作为Question列,第二部分作为值列的名称 names_to = c("Question", ".value") ) %>% # 重命名自动生成的列,匹配目标格式 rename(Score = `NA`, Answer = answer) %>% # 调整列顺序,与目标格式一致 select(Name, Question, Answer, Score) print(df2)
代码说明
names_pattern:用正则表达式将列名拆分为两部分,(Question\\d+)匹配问题编号,_(answer)?匹配可选的_answer后缀.value:指定拆分出的第二部分作为值列的名称,空后缀对应得分列(自动命名为NA),answer后缀对应答案列rename:将自动生成的列名调整为目标格式的Score和Answerselect:调整列顺序,与目标输出完全对齐
内容的提问来源于stack exchange,提问作者Freya
相关产品推荐
相关产品推荐

