Merge dataframes on matching A, B and *closest* C?

前端 未结 3 1243
走了就别回头了
走了就别回头了 2020-12-05 11:14

I have two dataframes like so:

set.seed(1)
df <- cbind(expand.grid(x=1:3, y=1:5), time=round(runif(15)*30))
to.merge <- data.frame(x=c(2, 2, 2, 3, 2),
         


        
3条回答
  •  我在风中等你
    2020-12-05 12:05

    Use data.table and roll='nearest' or to limit to 1, roll = 1, rollends = c(TRUE,TRUE)

    eg

    library(data.table)
    # create data.tables with the same key columns (x, y, time)
    DT <- data.table(df, key = names(df))
    tm <- data.table(to.merge, key = key(DT))
    
    # use join syntax with roll = 'nearest'
    
    
    tm[DT, roll='nearest']
    
    #     x y time val
    #  1: 1 1    8  NA
    #  2: 1 2   27  NA
    #  3: 1 3   28  NA
    #  4: 1 4    2  NA
    #  5: 1 5   21  NA
    #  6: 2 1   11   c
    #  7: 2 2    6  NA
    #  8: 2 3   20  NA
    #  9: 2 4    6   e
    # 10: 2 5   12  NA
    # 11: 3 1   17  NA
    # 12: 3 2   27  NA
    # 13: 3 3   19  NA
    # 14: 3 4    5  NA
    # 15: 3 5   23   d
    

    You can limit your self to looking forward and back (1) by setting roll=-1 and rollends = c(TRUE,TRUE)

    new <- tm[DT, roll=-1, rollends  =c(TRUE,TRUE)]
    new
        x y time val
     1: 1 1    8  NA
     2: 1 2   27  NA
     3: 1 3   28  NA
     4: 1 4    2  NA
     5: 1 5   21  NA
     6: 2 1   11   c
     7: 2 2    6  NA
     8: 2 3   20  NA
     9: 2 4    6  NA
    10: 2 5   12  NA
    11: 3 1   17  NA
    12: 3 2   27  NA
    13: 3 3   19  NA
    14: 3 4    5  NA
    15: 3 5   23   d
    

    Or you can roll=1 first, then roll=-1, then combine the results (tidying up the val.1 column from the second rolling join)

    new <- tm[DT, roll = 1][tm[DT,roll=-1]][is.na(val), val := ifelse(is.na(val.1),val,val.1)][,val.1 := NULL]
    new
        x y time val
     1: 1 1    8  NA
     2: 1 2   27  NA
     3: 1 3   28  NA
     4: 1 4    2  NA
     5: 1 5   21  NA
     6: 2 1   11   c
     7: 2 2    6  NA
     8: 2 3   20  NA
     9: 2 4    6  NA
    10: 2 5   12  NA
    11: 3 1   17  NA
    12: 3 2   27  NA
    13: 3 3   19  NA
    14: 3 4    5  NA
    15: 3 5   23   d
    

提交回复
热议问题