复杂的数据重组-宽到长(多列)

时间:2018-12-08 18:10:29

标签: r reshape reshape2 melt

我想进行如上所述的重组,而我正在努力使用gather(),因为要创建多个列……有人知道这样做的方法吗?

enter image description here

2 个答案:

答案 0 :(得分:1)

这应该可行,尽管可能不是最优雅的:

library(reshape2)
library(tidyr)
library(dplyr)

示例数据(基于屏幕截图)

df <- tibble(id = c(1,2,3), 
         mathT1 = c(10, 9, 7),
         mathT2 = c(11, 6, 8),
         write1 = c(2, 3, 1),
         write2 = c(3, 5, 1),
         ses = c(3, 4, 5))

使用reshape2,dplyr和tidyr软件包的代码:

df <- df %>%
  rename(math_1 = mathT1, math_2 = mathT2, 
         write_1 = write1, write_2 = write2, ses_1 = ses) %>%
  mutate(ses_2 = ses_1) %>%
  melt(id.vars = "id", variable.name = "var", value.name = "value") %>%
  separate(var, c("var", "time"), "_", extra = "merge") %>%
  spread(var, value)

答案 1 :(得分:0)

这里是reshape的一个选项。

names(df1)[ncol(df1)] <- "ses1"
df1$ses2 <- df1$ses1 # according to your desired output
out <- reshape(df1, varying = 2:7, direction = "long", sep = "")
out[order(out$id), ]
#    id time mathT write ses
#1.1  1    1    10     2   3
#1.2  1    2    11     3   3
#2.1  2    1     9     3   4
#2.2  2    2     6     5   4
#3.1  3    1     7     1   5
#3.2  3    2     8     1   5

不是我们需要创建列ses2来获得所需的输出。如果您想用NA代替ses2的值出现的位置(我认为是正确的,给定输入数据),请查看下面的data.table解决方案。


使用melt中的data.table

library(data.table)
setDT(df1)
melt(df1,
     id.vars = "id", 
     measure.vars = patterns("^mathT", "^write", "^ses"), 
     variable.name = "Time", 
     value.name = c("mathT", "write", "ses"))
#   id Time mathT write ses
#1:  1    1    10     2   3
#2:  2    1     9     3   4
#3:  3    1     7     1   5
#4:  1    2    11     3  NA
#5:  2    2     6     5  NA
#6:  3    2     8     1  NA

数据,感谢@Pete!

df1 <- data.frame(
  id = c(1, 2, 3),
  mathT1 = c(10, 9, 7),
  mathT2 = c(11, 6, 8),
  write1 = c(2, 3, 1),
  write2 = c(3, 5, 1),
  ses = c(3, 4, 5)
)