слияние по критериям - PullRequest
       7

слияние по критериям

0 голосов
/ 29 августа 2018

Я пытаюсь объединить два набора данных df1, df2.

Данные в моем первом наборе данных (df1) выглядят следующим образом

     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

Это данные из моего второго набора данных (df2)

     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

1) Я пытаюсь объединить эти два набора данных по идентификатору
2) В дополнение к объединению с помощью = "Id" значение емкости должно быть основано на df1$ServiceDate между df2$Effective_Dt и df2$Effct_End_Dt.

Например, ожидаемый результат должен выглядеть следующим образом

     Id       ServiceDate       Capacity 
    234       2004-02-10        10
    234       2003-11-05        17 
    234       2002-06-07        17
 117458       2002-03-14        11 
 117458       2003-03-17        11
 117458       2004-07-05        11
2195623       2002-04-12        22 
2195623       2003-08-15        27
2195623       2004-09-10        25

Я могу выполнить слияние по идентификатору, но не уверен, как включить вторую логику, включающую емкость, основанную на ограничении даты. Буду признателен за любую оказанную помощь. Благодарю.

Ответы [ 2 ]

0 голосов
/ 29 августа 2018

Используя dplyr, вы можете сделать простое левое соединение, а затем отфильтровать строки и столбцы, которые вам не нужны ...

library(dplyr)
df1 %>% left_join(df2) %>% 
        filter(as.Date(ServiceDate)>=as.Date(Effective_Dt),
               as.Date(ServiceDate)<=as.Date(Effct_End_Dt)) %>% 
        select(-Effective_Dt,
               -Effct_End_Dt)

       Id 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

Обратите внимание, что последние три цифры Capacity отличаются от вашего ответа - что, по-видимому, неверно на основании ваших данных.

0 голосов
/ 29 августа 2018

Вот идея с нечетким соединением:

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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...