在R中将一行数据转换为多行数据

4
在R中,我有一些数据,每个人都有多个会话日期和一些测试的分数,但这些都在一行中。我想将其更改为每个人的多个行,其中只包含一个会话日期和对应的测试分数,并对每个人都执行此操作。此外,每个人可能完成不同数量的会话。
例如:
ID  Name  Session1Date  Score  Score  Session2Date  Score  Score
23  sjfd  20150904      2      3      20150908      5      7
28  addf  20150905      3      4      20150910      6      8

致:

ID  Name  SessionDate  Score  Score
23  sjfd  20150904     2      3     
23  sjfd  20150908     5      7
28  addf  20150905     3      4
28  addf  20150910     6      8
2个回答

6
你可以使用 data.table 的开发版本中的 melt 函数,即 v1.9.5。它可以将多个“测量”列作为列表输入。 安装说明可在这里找到。
library(data.table)#v1.9.5+
melt(setDT(df1), measure = patterns("Date$", "Score(\\.2)*$", "Score\\.[13]"))
#   ID Name variable   value1 value2 value3
#1: 23 sjfd        1 20150904      2      3
#2: 28 addf        1 20150905      3      4
#3: 23 sjfd        2 20150908      5      7
#4: 28 addf        2 20150910      6      8

或者使用来自base Rreshape函数,我们可以将direction参数设为'long',并将varying参数设为一个列索引list

 res <- reshape(df1, idvar=c('ID', 'Name'), varying=list(c(3,6), c(4,7), 
         c(5,8)), direction='long')
 res  
 #            ID Name time Session1Date Score Score.1
 #23.sjfd.1 23 sjfd    1     20150904     2       3
 #28.addf.1 28 addf    1     20150905     3       4
 #23.sjfd.2 23 sjfd    2     20150908     5       7
 #28.addf.2 28 addf    2     20150910     6       8

如果需要的话,可以更改rownames
 row.names(res) <- NULL 

更新

如果列按特定顺序排列,例如第三列与第六列分组,第四列与第七列分组,第五列与第八列分组,我们可以创建一个列索引的矩阵,然后使用split将其拆分为reshape可变参数的列表

 m1 <- matrix(3:8,ncol=2)
 lst <- split(m1, row(m1))
 reshape(df1, idvar=c('ID', 'Name'), varying=lst, direction='long')

有没有一种方法可以不用输入所有变量名称来完成这个操作,因为我有625列? - Swanny
@MichaelпјҢдҪ еҸҜд»ҘдҪҝз”Ёsplitstackshapeдёӯзҡ„merged.stackеҮҪж•°пјҢдҪҶжҲ‘们йңҖиҰҒдёҖдәӣе…ұеҗҢеҲ—еҗҚзҡ„жЁЎејҸжҲ–иҖ…йңҖиҰҒзҹҘйҒ“еҲ—жҳҜеҗҰйҒөеҫӘзү№е®ҡзҡ„йЎәеәҸгҖӮ - akrun
非常抱歉,我对R还不是很熟悉。但是在您使用reshape的答案中,varying=list指定了什么?我似乎无法弄清楚这些数字对应的是什么? - Swanny
@Michael lst 是列索引的列表。如果您在 R 控制台上键入 lst,您将看到第一个 lst 元素是 lst[[1]] 对应于 3 6,即我们要分组的列。同样,我们将 4 75 8 分组,因为它们是单独的列表元素。 - akrun
1
@Swanny,请查看更新的解决方案。您可以在melt中使用正则表达式,并借助patterns()函数。 - Arun
显示剩余4条评论

0
如果您的数据框名称为data
请使用以下代码:
data1 <- data[1:5]
data2 <- data[c(1,2,6,7,8)]
newdata <- rbind(data1,data2)

这对于你提供的示例是有效的。你可能需要适当地更改data1和data2中的列名以进行正确的rbind


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接