我有2个数据框
df1具有700,000个数据点
样本数据:
ID1 ExtractDate1 MktSeg1 ConfirmationNo
145 3/7/2017 2 29083253
145 3/7/2017 1 29085100
145 3/7/2017 1 29085102
145 3/7/2017 1 29085106
145 3/7/2017 1 29084895
145 3/7/2017 1 29084953
df2具有100,000个数据点
我想创建一个新变量,将标志标记为df1,当df1和df2中的确认编号出现时标记为1,否则为0
我通过使用以下方法实现了这一目标:
combi1 <- sqldf("SELECT Distinct ID1,
ExtractDate1,
MktSeg1,
ConfirmationNo,
CASE
WHEN confno IS NOT NULL
THEN 1
ELSE 0
END AS 'Flag'
FROM df1
LEFT JOIN df2 ON ID1 = ID2
AND ExtractDate2 >= ExtractDate1
AND ConfirmationNo = confno", drv = "SQLite")
得出结果需要20到30分钟以上,有没有更好的方法?
我已经尝试过了
combi3 <- left_join(tbl_df(df1),tbl_df(df2),
by = c("ID1" = "ID2" , "ExtractDate1" <= "ExtractDate2", "ConfirmationNo" = "ConfNo")) %>%
select(distinct(ID1, ExtractDate1, MktSeg1, ConfirmationNo))
它抛出以下错误:
`by` can't contain join column `TRUE` which is missing from LHS
答案 0 :(得分:3)
使用您提供的数据以及与之相似的第二个数据帧,可以使用%in%
运算符:
df1 <- read.table(text = "ID1 ExtractDate1 MktSeg1 ConfirmationNo
145 3/7/2017 2 29083253
145 3/7/2017 1 29085100
145 3/7/2017 1 29085102
145 3/7/2017 1 29085106
145 3/7/2017 1 29084895
145 3/7/2017 1 29084953", header = TRUE)
df2 <- read.table(text = "ID1 ExtractDate1 MktSeg1 ConfirmationNo
145 3/7/2017 2 29083253
145 3/7/2017 1 29085106
145 3/7/2017 1 29084895
145 3/7/2017 1 29084953
145 3/7/2017 1 29084899
145 3/7/2017 1 29084959", header = TRUE)
df1$conf_flag <- as.numeric(df1$ConfirmationNo %in% df2$ConfirmationNo)
df1
答案 1 :(得分:3)
如果您想坚持使用sqldf
(这可能不是最快的选择),则可以尝试重写查询以使用EXISTS
:
combi1 <- sqldf("SELECT ID1,
ExtractDate1,
MktSeg1,
ConfirmationNo,
CASE WHERE EXISTS (SELECT 1 FROM df2
WHERE ID1 = ID2
AND ExtractDate2 >= ExtractDate1
AND ConfirmationNo = confno)
THEN 1
ELSE 0
END AS Flag
FROM df1", drv = "SQLite")
切换到EXISTS
意味着我们不再需要使用DISTINCT
。它还可以让我们取消左连接,因为逻辑可以在第一个匹配之后停止扫描。
请注意,我们可以对实际数据库进行更多调整。对于sqldf
,这可能是我们所能做的。