【问题标题】:R: Merging 2 data frames with index on previous and past rowsR:将 2 个数据帧与前一行和过去行的索引合并
【发布时间】:2016-12-27 05:02:51
【问题描述】:

假设我有一个这样的数据集:

origin=data.frame(Date=as.Date(c("2016-08-05","2016-08-04","2016-08-03")),
                  L=c(1,2,3),
                  Type=c("H","L","H"))

        Date L Type
1 2016-08-05 1    H
2 2016-08-04 2    L
3 2016-08-03 3    H

end=data.frame(Date=as.Date(c("2016-08-05","2016-08-04","2016-08-03","2016-08-02","2016-08-01")),
               N=c(50,40,30,20,10),
               Name=c("CA","CB","CC","CD","CE"),
               Vol=c(2,1,2,2,3),
               Act=c(0.1,0.2,0.3,0.2,0.2))

        Date  N Name Vol Act
1 2016-08-05 50   CA   2 0.1
2 2016-08-04 40   CB   1 0.2
3 2016-08-03 30   CC   2 0.3
4 2016-08-02 20   CD   2 0.2
5 2016-08-01 10   CE   3 0.2

我想要这样的东西:

        Date L Type  N Name Vol Act
3 2016-08-05 1    H 50   CA   2 0.1
3 2016-08-05 1    H 40   CB   1 0.2
3 2016-08-05 1    H 30   CC   2 0.3
2 2016-08-04 2    L 40   CB   1 0.2
2 2016-08-04 2    L 30   CC   2 0.3
2 2016-08-04 2    L 20   CD   2 0.2
1 2016-08-03 3    H 30   CC   2 0.3
1 2016-08-03 3    H 20   CD   2 0.2
1 2016-08-03 3    H 10   CE   3 0.2

我想维护“origin”的原始列日期,并且在合并中,我想将它与“end”的当前和以前的日期值(两个以前的值)合并,就像一种合并一个循环。在其他帖子中,仅匹配公共值,这给出了 3 行结果:

merge(x = origin, y = end, by = "Date")

        Date L Type  N Name Vol Act
1 2016-08-03 3    H 30   CC   2 0.3
2 2016-08-04 2    L 40   CB   1 0.2
3 2016-08-05 1    H 50   CA   2 0.1

这是非常不同的,并且不会通过当前行和上一个行值合并两个数据帧,所以我无法弄清楚如何去做。

【问题讨论】:

    标签: r loops date merge


    【解决方案1】:

    看起来data.table 中的foverlaps 适合这份工作:

    # prepare data and add extra columns for foverlaps join which relies on columns instead of one
    library(data.table)
    setDT(origin)[, DateStart := Date - 2]
    setDT(end)[, DateStart := Date]
    setkey(origin, DateStart, Date)
    
    # join two tables with foverlaps and remove subsidiary columns
    foverlaps(end, origin, type = "within")[, `:=` (DateStart = NULL, i.Date = NULL, i.DateStart = NULL)][order(Date)]
    
    #          Date L Type  N Name Vol Act
    # 1: 2016-08-03 3    H 30   CC   2 0.3
    # 2: 2016-08-03 3    H 20   CD   2 0.2
    # 3: 2016-08-03 3    H 10   CE   3 0.2
    # 4: 2016-08-04 2    L 40   CB   1 0.2
    # 5: 2016-08-04 2    L 30   CC   2 0.3
    # 6: 2016-08-04 2    L 20   CD   2 0.2
    # 7: 2016-08-05 1    H 50   CA   2 0.1
    # 8: 2016-08-05 1    H 40   CB   1 0.2
    # 9: 2016-08-05 1    H 30   CC   2 0.3
    

    或者使用non-equi加入data.table版本1.9.7的功能:

    setDT(origin)[, `:=` (DateEnd = Date, StartDate = Date - 2)]
                 [setDT(end), on = .(DateEnd >= Date, StartDate <= Date), allow = T]
    
    #          Date L Type    DateEnd  StartDate  N Name Vol Act
    # 1: 2016-08-05 1    H 2016-08-05 2016-08-05 50   CA   2 0.1
    # 2: 2016-08-04 2    L 2016-08-04 2016-08-04 40   CB   1 0.2
    # 3: 2016-08-05 1    H 2016-08-04 2016-08-04 40   CB   1 0.2
    # 4: 2016-08-03 3    H 2016-08-03 2016-08-03 30   CC   2 0.3
    # 5: 2016-08-04 2    L 2016-08-03 2016-08-03 30   CC   2 0.3
    # 6: 2016-08-05 1    H 2016-08-03 2016-08-03 30   CC   2 0.3
    # 7: 2016-08-03 3    H 2016-08-02 2016-08-02 20   CD   2 0.2
    # 8: 2016-08-04 2    L 2016-08-02 2016-08-02 20   CD   2 0.2
    # 9: 2016-08-03 3    H 2016-08-01 2016-08-01 10   CE   3 0.2
    

    删除子列应该很简单。

    【讨论】:

    • 这实际上解决了我的问题。但是我没有意识到我在这里提出的数据框并没有完全反映问题。实际上,我需要合并 2 个数据帧,但第二个数据帧有多个列(最多 10 个),我最多需要 5 个滞后。所以我正在纠正这个问题,以充分反映这种情况。
    猜你喜欢
    • 1970-01-01
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-10
    • 1970-01-01
    • 2020-03-12
    • 2020-11-02
    相关资源
    最近更新 更多