如何使用dplyr基于间隔执行连接?

时间:2017-06-06 19:27:35

标签: r dplyr lubridate

我有一个包含两列的数据框:分组变量和分组变量所在的间隔时间段。我有另一个数据框,其中包含日期列和值列。如何使用dplyr + tidyverse函数将这两个表有效地连接在一起?

library(dplyr)
library(lubridate)
ty <- data_frame(date = mdy(paste(1, 1 + seq(20), 2017, sep = "/")), 
                 y = c(rnorm(7), rnorm(7, mean = 2), rnorm(6, mean = -1)))
gy <- data_frame(period = interval(mdy(c("01/01/2017", "01/08/2017", "01/15/2017")), 
                                   mdy(c("01/07/2017", "01/14/2017", "01/20/2017"))), 
                          batch = c(1, 2, 3))

我想构建一个等同于:

的表
ty %>% mutate(batch = c(rep(1, 7), rep(2, 7), rep(3, 6)))

理想情况下,对于最多1,000,000行的数据集,这应该能够合理地快速运行。更好的是,如果它的工作量为100,000,000:)。

2 个答案:

答案 0 :(得分:1)

怎么样:

ty %>% 
  mutate(batch = case_when(
  ty$date %within% gy$period[1] ~gy$batch[1],
  ty$date %within% gy$period[2] ~gy$batch[2],
  ty$date %within% gy$period[3] ~gy$batch[3]))

您显然需要定义case_when间隔。你有几个人?我过去使用catpaste0效果很好。

编辑以反映OP的评论。这应该照顾NSE,并允许以编程方式生成case_when间隔:

ty %>%
  mutate(batch = eval(parse(text = paste0("case_when(",
                                      paste(
                                        paste0(
                                          "ty$date %within% gy$period[",
                                          seq_along(gy$period),
                                          "] ~gy$batch[",
                                          seq_along(gy$period),
                                          "]"
                                        ),
                                        collapse = ", "
                                      ), ")"))))

答案 1 :(得分:0)

这是迄今为止我能想到的最好的结果:

ty$batch <- unlist(lapply(ty$date, function(d) gy$batch[which(d %within% gy$period)]), recursive = FALSE, use.names = FALSE)

但它看起来不是很快。