如何使用 dplyr 基于间隔执行连接?
How to perform a join based on intervals with dplyr?
我有一个包含两列的数据框:一个分组变量和一个分组变量所在的区间。我有另一个带有日期列和值列的数据框。如何使用 dplyr+tidyverse 函数将这两个 table 有效地连接在一起?
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))
我想构建等同于:
的 table
ty %>% mutate(batch = c(rep(1, 7), rep(2, 7), rep(3, 6)))
理想情况下,这应该可以在最多 1,000,000 行的数据集上相当快速地工作。更好的是,如果它适用于 100,000,000 :).
这是迄今为止我能想到的最好的:
ty$batch <- unlist(lapply(ty$date, function(d) gy$batch[which(d %within% gy$period)]), recursive = FALSE, use.names = FALSE)
但是好像不是很快
怎么样:
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 间隔。你有几个?我过去使用 cat
和 paste0
效果很好。
编辑以反映 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 = ", "
), ")"))))
我有一个包含两列的数据框:一个分组变量和一个分组变量所在的区间。我有另一个带有日期列和值列的数据框。如何使用 dplyr+tidyverse 函数将这两个 table 有效地连接在一起?
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))
我想构建等同于:
的 tablety %>% mutate(batch = c(rep(1, 7), rep(2, 7), rep(3, 6)))
理想情况下,这应该可以在最多 1,000,000 行的数据集上相当快速地工作。更好的是,如果它适用于 100,000,000 :).
这是迄今为止我能想到的最好的:
ty$batch <- unlist(lapply(ty$date, function(d) gy$batch[which(d %within% gy$period)]), recursive = FALSE, use.names = FALSE)
但是好像不是很快
怎么样:
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 间隔。你有几个?我过去使用 cat
和 paste0
效果很好。
编辑以反映 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 = ", "
), ")"))))