代码之家  ›  专栏  ›  技术社区  ›  eun lee

如何按行使用另一个表中的which.min

  •  0
  • eun lee  · 技术社区  · 6 年前

    我尝试从另一个具有最小值的data.frame获取数据。

    有两种数据集,即卡片和日志。

    卡片

    #    id      BSTN    ASTN    BSEC    ASEC
    #    201557  151     150     60633   61302
    #    201558  151     150     60159   60680
    #    201559  151     150     44757   45149
    #    201560  151     150     77551   77923
    #    201561  151     150     61160   61606
    

        TRNID   ASTN    TIME
    #    1   150     45140
    #    2   150     61300
    #    3   150     61600
    #    4   150     68570
    #    5   150     77900
    #    6   150     79125
    #    7   150     82477
    #    8   150     82767
    

    我想要的是使用下面的函数log[which.min(card$ASEC log$TIME)]

    data.frame的最终结果如下:

    #    id      BSTN    ASTN    BSEC    ASEC    TRNID   TIME
    #    201557  151     150     60633   61302   2       61300
    #    201558  151     150     60159   60680   2       61300
    #    201559  151     150     44757   45149   1       45140
    #    201560  151     150     77551   77923   5       77900
    #    201561  151     150     61160   61606   3       61600
    
    3 回复  |  直到 4 年前
        1
  •  2
  •   mt1022    6 年前

    另一种方法是滚动连接:

    library(data.table)
    setDT(log)
    setDT(card)
    
    log[, ASEC := TIME]
    res <- log[card, roll = -Inf, on = .(ASTN, ASEC)]
    
    # >res
    #
    #    TRNID ASTN  TIME  ASEC     id BSTN  BSEC
    # 1:     2  150 61350 61302 201557  151 60633
    # 2:     2  150 61350 60680 201558  151 60159
    # 3:     1  150 46140 45149 201559  151 44757
    # 4:     5  150 77950 77923 201560  151 77551
    # 5:     3  150 61650 61606 201561  151 61160
    

    滚动联接将在中找到一个间隔 log 对于最后一个联接列的每个值( ASEC )在 card . -Inf 日志 将用于匹配中的值

        2
  •  1
  •   r2evans    6 年前

    因为您需要比较所有数据之间的(绝对值)差异 card$ASEC log$TIME outer

    outer(card$ASEC, log$TIME, `-`)
    #       [,1]   [,2]   [,3]   [,4]   [,5]   [,6]   [,7]   [,8]
    # [1,] 15162    -48   -348  -7268 -16648 -17823 -21175 -21465
    # [2,] 14540   -670   -970  -7890 -17270 -18445 -21797 -22087
    # [3,]  -991 -16201 -16501 -23421 -32801 -33976 -37328 -37618
    # [4,] 31783  16573  16273   9353    -27  -1202  -4554  -4844
    # [5,] 15466    256    -44  -6964 -16344 -17519 -20871 -21161
    

    我们可以快速减少该值(每行),以找到最小绝对值:

    ( ind <- apply(abs(outer(card$ASEC, log$TIME, `-`)), 1, which.min) )
    # [1] 2 2 1 5 3
    
    cbind.data.frame(card, log[ind,], stringsAsFactors=FALSE)
    #         id BSTN ASTN  BSEC  ASEC TRNID ASTN  TIME
    # 2   201557  151  150 60633 61302     2  150 61350
    # 2.1 201558  151  150 60159 60680     2  150 61350
    # 1   201559  151  150 44757 45149     1  150 46140
    # 5   201560  151  150 77551 77923     5  150 77950
    # 3   201561  151  150 61160 61606     3  150 61650
    
        3
  •  1
  •   Ronak Shah    6 年前

    ASEC 我们找到了最小值的指数 TIME log 使用该索引返回相应的 TRNID 值并将其添加到的原始数据帧中 card .

    card[c("TRNID", "TIME")] <- do.call("rbind", lapply(card$ASEC, function(x) {
                   inds <- log$TIME - x 
                   idx <- which(inds %in% max(inds[inds < 0]))
                   c(log$TRNID[idx], log$TIME[idx])
    }))
    
    card
    
    #      id BSTN ASTN  BSEC  ASEC TRNID  TIME
    #1 201557  151  150 60633 61302     2 61300
    #2 201558  151  150 60159 60680     1 45140
    #3 201559  151  150 44757 45149     1 45140
    #4 201560  151  150 77551 77923     5 77900
    #5 201561  151  150 61160 61606     3 61600