3

我有两个数据框(实际上是 data.tables)。

set.seed(123)
dt1 <- data.table(P=rep(letters[1:3],c(4,2,3)),X=sample(9))
dt1
   P X
1: a 3
2: a 7
3: a 9
4: a 6
5: b 5
6: b 1
7: c 2
8: c 8
9: c 4

和:

dt2 <- data.table(P=rep(letters[1:5],length=10),D=c("X","Y","Z","G","F"))
dt2
    P D
 1: a X
 2: b Y
 3: c Z
 4: d G
 5: e F
 6: a X
 7: b Y
 8: c Z
 9: d G
10: e F

现在我想在 dt1 中添加一个新列,其中 dt2 的列“D”中 P 在 dt1 和 dt2 中具有相同的值。它应该如下所示:

dt_new
   P X D
1: a 3 X
2: a 7 X
3: a 9 X
4: a 6 X
5: b 5 Y
6: b 1 Y
7: c 2 Z
8: c 8 Z
9: c 4 Z
4

2 回答 2

7

我会这样做data.table join

setkey(dt1, P)
dt1[unique(dt2),nomatch=0]

   P X D
1: a 3 X
2: a 7 X
3: a 9 X
4: a 6 X
5: b 5 Y
6: b 1 Y
7: c 2 Z
8: c 8 Z
9: c 4 Z
于 2013-08-20T22:31:54.320 回答
6

+1 对 Arun 的回答。要显示按引用更新的方式来执行此操作...

再次来自问题的示例数据:

set.seed(123)
dt1 = data.table(P=rep(letters[1:3],c(4,2,3)),X=sample(9))
dt2 = data.table(P=rep(letters[1:5],length=10),D=c("X","Y","Z","G","F"))

unique()使用Arun删除示例数据中的重复数据:

dt2 = unique(dt2)  
dt2
   P D
1: a X
2: b Y
3: c Z
4: d G
5: e F

现在通过引用 dt1 和来自 dt2 的数据添加 D。就像 SQL 中的外键一样。诚然,这种语法并不明显或特别优雅,但它确实避免了dt1. dt1因此,如果说 10GB 大小,它可以明显更快。

setkey(dt2, P)
dt1[,D:={ .P=P           # allows us to refer to the P from dt1 on next line
          dt2[.P,D]$D}]  # since P is type character, no need to J() or .()
dt1
   P X D
1: a 3 X
2: a 7 X
3: a 9 X
4: a 6 X
5: b 5 Y
6: b 1 Y
7: c 2 Z
8: c 8 Z
9: c 4 Z

或者,将重复项保留在 dt2 中:

set.seed(123)
dt1 = data.table(P=rep(letters[1:3],c(4,2,3)),X=sample(9))
dt2 = data.table(P=rep(letters[1:5],length=10),D=c("X","Y","Z","G","F"))
setkey(dt2,P)
dt2
    P D
 1: a X
 2: a X
 3: b Y
 4: b Y
 5: c Z
 6: c Z
 7: d G
 8: d G
 9: e F
10: e F
dt1[,D:={ .P=P
          dt2[.P,D,mult="first"]}]
dt1
   P X D
1: a 3 X
2: a 7 X
3: a 9 X
4: a 6 X
5: b 5 Y
6: b 1 Y
7: c 2 Z
8: c 8 Z
9: c 4 Z
于 2013-08-21T04:06:19.103 回答