r 中比 sqldf 更快的任何其他进程
Any other process faster than sqldf in r
我有 2 个数据框
df1 有 700,000 个数据点
- ID1:分类变量有 400 多个类别
- 日期 1:1 年数据
- MST1: 2级变量1/2
- 确认号:唯一标识符
示例数据:
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 个数据点
- ID2:分类变量有 400 多个类别
- 日期 2:1 年数据
- MST2:2级变量1/2
- 会议号:唯一标识符
我想创建一个新变量,标记为 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
将您提供的数据和类似的数据用于第二个数据框,您可以使用 %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
如果您想坚持使用 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
,这可能是我们所能做的。
我有 2 个数据框
df1 有 700,000 个数据点
- ID1:分类变量有 400 多个类别
- 日期 1:1 年数据
- MST1: 2级变量1/2
- 确认号:唯一标识符
示例数据:
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 个数据点
- ID2:分类变量有 400 多个类别
- 日期 2:1 年数据
- MST2:2级变量1/2
- 会议号:唯一标识符
我想创建一个新变量,标记为 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
将您提供的数据和类似的数据用于第二个数据框,您可以使用 %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
如果您想坚持使用 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
,这可能是我们所能做的。