根据R中的规则连接data.frames
我有以下data.frame(data.frame_1),从2019-10-01到2020-10-01,每个根据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
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个可能的场景:
partner_code
的任何信息,我使用的是从partnership_start_date
(2019-10-01)到partnership_end_date
的data.frame_2的信息(如果不适用,则表示未结束)合作伙伴代码
,但之前没有任何信息,因此我使用了从合作伙伴关系开始日期
(2019-10-01)到合作伙伴关系结束日期
(2019-12-31)的data.frame_2中的信息合作伙伴代码的信息,但之前没有任何信息,因此我使用了从合作伙伴开始日期(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”)、*)
扩展(日期=顺序日期(合伙企业开始日期、合伙企业结束日期,按=“月”),…)
# 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))