Roll join 在 data.table 中不给出 NA 值

Roll join does not give NA values in data.table

假设我有以下数据:

library(data.table)           
x1 <- structure(list(age = c(NA, 40L, 78L, 49L, 59L), 
                     age_cat = c(NA, "(39,50]", "(72,83]", "(39,50]", "(57,64]")),
                row.names = c(NA, -5L), class = c("data.table", "data.frame"))  

x2 <- structure(list(age = c(20.5, 25.5, 30.5, 35.5, 40.5, 45.5, 50.5, 
                             55.5, 60.5, 65.5, 70.5, 75.5, 80.5, 85.5, 90.5), 
                     yhat = c(2.04759618619815, 1.48463998876167, 
                              1.20171574722936, 1.05038762605566, 
                              1.00519209126108, 0.996948029536619, 
                              0.945501768666378, 0.834241582084186, 
                              0.731586245690655, 0.727522200367293, 
                              0.816133858934611, 0.817941581611403, 
                              0.498731829342745, 0.104433989674483, 
                              1.59446835516229)), 
                row.names = c(NA, -15L), 
                class = "data.frame")

然后创建一个函数来加入最接近的年龄:

join_nearest <- function(dat, reference, x){
  reference <- data.table::data.table(reference)
  dat <- data.table::data.table(dat)
  join <- reference[dat, roll = "nearest", on = x]
  as.data.frame(join)
}

这给出了以下解决方案:

join_nearest(x1, x2, "age")
#>   age      yhat age_cat
#> 1  NA 2.0475962    <NA>
#> 2  40 1.0051921 (39,50]
#> 3  78 0.8179416 (72,83]
#> 4  49 0.9455018 (39,50]
#> 5  59 0.7315862 (57,64]

如果 age 等于 NA 我期望 yhat 也等于 NA。我想知道为什么不是这种情况,有没有办法 return NA 对于 age 等于 NA 的行?

reprex package (v2.0.1)

于 2021-11-10 创建

您可以进行基于范围的手动联接。

前面:x1$age 是整数,但 x2$age 是数字,所以我会将第一个转换为 numeric,这样 data.table 就不会抱怨 class.

然后,我将在 x2 中创建 lo/hi 个字段,我们可以使用这些字段加入。如果你更喜欢断点不是中途,这很容易改变,根据你的需要。

x1[, age := as.numeric(age)]

x1[x2[, c("lo","hi") := .(age - c(age[1],diff(age)/2), age + c(diff(age)/2,Inf))
   ], yhat := i.yhat, on = .(age >= lo, age < hi),
   ][]
#      age age_cat      yhat
#    <num>  <char>     <num>
# 1:    NA    <NA>        NA
# 2:    40 (39,50] 1.0051921
# 3:    78 (72,83] 0.4987318
# 4:    49 (39,50] 0.9455018
# 5:    59 (57,64] 0.7315862

## cleanup
x2[, c("lo","hi") := NULL]

我认识到添加 lohi 的暂时副作用,因此需要清理。如果您的数据不大,您可以使用 copy(x2)[,c("lo","hi"):=...] 来避免这种情况,但会降低内存效率。