R具有模式的多个变量的宽到长格式

时间:2017-03-31 22:55:03

标签: r melt

我有一个带有单个标识符的数据集和五个重复18次的列。我想将数据重组为长格式,将前五列标题保留为列标题。以下是仅重复两次的示例:

structure(list(Response.ID = 1:2, Task = structure(c(1L, 1L), .Label = "task1", class = "factor"), 
Freq = structure(c(1L, 1L), .Label = "Daily", class = "factor"), 
Hours = c(3L, 2L), Value = c(10L, 8L), Mood = structure(1:2, .Label = c("Engaged", 
"Neutral"), class = "factor"), Task.1 = structure(c(1L, 1L
), .Label = "task2", class = "factor"), Freq.1 = structure(c(1L, 
1L), .Label = "Weekly", class = "factor"), Hours.1 = c(4L, 
4L), Value.1 = c(10L, 6L), Mood.1 = structure(c(2L, 1L), .Label = c("Neutral", 
"Optimistic"), class = "factor")), .Names = c("Response.ID", "Task", "Freq", "Hours", "Value", "Mood", "Task.1", "Freq.1", "Hours.1", "Value.1", "Mood.1"), class = "data.frame", row.names = c(NA, -2L))

我尝试使用熔化和图案功能,这似乎与我想要的结果近似,而没有所需的列标题:

df = melt(df1, id.vars = c("Response.ID"), measure.vars = patterns("^Task", "^Freq","^Hours","^Mood"))

结果如下:

structure(list(Response.ID = c(1L, 2L, 1L, 2L), variable = structure(c(1L, 1L, 2L, 2L), class = "factor", .Label = c("1", "2")), value1 = c("task1", "task1", "task2", "task2"), value2 = c("Daily", "Daily", "Weekly", "Weekly"), value3 = c(3L, 2L, 4L, 4L), value4 = c("Engaged", "Neutral", "Optimistic", "Neutral")), .Names = c("Response.ID", "variable", "value1", "value2", "value3", "value4"), row.names = c(NA, -4L), class = c("data.table", "data.frame"), .internal.selfref = <pointer: 0x0000000000330788>)

当我尝试使用value.name()指定名称时,我收到错误:

df = melt(df1, id.vars = c("Response.ID"),measure.vars = patterns("^Task", "^Freq","^Hours","^Mood"), value.name=c("Task", "Freq", "Hours", "Value","Mood"))

我想要的结果如下:

structure(list(Response.ID = c(1L, 2L, 1L, 2L), Task = structure(c(1L, 1L, 2L, 2L), .Label = c("task1", "task2"), class = "factor"), 
Freq = structure(c(1L, 1L, 2L, 2L), .Label = c("Daily", "Weekly"
), class = "factor"), Hours = c(3L, 2L, 4L, 4L), Value = c(10L, 
8L, 10L, 6L), Mood = structure(c(1L, 2L, 3L, 2L), .Label = c("Engaged", 
"Neutral", "Optimistic"), class = "factor")), .Names = c("Response.ID", "Task", "Freq", "Hours", "Value", "Mood"), class = "data.frame", row.names = c(NA, -4L))

1 个答案:

答案 0 :(得分:1)

在我看来,你使用melt开始了一段艰难的旅程:这个功能很有名,因为尝试使用它可能会让你的大脑融化。除了笑话之外,函数melt有很多基础计算,如果你有一个大数据集,它的使用效率可能会很低。

我会用rbindlist手动解决问题(来自优秀的软件包data.table,如果您真的想要使用它,它还附带了melt的优化版本),手动连接列组。这也保留了列名:

> rbindlist(lapply(1:2, function(i) df1[,c(1,((i-1)*5+2):((i-1)*5+6))]))
   Response.ID  Task   Freq Hours Value       Mood
1:           1 task1  Daily     3    10    Engaged
2:           2 task1  Daily     2     8    Neutral
3:           1 task2 Weekly     4    10 Optimistic
4:           2 task2 Weekly     4     6    Neutral

这适用于您的示例:将索引1:2替换为重复次数,以使其与真实数据集一起使用(因此,lapply(1:18))。