使用重复键滚动连接

rolling joins with duplicate keys

考虑这个简单的例子

library(dplyr)
library(lubridate)
library(data.table)


masterdf <- data.table(time = c(ymd('2019-02-01'),
                                ymd('2019-02-01'),
                                ymd('2019-03-01')),
                       var = c(1,2,3))

masterdf[, mykey := time]
setkey(masterdf, 'mykey')
> masterdf
         time var      mykey
1: 2019-02-01   1 2019-02-01
2: 2019-02-01   2 2019-02-01
3: 2019-03-01   3 2019-03-01

slavedf <- data.table(timeref = c(ymd('2019-01-01'),
                                  ymd('2019-01-28'),
                                  ymd('2019-01-29')))

slavedf[, mykey := timeref]
setkey(slavedf, 'mykey')
> slavedf
      timeref      mykey
1: 2019-01-01 2019-01-01
2: 2019-01-28 2019-01-28
3: 2019-01-29 2019-01-29

我想要实现的是一个经典的滚动连接问题。对于 masterdf 中的每个日期,slavedf 中最近的前一个日期是什么?

使用以下语法 returns 令人费解的结果:

> #rolling join
> masterdf[slavedf, roll = - Inf]
         time var      mykey    timeref
1: 2019-02-01   1 2019-01-01 2019-01-01
2: 2019-02-01   1 2019-01-28 2019-01-28
3: 2019-02-01   1 2019-01-29 2019-01-29

如您所见,人们希望 masterdf 的两个 2019-02-01 日期与 slavedf 的相同(最接近)2019-01-29 日期匹配,并且masterdf 中的 2019-03-01 也与 2019-01-29 匹配。

在这里您可以看到情况并非如此,并且 2019-03-01 甚至不存在于输出中......我认为来自重复键。知道该怎么做吗?

谢谢!

如果你这样做:

slavedf[masterdf, roll = T]

这给出:

      timeref      mykey       time var
1: 2019-01-29 2019-02-01 2019-02-01   1
2: 2019-01-29 2019-02-01 2019-02-01   2
3: 2019-01-29 2019-03-01 2019-03-01   3

让我们以我们的主要数据框 df (X) 和辅助数据框 df1 (Y) 为例。

df <- data.frame(A = c("A", "A", "A", "B", "B"),
                 B = c(2, 2, 3, 4, 3)
)

df1 <- data.frame(A = c("A", "B", "C"),
                  val = c(1000, 100, 500)
)

左连接 dplyr:

df %>% left_join(df1, by = "A")

  A B  val
1 A 2 1000
2 A 2 1000
3 A 3 1000
4 B 4  100
5 B 3  100

那么data.table中的left join是什么?也许:

setDT(df)
setDT(df1)

df[df1, on = "A"]

   A  B  val
1: A  2 1000
2: A  2 1000
3: A  3 1000
4: B  4  100
5: B  3  100
6: C NA  500

也许不是 - 怎么样:

setDT(df)
setDT(df1)

df1[df, on = "A"]

   A  val B
1: A 1000 2
2: A 1000 2
3: A 1000 3
4: B  100 4
5: B  100 3

是的!这在 this vignette 中也解释为 X[DT, on="x"] # left join.