r根据条件合并

时间:2018-08-29 18:00:32

标签: r filter merge

我正在尝试合并两个数据集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)我正在尝试通过ID合并这两个数据集
2)除了通过“ Id”合并外,“容量”值还应基于df1$ServiceDatedf2$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

我可以按ID进行合并,但不确定如何包含第二个逻辑,该逻辑包括基于日期约束的Capacity。任何帮助深表感谢。谢谢。

2 个答案:

答案 0 :(得分:1)

这是一个模糊连接的想法:

polymorphic_allocator

首先将日期字符串转换为实际日期

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 df2的Fuzzy_left_join

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

答案 1 :(得分:0)

使用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数字与您的答案不同-根据您的数据,这似乎是错误的。