【问题标题】:Roll join does not give NA values in data.table滚动连接不会在 data.table 中给出 NA 值
【发布时间】:2021-12-23 01:18:24
【问题描述】:

假设我有以下数据:

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。我想知道为什么不是这样,有没有办法为 age 等于 NA 的行返回 NA?

reprex package 创建于 2021-11-10 (v2.0.1)

【问题讨论】:

    标签: r join data.table


    【解决方案1】:

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

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

    从那里,我将在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"):=...] 来回避这一点,但会降低内存效率。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-08-08
      • 2018-06-24
      • 2012-08-15
      • 2016-04-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多