4

我想dt根据查找表创建一个变量k。根据我如何提取感兴趣的变量,我得到了一些意想不到的结果k

dt <- data.table(x=c(1:10))
setkey(dt, x)

k <- data.table(x=c(1:5,10), b=c(letters[1:5], "d"))
setkey(k, x)

dt[,b:=k[.BY, list(b)],by=x]

dt  #unexpected results
#      x  b
#  1:  1  1
#  2:  2  2
#  3:  3  3
#  4:  4  4
#  5:  5  5
#  6:  6  6
#  7:  7  7
#  8:  8  8
#  9:  9  9
# 10: 10 10

dt <- data.table(x=c(1:10))
setkey(x, x)

dt[,b:=k[.BY]$b,by=x]

dt  #expected results
#      x  b
#  1:  1  a
#  2:  2  b
#  3:  3  c
#  4:  4  d
#  5:  5  e
#  6:  6 NA
#  7:  7 NA
#  8:  8 NA
#  9:  9 NA
# 10: 10  d

谁能解释为什么会这样?

4

1 回答 1

3

您根本不必在by=.这里使用。

第一个解决方案:

设置适当的键并使用 X[Y] 语法data.table

require(data.table)
dt <- data.table(x=c(1:10))
setkey(dt, "x")
k <- data.table(x=c(1:5,10), b=c(letters[1:5], "d"))
setkey(k, "x")

k[dt]

#      x  b
#  1:  1  a
#  2:  2  b
#  3:  3  c
#  4:  4  d
#  5:  5  e
#  6:  6 NA
#  7:  7 NA
#  8:  8 NA
#  9:  9 NA
# 10: 10  d

OP 说这会创建一个新的 data.table ,这对他来说是不可取的。

第二种解决方案

同样,没有by

dt <- data.table(x=c(1:10))
setkey(dt, "x")
k <- data.table(x=c(1:5,10), b=c(letters[1:5], "d"))
setkey(k, "x")

# solution
dt[k, b := i.b]

这不会创建新的data.table并提供您期望的解决方案。

解释为什么会发生意外结果:

对于您执行的第一种情况,dt[,b:=k[.BY, list(b)],by=x]. 在这里,k[.BY, list(b)]它本身返回一个data.table. 例如:

k[list(x=1), list(b)]

#    x b
# 1: 1 a

所以,基本上,如果你愿意:

k[list(x=dt$x), list(b)]

这也将为您提供所需的解决方案。要回答为什么你会得到你得到的东西b := k[.BY, list(b)],因为 RHS 返回 adata.table并且你正在为它分配一个变量,它需要第一个元素并丢弃其余元素。例如,这样做:

dt[, c := dt[1], by=x] 
# you'll get the whole column to be 1

对于第二种情况,要了解它的工作原理,您必须了解访问data.tableask[6]和之间的细微差别k[list(6)],例如:

在第一种情况下k[6],您正在访问 的第 6 个元素k,即10 d。但在第二种情况下,你要求一个J, join. 因此,它搜索 x = 6 (键列)并且由于没有任何 in k,它返回6 NA。在您的情况下,由于您使用k[.BY]which 返回一个列表,因此它是一个J获取正确值的操作。

我希望这有帮助。

于 2013-02-27T20:26:07.420 回答