在功能中将列合并到data.table

时间:2013-10-07 23:36:25

标签: r data.table

我需要在巨大的data.table dt.1中添加一个列(来自查找表dt.2)。可以这样做:

df.1 <- cbind(c(1,2,3,1,2,3,1,2,3),c(1,2,3,1,2,3,1,2,3),c(1,2,3,4,5,6,7,8,9))
colnames(df.1) <- c("ColA", "ColB", "ColC")
df.2 <- cbind(c(1,3),c(1,3),c(10,11))
colnames(df.2) <- c("ColA", "ColB", "ColD")
dt.1 <- data.table(df.1)
dt.2 <- data.table(df.2)

getAnotherColumn <- function() {
  keycols <- c("ColA", "ColB")
  setkeyv(dt.1, keycols)
  setkeyv(dt.2, keycols)
  dt.1 <- merge(dt.1, dt.2, all=TRUE)
  dt.1  # Will print with ColA, ColB, ColC, and ColD. As needed.
}

getAnotherColumn()
dt.1  # Only ColA, ColB, and ColC are here. ColD is also needed.

问题是我必须在函数内部执行它,所以在从函数返回时,旧的dt.1仍然存在(没有新的列ColD)。

如何将列添加到dt.1而不是创建新的dt.1?

由于dt.1非常庞大,我无法承担它的“额外副本”。

1 个答案:

答案 0 :(得分:3)

请注意,在函数内部,您将在此行中更改对象dt.1

   dt.1 <- merge(dt.1, dt.2, all=TRUE)

您正在为对象dt.1分配一个全新的值。碰巧新值与先前的dt.1值相关,但这与

没有什么不同。
   dt.1 <- "spaghetti"  # or any other unrelated value

要通过引用分配,您需要使用:=

getAnotherColumn <- function() {
  keycols <- c("ColA", "ColB")
  setkeyv(dt.1, keycols)
  setkeyv(dt.2, keycols)

  dt.1[dt.2, ColD := ColD]
}

getAnotherColumn()

现在ColD位于dt.1

> dt.1 
   ColA ColB ColC ColD
1:    1    1    1   10
2:    1    1    4   10
3:    1    1    7   10
4:    2    2    2   NA
5:    2    2    5   NA
6:    2    2    8   NA
7:    3    3    3   11
8:    3    3    6   11
9:    3    3    9   11