【问题标题】:rolling joins with duplicate keys具有重复键的滚动连接
【发布时间】:2019-08-01 05:34:12
【问题描述】:

考虑这个简单的例子

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 中最近的前一个日期是什么?

使用以下语法会返回令人费解的结果:

> #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 日期匹配,并且来自masterdf2019-03-01 将被匹配2019-01-29 也一样。

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

谢谢!

【问题讨论】:

  • 我会尝试slavedf[masterdf, roll = T]。它给出了Jan-29,尽管这是最接近的

标签: r data.table lubridate


【解决方案1】:

如果你这样做:

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 中的左连接是什么?也许:

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

【讨论】:

  • 谢谢,这似乎确实有效。你能解释一下为什么会这样吗?这里的逻辑是什么?
  • 这是翻译“数据框 B (slavedf) 中的内容位于数据框 A (masterdf) 之前的内容”的标准方式。您的放置方式用于检查紧随其后的内容 - 因此它产生了正确的结果。
  • 令我困惑的是,语法X[Y] 的意思是X left join Y。我说的对吗?本质上,我正在尝试进行左连接(将所有行保留在 X 中),同时在 Y 中滚动键(在 Y 中找到与 X 中的当前键最近的键)
  • 在我的帖子中查看我的演示
  • roll = TRUE 给出的第一个值等于或低于,roll = -Inf 的第一个值等于或高于 :)
猜你喜欢
  • 2015-11-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-03
  • 2016-10-11
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
相关资源
最近更新 更多