r - 通过匹配日期合并2个数据框

标签 r merge dataframe dplyr

我有两个数据框:

id      dates
MUM-1  2015-07-10
MUM-1  2015-07-11
MUM-1  2015-07-12
MUM-2  2014-01-14
MUM-2  2014-01-15
MUM-2  2014-01-16
MUM-2  2014-01-17

和:
id      dates      field1  field2
MUM-1  2015-07-10     1       0
MUM-1  2015-07-12     2       1
MUM-2  2014-01-14     4       3
MUM-2  2014-01-17     0       1

合并数据:
id      dates        field1   field2
MUM-1  2015-07-10      1         0
MUM-1  2015-07-11      na        na
MUM-1  2015-07-12      2         1
MUM-2  2014-01-14      4         3
MUM-2  2014-01-15      na        na
MUM-2  2014-01-16      na        na
MUM-2  2014-01-17      0         1   

代码:merge(x= df1, y= df2, by= 'id', all.x= T)
我正在使用合并,但是由于两个数据帧的大小太大,因此处理时间太长。合并功能还有其他选择吗?也许在dplyr?这样就可以快速进行比较。两个数据帧都有超过900K的行。

最佳答案

除了将mergedata.table结合使用外,您还可以按照以下方式简单地加入:

setDT(df1)
setDT(df2)

df2[df1, on = c('id','dates')]

这给出了:
> df2[df1]
      id      dates field1 field2
1: MUM-1 2015-07-10      1      0
2: MUM-1 2015-07-11     NA     NA
3: MUM-1 2015-07-12      2      1
4: MUM-2 2014-01-14      4      3
5: MUM-2 2014-01-15     NA     NA
6: MUM-2 2014-01-16     NA     NA
7: MUM-2 2014-01-17      0      1

使用dplyr做到这一点:
library(dplyr)
dplr <- left_join(df1, df2, by=c("id","dates"))

正如@Arun在评论中所提到的,基准对于具有七行的小型数据集不是很有意义。因此,让我们创建一些更大的数据集:
dt1 <- data.table(id=gl(2, 730, labels = c("MUM-1", "MUM-2")),
                  dates=c(seq(as.Date("2010-01-01"), as.Date("2011-12-31"), by="days"),
                          seq(as.Date("2013-01-01"), as.Date("2014-12-31"), by="days")))
dt2 <- data.table(id=gl(2, 730, labels = c("MUM-1", "MUM-2")),
                  dates=c(seq(as.Date("2010-01-01"), as.Date("2011-12-31"), by="days"),
                          seq(as.Date("2013-01-01"), as.Date("2014-12-31"), by="days")),
                  field1=sample(c(0,1,2,3,4), size=730, replace = TRUE),
                  field2=sample(c(0,1,2,3,4), size=730, replace = TRUE))
dt2 <- dt2[sample(nrow(dt2), 800)]

可以看出,@ Arun的方法稍快一些:
library(rbenchmark)
benchmark(replications = 10, order = "elapsed", columns = c("test", "elapsed", "relative"),
          jaap = dt2[dt1, on = c('id','dates')],
          pavo = merge(dt1,dt2,by="id",allow.cartesian=T),
          dplr = left_join(dt1, dt2, by=c("id","dates")),
          arun = dt1[dt2, c("fiedl1", "field2") := .(field1, field2), on=c("id", "dates")])

  test elapsed relative
4 arun   0.015    1.000
1 jaap   0.016    1.067
3 dplr   0.037    2.467
2 pavo   1.033   68.867

有关大型数据集的比较,请参见the answer of @Arun

关于r - 通过匹配日期合并2个数据框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31876335/

相关文章:

r - 使用 pROC 的 PPV 和 NPV CI

r - 在R中将字符列转换为具有混合数字和日期的日期

Pandas 合并具有相同值和相同索引的行

python - 将新列迭代添加到具有唯一列名称的数据框

r - 使用 shift() 进行递归在 data.table 中生成多列

git - 什么是正确的 Git p4 工作流程?

merge - 数据 block 三角洲湖的 MERGE INTO 的 pyspark 等价物是什么?

python - Pandas 丢弃重复项而忽略 NaN

python - 如果列中存在匹配值,则使用另一个数据帧注释一个数据帧

R:双枢轴使用 DPLYR?