【问题标题】:merge two dataframes by nearest preceding date while aggregating在聚合时按最近的日期合并两个数据框
【发布时间】:2016-12-07 21:23:56
【问题描述】:

我正在尝试按最近的前一个日期按组匹配两个数据集。 因此,在一个组中,我想将第二个数据集(d2)的变量添加到第一个数据集(d1)的变量中,当第一个数据集的日期是第二个日期或之前的最近日期时。如果第二个数据集中的两行与第一行中的一行匹配,我想添加较大的值。 (按组,d1 中的日期总是比 d2 中的日期少一个日期)

这是一个例子,希望能更清楚

 d1 = data.frame(id=c(1,1,1,2,2), 
                 ref=as.Date(c("2013-12-07", "2014-12-07", "2015-12-07", "2013-11-07", "2014-11-07" )))
 d1
#   id        ref
# 1  1 2013-12-07
# 2  1 2014-12-07
# 3  1 2015-12-07
# 4  2 2013-11-07
# 5  2 2014-11-07

 d2 = data.frame(id=c(1,1,2),                
                 date=as.Date(c("2014-05-07","2014-12-05", "2015-11-05")),
                 x1 = factor(c(1,2,2), ordered = TRUE), 
                 x2 = factor(c(2, NA ,2), ordered=TRUE))
 d2
#   id    date x1   x2
# 1  1 2014-05-07  1    2
# 2  1 2014-12-05  2 <NA>
# 3  2 2015-11-05  2    2

预期结果

 output = data.frame(id=c(1,1,1,2,2),
                     ref=as.Date(c("2013-12-07", "2014-12-07", "2015-12-07", "2013-11-07", "2014-11-07" )),
                     x1 = c(2, NA, NA, NA, 2),
                     x2 = c(2, NA, NA, NA, 2))
 output
#   id        ref x1 x2
# 1  1 2013-12-07  2  2
# 2  1 2014-12-07 NA NA
# 3  1 2015-12-07 NA NA
# 4  2 2013-11-07 NA NA
# 5  2 2014-11-07  2  2

例如,d2 的前两个观测值,id=1,日期为"2014-05-07","2014-12-05",与 d1 中较早的日期"2013-12-07" 匹配。由于有两行与 d1 中的一行匹配, 然后选择最高级别。

我可以在基础 R 中通过循环以下计算来做到这一点 每个小组,但我希望有更有效的东西。 我很想看到 data.table 方法(但我仅限于 R v3.1 和 data.table v1.9.4)。谢谢

真实数据集:
d1:行 1M / 100K 组
d2:行 11K / 4K 组

# for one group
x = d1[d1$id==1, ]
y = d2[d2$id==1, ]
id = apply(outer(x$ref, y$date, "-"), 2, which.min)
temp = cbind(y, ref=x$ref[id])
# aggregate variables by ref
temp = merge(aggregate(x1 ~ ref, data=temp, max),
aggregate(x2 ~ ref, data=temp, max)
)
merge(x, temp, all=T)

ps:我查看了How to match by nearest date from two data frames?Join data.table on exact date or if not the case on the nearest less than date 没有成功。

【问题讨论】:

    标签: r data.table


    【解决方案1】:

    您可以使用dplyr

    d2$ind <- 0
    library(dplyr)
    out <- d1 %>% full_join(d2,by=c("id","ref"="date")) %>%
                  arrange(id,ref) %>%
                  mutate(ind=cumsum(ifelse(is.na(ind),1,ind))) %>%
                  group_by(ind) %>% 
                  summarise(ref=min(ref),x1=max(x1,na.rm=TRUE),x2=max(x2,na.rm=TRUE))
    ### A tibble: 5 x 4
    ##    ind        ref     x1     x2
    ##  <dbl>     <date> <fctr> <fctr>
    ##1     1 2013-12-07      2      2
    ##2     2 2014-12-07     NA     NA
    ##3     3 2015-12-07     NA     NA
    ##4     4 2013-11-07     NA     NA
    ##5     5 2014-11-07      2      2
    

    我们首先向d2 添加一列指标并将其设置为零。然后,我们在d1d2 之间执行完全外连接。 d1 中的那些行将具有 indNA。我们按idref(即日期)排序,并将indNA 条目替换为1 并执行cumsum。这导致:

      id        ref   x1   x2 ind
    1  1 2013-12-07 <NA> <NA>   1
    2  1 2014-05-07    1    2   1
    3  1 2014-12-05    2 <NA>   1
    4  1 2014-12-07 <NA> <NA>   2
    5  1 2015-12-07 <NA> <NA>   3
    6  2 2013-11-07 <NA> <NA>   4
    7  2 2014-11-07 <NA> <NA>   5
    8  2 2015-11-05    2    2   5
    

    由此我们可以很容易地看出,我们可以适当地按indsummarise 分组以获得您的结果。

    【讨论】:

      猜你喜欢
      • 2020-12-24
      • 1970-01-01
      • 1970-01-01
      • 2019-05-27
      • 2017-08-26
      • 2016-01-30
      • 2019-08-18
      • 2018-10-13
      • 2018-03-21
      相关资源
      最近更新 更多