Вот идея с нечетким соединением:
library(fuzzyjoin)
library(dplyr)
Сначала преобразовать строки даты в фактические даты
df2 %>%
mutate(Effective_Dt = as.Date(Effective_Dt),
Effct_End_Dt = as.Date(Effct_End_Dt)) -> df2
df1 %>%
mutate(ServiceDate = as.Date(ServiceDate)) -> df1
Затем выполните fuzzy_left_join от df2
до df1
df1 %>%
fuzzy_left_join(df2,
by = c("Id" = "Id",
"ServiceDate" = "Effective_Dt",
"ServiceDate" = "Effct_End_Dt"), #variables to join by
match_fun = list(`==`, `>=`, `<=`)) %>% #function to use for each pair of variables
select(c(1,2,6)) #select just needed variables
#output:
Id.x ServiceDate Capacity
1 234 2004-02-10 10
2 234 2003-11-05 17
3 234 2002-06-07 17
4 117458 2002-03-14 11
5 117458 2003-03-17 11
6 117458 2004-07-05 11
7 2195623 2002-04-12 22
8 2195623 2002-08-15 22
9 2195623 2002-09-10 22
другие опции (после преобразования в дату) включают неэквивалентное объединение в data.table
library(data.table)
setDT(df1)
setDT(df2)
df1[df2, on = .(Id = Id, ServiceDate >= Effective_Dt, ServiceDate <= Effct_End_Dt), nomatch = 0]
#output
Id ServiceDate ServiceDate.1 Capacity
1: 234 2004-01-01 2004-12-31 10
2: 234 2002-01-01 2003-12-31 17
3: 234 2002-01-01 2003-12-31 17
4: 117458 2000-03-14 2004-12-31 11
5: 117458 2000-03-14 2004-12-31 11
6: 117458 2000-03-14 2004-12-31 11
7: 2195623 1995-04-01 2003-05-25 22
8: 2195623 1995-04-01 2003-05-25 22
9: 2195623 1995-04-01 2003-05-25 22
и, вероятно, sqldf
, с которым я не так хорошо знаком.
данные
df1 <- read.table(text="Id ServiceDate
234 2004-02-10
234 2003-11-05
234 2002-06-07
117458 2002-03-14
117458 2003-03-17
117458 2004-07-05
2195623 2002-04-12
2195623 2002-08-15
2195623 2002-09-10", header = TRUE)
df2 <- read.table(text="Id Effective_Dt Effct_End_Dt Capacity
234 2004-01-01 2004-12-31 10
234 2002-01-01 2003-12-31 17
117458 2000-03-14 2004-12-31 11
2195623 1995-04-01 2003-05-25 22
2195623 2003-05-26 2004-04-17 27
2195623 2004-04-18 2004-12-31 25", header = TRUE)