Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/80.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
根据R中的规则连接data.frames_R_Dataframe_Join_Merge - Fatal编程技术网

根据R中的规则连接data.frames

根据R中的规则连接data.frames,r,dataframe,join,merge,R,Dataframe,Join,Merge,我有以下data.frame(data.frame_1),从2019-10-01到2020-10-01,每个clinic_code,它是包含许多变量的主要data.frame(以下仅显示了少数变量): 然后是从2019-10-01到2020-02-31的旧版本(data.frame_2): clinic_code partner_code partnership_start_date partnership_end_date A05 00033

我有以下data.frame(data.frame_1),从2019-10-01到2020-10-01,每个
clinic_code
,它是包含许多变量的主要data.frame(以下仅显示了少数变量):

然后是从2019-10-01到2020-02-31的旧版本(data.frame_2):

clinic_code    partner_code    partnership_start_date    partnership_end_date
A05            00033           2019-10-01                NA
A12            00001           2019-10-01                NA
A12            00001           2019-10-01                2019-12-31 
A12            00044           2020-01-01                NA
B17            00002           2019-10-01                NA
我想使用data.frame_2来填充data.frame_1中
partner_code
中的空格。(+主数据框_1中的所有其他变量):

我的标准是:在data.frame 2中的
partner\u code
上填写data.frame\u 1关于
partner\u code
的任何额外信息。我的3个可能的场景:

  • A05-data.frame_1没有关于A05的
    partner_code
    的任何信息,我使用的是从
    partnership_start_date
    (2019-10-01)到
    partnership_end_date
    的data.frame_2的信息(如果不适用,则表示未结束)
  • A12-data.frame_1包含一些关于特定日期(2020-01-01)的
    合作伙伴代码
    ,但之前没有任何信息,因此我使用了从
    合作伙伴关系开始日期
    (2019-10-01)到
    合作伙伴关系结束日期
    (2019-12-31)的data.frame_2中的信息
  • B17-data.frame_1包含一些关于特定日期(2020-03-01)的
    合作伙伴代码的信息,但之前没有任何信息,因此我使用了从
    合作伙伴开始日期(2019-10-01)到
    合作伙伴结束日期的data.frame_2中的信息
    (NA=未结束;在这种情况下,因为data.frame_1中有一个2020-03-01的
    合作伙伴_代码
    ,我不想覆盖它并保留data.frame_1中的内容

  • 我想这就是你想要的

    library(dplyr)
    library(tidyr)
    
    prep <- 
      . %>% 
      as_tibble() %>% 
      mutate(across(ends_with("date"), as.Date))
    
    prep(data.frame_2) %>% 
      group_by(clinic_code, partner_code) %>% 
      slice(which.max(order(partnership_end_date, na.last = FALSE))) %>% 
      mutate(partnership_end_date = if_else(is.na(partnership_end_date), as.Date("2020-10-01"), partnership_end_date)) %>% 
      expand(date = seq.Date(partnership_start_date, partnership_end_date, by = "month"), clinic_code, partner_code) %>% 
      left_join(prep(data.frame_1), ., by = c("date", "clinic_code"), suffix = c("", ".2")) %>% 
      mutate(partner_code = coalesce(partner_code, partner_code.2)) %>% 
      select(-partner_code.2)
    
    一些关键步骤
  • slice(which.max(order(…)
  • 查找每组诊所代码和合作伙伴代码的最后一个合作伙伴结束日期。使用
    na.last=FALSE
    将NAs置于非na值之前。这样,我们总是可以获得na或最后一个非na合作伙伴结束日期(如果有)

  • mutate(*=if_else(is.na(*)、as.Date(“2020-10-01”)、*)
  • 将NAs视为2020-10-01,因为这是最新日期

  • 扩展(日期=顺序日期(合伙企业开始日期、合伙企业结束日期,按=“月”),…)
  • 将data.frame_2中的每个开始-结束日期对展开为一个完整的序列。展开后,data.frame_2和data.frame_1将具有相同的格式,如下所示

    # A tibble: 39 x 3
    # Groups:   clinic_code, partner_code [4]
       date       clinic_code partner_code
       <date>     <chr>       <chr>       
     1 2019-10-01 A05         00033       
     2 2019-11-01 A05         00033       
     3 2019-12-01 A05         00033       
     4 2020-01-01 A05         00033       
     5 2020-02-01 A05         00033       
     6 2020-03-01 A05         00033       
     7 2020-04-01 A05         00033       
     8 2020-05-01 A05         00033       
     9 2020-06-01 A05         00033       
    10 2020-07-01 A05         00033       
    # ... with 29 more rows
    
    数据帧2

    structure(list(clinic_code = c("A05", "A12", "A12", "A12", "B17"
    ), partner_code = c("00033", "00001", "00001", "00044", "00002"
    ), partnership_start_date = c("2019-10-01", "2019-10-01", "2019-10-01", 
    "2020-01-01", "2019-10-01"), partnership_end_date = c(NA, NA, 
    "2019-12-31", NA, NA)), class = "data.frame", row.names = c(NA, 
    -5L))
    

    您可以尝试使用
    fuzzyjoin
    根据范围进行连接:

    library(dplyr)
    
    df2 %>%
      mutate(partnership_end_date = replace(partnership_end_date, 
                                    is.na(partnership_end_date), Sys.Date())) %>%
      fuzzyjoin::fuzzy_right_join(df1, by = c('clinic_code', 
                   'partnership_start_date' = 'date', 'partnership_end_date' = 'date'), 
                    match_fun = list(`==`, `<=`, `>=`)) %>%
      mutate(partner_code = coalesce(partner_code.y, partner_code.x))
    
    库(dplyr)
    df2%>%
    变更(合伙关系结束日期=替换(合伙关系结束日期,
    is.na(合伙关系结束日期),Sys.date())%>%
    fuzzyjoin::fuzzy_right_join(df1,by=c('clinic_code'),
    “合作关系开始日期”=“日期”,“合作关系结束日期”=“日期”),
    匹配乐趣=列表(`=`,`=`))%>%
    变异(合作伙伴代码=合并(合作伙伴代码.y,合作伙伴代码.x))
    
    您的填写标准是什么?我无法从您的示例中推断出来。例如,为什么在您的预期输出中有这么多行用于临床代码A05,但data.frame_1或data.frame_2仅显示一行?非常感谢ekoam,如果不清楚,很抱歉-我刚刚用标准更新了我的问题。您的具体问题是:每个clinic_代码在我的数据中从2019-10-01到2020-10-01。框_1-请查看更新的数据。框_1Hi,我有一些想法,但需要进一步澄清。框_2中的第2行和第3行显示了诊所_代码和合作伙伴_代码的相同值。为什么选择第3行而不是第2行来填写数据中的A12。框_1?很抱歉没有解释。这是因为data.frame_2加入了2个data.frames(一个从2月份开始,一个从3月份开始),有时我们会看到这样的场景,在2月份(第2行)合作关系仍在进行(NA),但在3月份(第3行)结束。也许我需要用NA删除这些行(如第2行)当同一诊所代码、合作伙伴代码和合作伙伴开始日期以及为合作伙伴结束日期设置的日期出现另一行时。不确定您是否可以想出其他方法来解决此问题。非常感谢@ekoam花时间查看此问题。似乎“跨越”功能仍仅在dp的开发版本中可用lyr,还没有在CRAN上。是否有其他方法来代替使用“Cross”?它找不到“Cross”函数,所以我得到了一个错误。很高兴将您的dplyr包更新到最新的CRAN版本。Cross应该可用。较旧的语法
    mutate_at(vars(以(“date”)结尾),as.date)
    我刚刚完成了install.library(“tidyverse”)&library(tidyverse),然后在顶部安装.library(“dplyr”)&library(dplyr)我假设它正在自动安装最新的CRAN版本?但我一直得到消息说“Cross”不存在。无论如何,使用较旧的语法可以工作,谢谢!我现在将检查输出。这是很棒的ekoam,我已经做了一些检查,一切似乎都按预期工作。谢谢!我意识到那些带有NAs的行用于e在我的数据集上带有partnership_end_date的行之后出现了相同的诊所代码、partnership_代码和partnership_start_date(与我之前的问题相反),并且由于您关于“一些关键步骤”的第一点,为了避免任何问题,我在运行代码之前从data.frame_2中删除了这些行。非常感谢Ronak提出的解决方案。我还必须加载fuzzyjoin包,但随后我收到一个错误,错误是“错误:向量内存已耗尽(达到限制?)“.您的数据有多大?行数与列数?我认为不大。data.frame_1=88761 obs.共12个变量&data.frame_2=6824 obs.共5个变量,谢谢!”!
             date clinic_code partner_code
    1  2019-10-01         A05        00033
    2  2019-11-01         A05        00033
    3  2019-12-01         A05        00033
    4  2020-01-01         A05        00033
    5  2020-02-01         A05        00033
    6  2020-03-01         A05        00033
    7  2020-04-01         A05        00033
    8  2020-05-01         A05        00033
    9  2020-06-01         A05        00033
    10 2020-07-01         A05        00033
    11 2020-08-01         A05        00033
    12 2020-09-01         A05        00033
    13 2020-10-01         A05        00033
    14 2019-10-01         A12        00001
    15 2019-11-01         A12        00001
    16 2019-12-01         A12        00001
    17 2020-01-01         A12        00044
    18 2020-02-01         A12        00044
    19 2020-03-01         A12        00044
    20 2020-04-01         A12        00044
    21 2020-05-01         A12        00044
    22 2020-06-01         A12        00044
    23 2020-07-01         A12        00044
    24 2020-08-01         A12        00044
    25 2020-09-01         A12        00044
    26 2020-10-01         A12        00044
    27 2019-10-01         B17        00002
    28 2019-11-01         B17        00002
    29 2019-12-01         B17        00002
    30 2020-01-01         B17        00002
    31 2020-02-01         B17        00002
    32 2020-03-01         B17        00045
    33 2020-04-01         B17        00045
    34 2020-05-01         B17        00049
    35 2020-06-01         B17        00002
    36 2020-07-01         B17        00002
    37 2020-08-01         B17        00002
    38 2020-09-01         B17        00002
    39 2020-10-01         B17        00049
    
    # A tibble: 39 x 3
    # Groups:   clinic_code, partner_code [4]
       date       clinic_code partner_code
       <date>     <chr>       <chr>       
     1 2019-10-01 A05         00033       
     2 2019-11-01 A05         00033       
     3 2019-12-01 A05         00033       
     4 2020-01-01 A05         00033       
     5 2020-02-01 A05         00033       
     6 2020-03-01 A05         00033       
     7 2020-04-01 A05         00033       
     8 2020-05-01 A05         00033       
     9 2020-06-01 A05         00033       
    10 2020-07-01 A05         00033       
    # ... with 29 more rows
    
    structure(list(date = c("2019-10-01", "2019-11-01", "2019-12-01", 
    "2020-01-01", "2020-02-01", "2020-03-01", "2020-04-01", "2020-05-01", 
    "2020-06-01", "2020-07-01", "2020-08-01", "2020-09-01", "2020-10-01", 
    "2019-10-01", "2019-11-01", "2019-12-01", "2020-01-01", "2020-02-01", 
    "2020-03-01", "2020-04-01", "2020-05-01", "2020-06-01", "2020-07-01", 
    "2020-08-01", "2020-09-01", "2020-10-01", "2019-10-01", "2019-11-01", 
    "2019-12-01", "2020-01-01", "2020-02-01", "2020-03-01", "2020-04-01", 
    "2020-05-01", "2020-06-01", "2020-07-01", "2020-08-01", "2020-09-01", 
    "2020-10-01"), clinic_code = c("A05", "A05", "A05", "A05", "A05", 
    "A05", "A05", "A05", "A05", "A05", "A05", "A05", "A05", "A12", 
    "A12", "A12", "A12", "A12", "A12", "A12", "A12", "A12", "A12", 
    "A12", "A12", "A12", "B17", "B17", "B17", "B17", "B17", "B17", 
    "B17", "B17", "B17", "B17", "B17", "B17", "B17"), partner_code = c(NA, 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "00044", 
    NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, "00045", 
    "00045", "00049", NA, NA, NA, NA, "00049")), row.names = c(NA, 
    39L), class = "data.frame")
    
    structure(list(clinic_code = c("A05", "A12", "A12", "A12", "B17"
    ), partner_code = c("00033", "00001", "00001", "00044", "00002"
    ), partnership_start_date = c("2019-10-01", "2019-10-01", "2019-10-01", 
    "2020-01-01", "2019-10-01"), partnership_end_date = c(NA, NA, 
    "2019-12-31", NA, NA)), class = "data.frame", row.names = c(NA, 
    -5L))
    
    library(dplyr)
    
    df2 %>%
      mutate(partnership_end_date = replace(partnership_end_date, 
                                    is.na(partnership_end_date), Sys.Date())) %>%
      fuzzyjoin::fuzzy_right_join(df1, by = c('clinic_code', 
                   'partnership_start_date' = 'date', 'partnership_end_date' = 'date'), 
                    match_fun = list(`==`, `<=`, `>=`)) %>%
      mutate(partner_code = coalesce(partner_code.y, partner_code.x))