在R中的data.table中使用赋值进行比较

时间:2017-03-21 17:51:01

标签: r data.table

我需要在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 1number dfA对应{{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做到这一点?

1 个答案:

答案 0 :(得分:0)

您可以使用滚动连接执行此操作。但是,numbervalue首先必须属于同一类型:

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会话设置详细程度。