我需要在data.table
dt
中创建一个新列。此列将包含data.frame
df
的数据。我的数据如下:
library(data.table)
df <- data.frame(letter = LETTERS[1:9], number = 1:9)
dt <- data.table(value = c(0.5, 2.5, 6, 8.5, 4.5, 1.6, 1.3, 7.8, 9.2))
现在,我想在col
中根据dt
的值value
创建一个名为letter
的新列,其中包含来自df
的{{1}}对应于number
的最小值大于等于value
的值。举一个例子,第col
列的第一行应该包含A
1
(number
df
列A
对应{{1} }})是大于或等于0.5的最小值,value
的第一行中的dt
。我尝试了以下代码:
dt[, col := df[which(value <= df[, 2])[1], 1]]
但是将A
放到所有行中。我可以使用data.frame
进行如下操作:
setDF(dt)
for(i in 1:nrow(dt)) {
dt$col[i] <- as.character(df[which(dt$value[i] <= df[, 2])[1], 1])
}
产生A,C,F,I,E,B,B,H和NA的所需输出。我怎么能用data.table
做到这一点?
答案 0 :(得分:0)
您可以使用滚动连接执行此操作。但是,number
和value
首先必须属于同一类型:
setDT(df)
df[, number := as.numeric(number)]
dt[, v := df[.SD, on=.(number = value), roll=-Inf, letter]]
value col v
1: 0.5 A A
2: 2.5 C C
3: 6.0 F F
4: 8.5 I I
5: 4.5 E E
6: 1.6 B B
7: 1.3 B B
8: 7.8 H H
9: 9.2 NA NA
要更容易地捕获这样的问题(将整数与double合并),请使用verbose
:
# when number is still an int...
df[dt, on=.(number = value), roll=-Inf, verbose=TRUE]
Calculated ad hoc index in 0 secs
Coercing double column i.'value' to integer to match type of x.'number'. Please avoid coercion for efficiency.
Starting bmerge ...done in 0 secs
letter number
1: A 0
2: B 2
3: F 6
4: H 8
5: D 4
6: A 1
7: A 1
8: G 7
9: I 9
您可以使用options(datatable.verbose = TRUE)
为完整的R会话设置详细程度。