我有时间戳数据。有时,很少,由于时间戳的分辨率(例如,到最接近的毫秒),我在单个时间戳获得多个更新。我希望按时间戳分组,聚合数据,然后返回每个组中的最后一行。
我发现在dplyr
中要做的显而易见的事情需要很长时间,特别是与data.table
相比。虽然这可能部分是由于当组数超过100K时速度data.table
多快(参见基准部分here),但我很想知道是否有办法更快地完成此操作在dplyr
(或甚至在data.table
中),通过利用具有多行的组非常稀疏这一事实。
示例数据(1000万行,只有1000组,数据行超过1行):
tmp_df <- data.frame(grp = seq_len(1e7))
set.seed(0)
tmp_df_dup <-
tmp_df %>%
sample_frac(1e-4)
tmp_df_dup <-
tmp_df_dup[rep(seq_len(nrow(tmp_df_dup)), 3), ,drop = F] %>%
arrange(grp) %>%
group_by(grp) %>%
mutate(change = seq(3)) %>%
ungroup
tmp_df <-
tmp_df %>%
left_join(tmp_df_dup, by = 'grp')
以下操作需要7分钟在我的机器上:
time_now <- Sys.time()
tmp_result <-
tmp_df %>%
group_by(grp) %>%
mutate(change = cumsum(change)) %>%
filter(row_number() == n()) %>%
ungroup
print(Sys.time() - time_now)
# Time difference of 7.340796 mins
相比之下,data.table
只需不到10秒:
time_now <- Sys.time()
setDT(tmp_df)
tmp_result_dt <-
tmp_df[, .(change = cumsum(change)), by = grp]
tmp_result_dt <-
tmp_result_dt[tmp_result_dt[, .I[.N], by = grp]$V1]
print(Sys.time() - time_now)
# Time difference of 9.033687 secs