R中的宽到长格式 - 多个问题的前后测试

时间:2016-07-13 06:06:26

标签: r

我正在尝试准备我的数据集以在其上运行HLM。现在,数据集是宽格式的,所以我需要将其更改为长格式。我已尝试使用reshape功能,但到目前为止无济于事。有51个测试前问题和51个测试后问题。数据集的原始格式与此类似(这仅适用于一个人):

Student.ID  PreTest1  PreTest2  PreTest3  ...  PostTest1  PostTest2  PostTest3
   2322        3          2         5               2          4          5 

理想情况下,我希望最终数据集看起来像这样:

Student.ID  time  Score  Question
   2322       1     3       1
   2322       1     2       2
   2322       1     5       3
   2322       2     2       1
   2322       2     4       2
   2322       2     5       3

这可以在R中做到吗?非常感谢。

1 个答案:

答案 0 :(得分:3)

我们可以使用melt。转换' data.frame'到' data.table' (setDT(df)),melt来自'范围'长期'格式,然后创建'时间'和'问题'使用变量的子字符串进行分组后的变量(通过使用sub删除数字部分)。

library(data.table)
melt(setDT(df), id.var = "Student.ID", value.name = "Score")[,
   c("time", "Question") := .(.GRP, 1:.N) , .(sub("\\d+", "", variable))
  ][, variable:= NULL]
#   Student.ID Score time Question
#1:       2322     3    1        1
#2:       2322     2    1        2
#3:       2322     5    1        3
#4:       2322     2    2        1
#5:       2322     4    2        2
#6:       2322     5    2        3

或使用dplyr/tidyr

library(dplyr)
library(tidyr)
gather(df, Var, Score, -1) %>% 
     separate(Var, into = c("time", "Var2"), sep = 3) %>% 
     group_by(time = match(time, unique(time))) %>% 
     mutate(Question = row_number()) %>%
     select(-Var2)
#  Student.ID  time Score Question
#       <int> <int> <int>    <int>
#1       2322     1     3        1
#2       2322     1     2        2
#3       2322     1     5        3
#4       2322     2     2        1
#5       2322     2     4        2
#6       2322     2     5        3

数据

df <- structure(list(Student.ID = 2322L, PreTest1 = 3L, PreTest2 = 2L, 
PreTest3 = 5L, PostTest1 = 2L, PostTest2 = 4L, PostTest3 = 5L),
 .Names = c("Student.ID", 
"PreTest1", "PreTest2", "PreTest3", "PostTest1", "PostTest2", 
"PostTest3"), class = "data.frame", row.names = c(NA, -1L))