使用R将一列提取为行,同时保留其他列

slh*_*hck 2 r plyr reshape2 dplyr tidyr

是)我有的:

我有一个如下所示的数据框:

sequence foo model output real
       1   3     a     12   12
       1   3     b     29   12
       1   3     c     10   12
       1   3     d     38   12
       1   3     e     10   12
       2   3     a     38   15
       2   3     b     10   15
       2   3     c     29   15
       2   3     d     56   15
       2   3     e     10   15
Run Code Online (Sandbox Code Playgroud)

由...制作:

d.test = data.frame(
  sequence = c(1, 1, 1, 1, 1, 2, 2, 2, 2, 2),
  foo = c(3, 3, 3, 3, 3, 3, 3, 3, 3, 3),
  model = c("a", "b", "c", "d", "e", "a", "b", "c", "d", "e"),
  output = c(12, 29, 10, 38, 10, 38, 10, 29, 56, 10),
  real = c(12, 12, 12, 12, 12, 15, 15, 15, 15, 15)
)
Run Code Online (Sandbox Code Playgroud)

该模型预测output每个给定的a sequence,但real输出也沿每个序列记录.

我需要的:

我想转换数据,使其real成为一个"模型"本身,即:

sequence foo model output
       1   3     a     12
       1   3     b     29
       1   3     c     10
       1   3     d     38
       1   3     e     10
       1   3  real     12
       2   3     a     38
       2   3     b     10
       2   3     c     29
       2   3     d     56
       2   3     e     10
       2   3  real     15
Run Code Online (Sandbox Code Playgroud)

我怎样才能实现这种使用dplyr,tidyr以及他们的表兄弟?

请注意,对于"漂亮"的解决方案,不应该:

  • 手动输入列索引
  • 手动指定foo不感兴趣的所有列

我尝试过的:

我试过以下,但感觉很笨拙:

unique(
  melt(d.test,
    id.vars = c("sequence", "foo"),
    measure.vars = c("real"),
    variable.name = "model",
    value.name = "output"
  )
)
Run Code Online (Sandbox Code Playgroud)

现在我必须real从原始数据框中删除该列并附加我刚才所做的行.这不是一个很好的解决方案,因为除了foo列之外,我可能还有更多列要保留,然后我必须将它们指定为id.vars.

Fra*_*ank 5

我使用data.table:

library(data.table)
setDT(d.test)

d.test[, 
  rbind(.SD, .SD[1L][, `:=`(model = "real", output = real[1L])])
, by=sequence][, real := NULL][]
Run Code Online (Sandbox Code Playgroud)

如果我不得不使用'经文:

d.real = d.test %>% distinct(sequence) %>%
  mutate(model = "real", output = real) %>% select(-real)

d = d.test %>% select(-real)
Run Code Online (Sandbox Code Playgroud)

然后堆叠它们:

bind_rows(d, d.real)
Run Code Online (Sandbox Code Playgroud)

如果排序很重要,请添加%>% arrange(sequence).


评论.OP中的问题源于不整洁的数据.如果你不知道我的意思,阅读Hadley关于这个主题的论文可能会有所帮助.