简体   繁体   中英

Using comparison in assignment in data.table in R

I need to create a new column in my data.table dt . This column will contain data from a data.frame df . My data is as follows:

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))

Now, I want to create a new column called col in dt based on the value of value that will contain the letter from df which corresponds to the smallest larger or equal value of number than value . To give an example, the first row of column col should contain A since 1 (that is the number column from df that corresponds to A ) is the smallest value larger than or equal to 0.5, the value in the first row of dt . I tried the following code:

dt[, col := df[which(value <= df[, 2])[1], 1]]

but that puts A to all rows. I could this with data.frame as follows:

setDF(dt)
for(i in 1:nrow(dt)) {
 dt$col[i] <- as.character(df[which(dt$value[i] <= df[, 2])[1], 1])
}

which produces the desired output of A, C, F, I, E, B, B, H, and NA. How could I do this with data.table ?

You can do this with a rolling join. However, number and value will both have to be of the same type first:

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

To catch problems like this (merging double with integer) more easily, use 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

You can set verbosity on for the full R session with options(datatable.verbose = TRUE) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM