使用sparklyr按时间戳+ ID查找缺少的行

时间:2018-04-21 11:30:39

标签: r apache-spark dplyr sparklyr

我试图找到丢失的时间戳。以下是解决这个问题的很多解决方案。不过我也想找到"其中"缺少时间戳ID。

例如,测试数据集看起来像这样:

elemuid timestamp
1232    2018-02-10 23:00:00
1232    2018-02-10 23:01:00
1232    2018-02-10 22:58:00
1674    2018-02-10 22:40:00
1674    2018-02-10 22:39:00
1674    2018-02-10 22:37:00
1674    2018-02-10 22:35:00

解决方案应该是:

elemuid timestamp
1232    2018-02-10 22:59:00
1674    2018-02-10 22:38:00
1674    2018-02-10 22:36:00

我的问题是我只能使用dplyr,因为我也想在sparklyr中使用此代码。 我真的很高兴你的帮助!

2 个答案:

答案 0 :(得分:2)

以下是anti_join的一个选项。假设'时间戳' column不是Datetime对象,我们将其转换为POSIXct

library(tidyverse)
df1 <- df1 %>%
          mutate(timestamp = ymd_hms(timestamp)) 

按照&#39; elemuid&#39;进行分组,使用complete扩展“时间戳”&#39; 1分钟后,使用原始数据集

进行anti_join
df1 %>%
    group_by(elemuid) %>% 
    complete(timestamp = seq(min(timestamp), max(timestamp), by = "1 min")) %>% 
    anti_join(df1)
# A tibble: 3 x 2
# Groups: elemuid [?]
#   elemuid timestamp          
#     <int> <dttm>             
#1    1232 2018-02-10 22:59:00
#2    1674 2018-02-10 22:36:00
#3    1674 2018-02-10 22:38:00

答案 1 :(得分:1)

为简单起见,我们假设您已经跟随instructions from your previous question,并在几秒钟内计算出minimum and maximummin_maxEpoch time

其余步骤与我们之前遵循的步骤非常相似:

  • 生成值范围:

    epoch_range <- spark_session(sc) %>% 
      invoke("range", as.integer(min_max[1]), as.integer(min_max[2]), 60L) %>%
      invoke("withColumnRenamed", "id", "timestamp")
    
  • 计算不同的elemuid

    elemuids <- df %>% select(elemuid) %>% distinct() %>% spark_dataframe()
    

现在,我们要生成一个参考表作为范围和唯一ID的笛卡尔积:

ref <- epoch_range %>% 
  invoke("crossJoin", elemuids) %>% 
  sdf_register() %>%
  mutate(timestamp = from_unixtime(timestamp, "yyyy-MM-dd HH:mm:ss.SSS"))

您可能想要使用更多dplyr - ish方法:

sdf_register(epoch_range) %>% mutate(dummy = 1) %>% 
  left_join(sdf_register(elemuids) %>% mutate(dummy = 1), by = "dummy") %>%
  select(-dummy)

如果产品的尺寸很小(在这种情况下Spark应该使用广播连接),这将工作正常,但是会导致完整的数据偏斜,否则一般情况下使用是不安全的。

最后我们像以前一样使用外连接数据:

ref %>% left_join(df, by = c("timestamp", "elemuid"))

填写内容,或(由already explained in the answer提供的akrun)反联接以删除缺失的内容:

ref %>% anti_join(df, by = c("timestamp", "elemuid"))