其他任何比r

时间:2018-07-03 07:38:56

标签: r dplyr data-manipulation 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
  • Conf No:唯一标识符

我想创建一个新变量,将标志标记为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

2 个答案:

答案 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,这可能是我们所能做的。