从长到宽没有id.var?

From long to wide form without id.var?

我有一些长格式的数据,如下所示:

dat1 = data.frame(
  id = rep(LETTERS[1:2], each=4),
  value = 1:8
)

在table形式中:

id   value
A    1
A    2
A    3
A    4
B    5
B    6
B    7
B    8

我希望它是简短的,看起来像这样:

dat1 = data.frame(A = 1:4, B = 5:8)

在table形式中:

A  B
1  5
2  6
3  7
4  8

现在我可以通过循环使用 cbind() 和其他东西来解决这个问题,但我想使用某种 reshape/melt 函数,因为我认为这是做这种事情的最佳方式。

然而,从花费超过 30 分钟试图让 melt()reshape() 开始工作,阅读关于 SO 的答案,似乎这些功能需要设置 id.var。现在,对于这种事情来说显然是多余的,那么我该如何做我想做的事情而不必诉诸某种循环?

我很确定之前已经回答过这个问题。无论如何,unstack 在这种具有相同组大小的特定情况下很方便:

unstack(dat1, form = value ~ id)
#   A B
# 1 1 5
# 2 2 6
# 3 3 7
# 4 4 8

当 A 和 B 的数量不同时,下面的解决方案有效。对于相同的计数,unstack 效果很好并且代码更少(Henrik's 答案)。

# create more general data (unbalanced 'id')
each <- c(4,2,3)
dat1 = data.frame(
    id = unlist(mapply(rep, x = LETTERS[1:length(each)], each = each)),
    value = 1:sum(each),
    row.names = 1:sum(each) # to reproduce original row.names
)

tab <- table(dat1$id)
dat1$timevar <- unlist(sapply(tab, seq))
library(reshape2)
dcast(dat1, timevar ~ id )[-1]

初始数据:

id value
1  A     1
2  A     2
3  A     3
4  A     4
5  B     5
6  B     6
7  C     7
8  C     8
9  C     9

结果:

  A  B  C
1 1  5  7
2 2  6  8
3 3 NA  9
4 4 NA NA

这里有一个基本的 R 方法可供考虑。它使用 lengths 函数,我相信它是在 R 3.2 中引入的。

x <- split(dat1$value, dat1$id)
as.data.frame(lapply(x, function(y) `length<-`(y, max(lengths(x)))))
#   A  B  C
# 1 1  5  7
# 2 2  6  8
# 3 3 NA  9
# 4 4 NA NA