根据嵌套列表

时间:2016-08-24 03:20:47

标签: r list data.table

我有一个像这样的data.table:

library(data.table)    
dt <- data.table(a = c(rep("A", 3), rep("B", 3)), b = c(1, 3, 5, 2, 4, 6))

我需要对每个a的值执行操作(预测),所以我决定将它们放在一个列表中,如下所示:

dt <- dt[, x := .(list(b)), by = a][, .SD[1,], by = a, .SDcols = "x"]

现在我想“融化”(这是我想到的事情)dt回到原来的形式。

我可以在a这样的极少数级别执行此操作:

dt2 <- rbind(expand.grid(dt[1, a], dt[1, x[[1]]]), expand.grid(dt[2, a], dt[2, x[[1]]]))

但当然,对于更多级别的a,该解决方案是不切实际的。

我试过

dt2 <- dt[, expand.grid(a, x[[1]]), by = a]

导致

dt2
##    a Var1 Var2
## 1: A    A    1
## 2: A    A    3
## 3: A    A    5
## 4: B    A    2
## 5: B    A    4
## 6: B    A    6

有趣的是,Var1实际上并没有遵循预期的“A - B”模式(但至少a仍然存在)。

有没有更好的方法来实现这一目标?

编辑

预期输出将是

的结果
dt2[, .(a, Var2)]
  • 更正了“dcast”的“融化”。

1 个答案:

答案 0 :(得分:3)

您正在寻找一种方法nest(将列从原子矢量类型转换为列表类型)和unnest(相反方向)以data.table方式。这不同于重新整形数据,其中spread列值与行标题(dcast)或gather行标题为列值(melt):

在data.table语法中,您可以在目标列上使用listunlist来汇总或广播它以及组变量:

说我们是否从以下开始:

dt
#    a b
# 1: A 1
# 2: A 3
# 3: A 5
# 4: B 2
# 5: B 4
# 6: B 6

要重复您在第一步中取得的成就,即nestb,您可以这样做:

dt_nest <- dt[, .(b = list(b)), a]
dt_nest
#    a     b
# 1: A 1,3,5
# 2: B 2,4,6

要反方向,请将unlist与组变量一起使用:

dt_nest[, .(b = unlist(b)), a]
#    a b
# 1: A 1
# 2: A 3
# 3: A 5
# 4: B 2
# 5: B 4
# 6: B 6