我想根据查找表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
任何人都可以解释为什么会这样吗?
答案 0 :(得分:3)
您根本不必使用by=.
。
设置适当的密钥并使用data.table
中的X [Y]语法:
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返回一个data.table
并且你为它分配一个变量,它将获取第一个元素并删除其余元素。例如,执行以下操作:
dt[, c := dt[1], by=x]
# you'll get the whole column to be 1
对于第二种情况,要理解其工作原理,您必须了解与data.table
k[6]
和k[list(6)]
之间的细微差别},例如:
在第一种情况下,k[6]
,您正在访问k
的第6个元素,即10 d
。但在第二种情况下,你要求J, join
。因此,它搜索x = 6(键列),因为k
中没有,它返回6 NA
。在您的情况下,由于您使用返回列表的k[.BY]
,因此它是J
操作,它会获取正确的值。
我希望这会有所帮助。