按ID重新排列DT,以便将所有不同的值放在彼此相邻的列中

时间:2017-02-03 09:12:12

标签: r data.table

如何通过id重新排列data.table,以便将相同id中的列放在一起? 以下代码作为输入和所需输出的简短示例

require(data.table)
set.seed(456)
DT <- data.table(id = c(1,1,1, 2,2, 3,3, 4,4,4, 5),
                 X  = round(runif(11, 0, 1),2),
                 Y  = round(runif(11, 5, 10)),
                 A  = c(rep(9, 3), rep(10, 2), rep(11, 2), rep(12, 3), 13))

输入

DT
#    id    X Y  A
# 1:  1 0.09 6  9
# 2:  1 0.21 9  9
# 3:  1 0.73 9  9
# 4:  2 0.85 8 10
# 5:  2 0.79 8 10
# 6:  3 0.33 9 11
# 7:  3 0.08 7 11
# 8:  4 0.29 9 12
# 9:  4 0.24 6 12
# 10: 4 0.39 6 12
# 11: 5 0.37 9 13
# ...

我想要这样的事情:   对于id的每个子集:在所有常量变量之后(在每个id中,这里:A和id),通过创建新列(X,将所有不同的变量(在每个id中,这里:X和Y列)放在同一行中 - &gt; X1,X2,X3,Y - > Y1,Y2,Y3) id的出现次数不同,在我的情况下在1和3之间有所不同,因此所有出现次数小于3的id的缺失值应该用NA填充。

所需的输出

# id  A   X1 Y1   X2 Y2   X3 Y3
#  1  9 0.09  6 0.21  9 0.73  9
#  2 10 0.85  8 0.79  8   NA NA
#  3 11 0.33  9 0.08  7   NA NA
#  4 12 0.29  9 0.24  6 0.39  6
#  5 13 0.37  9   NA NA   NA NA
# ...

使用DT[,.N, by = id]很容易获得每个子集中的项目数,但我很难接下来的步骤。当然,列和行的数量要大得多,因此我更倾向于使用较少命名列的解决方案(但当然应该定义常量和不同的列)。

1 个答案:

答案 0 :(得分:2)

我们可以使用dcast

library(data.table)
res <- dcast(DT, id~rowid(id), value.var = c("X", "Y", "A"))
res[, c("id", names(res)[-1][order(sub("\\D+", "", names(res)[-1]))]), with = FALSE]