我正在尝试准备我的数据集以在其上运行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中做到吗?非常感谢。
答案 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))