相当于tidyr :: data的data.table,具有group_by [英] data.table equivalent of tidyr::complete with group_by

查看:66
本文介绍了相当于tidyr :: data的data.table,具有group_by的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下数据框:

library(tidyverse)
df <- data_frame(
  id = c(1, 1, 2, 2), 
  date1 = as.Date(c("2013-01-01", "2013-02-01", "2015-04-01", "2015-05-01")), 
  date2 = as.Date(c("2012-12-09", "2012-12-09", "2015-03-10", "2015-03-10"))
)

# A tibble: 4 x 3
     id      date1      date2
  <dbl>     <date>     <date>
1     1 2013-01-01 2012-12-09
2     1 2013-02-01 2012-12-09
3     2 2015-04-01 2015-03-10
4     2 2015-05-01 2015-03-10

我想完成此数据这样,对于每个 id ,都会有另一个 date1 值。此另一个 date1 值将作为下个月计算。还有一个 date2 值,该值对于所有 id 都是相同的。使用 tidyr :: complete 可以执行以下操作:

And I want to complete this data frame such that for each id, there will be another date1 value. This another date1 value is computed as the next month. Also there is a date2 value which is same for all id's. With tidyr::complete this action can be done like this:

df %>% 
  group_by(id) %>% 
  complete(date1 = seq.Date(from = min(date1), length.out = 3, by = "month"), date2 = date2[1])

# A tibble: 6 x 3
# Groups:   id [2]
     id      date1      date2
  <dbl>     <date>     <date>
1     1 2013-01-01 2012-12-09
2     1 2013-02-01 2012-12-09
3     1 2013-03-01 2012-12-09
4     2 2015-04-01 2015-03-10
5     2 2015-05-01 2015-03-10
6     2 2015-06-01 2015-03-10

由于我的原始数据中有大约15万个组,因此 tidyr 解决方案需要一个多小时才能完成。我假设使用 data.table 可以提高速度。可以在 data.table 中完成同样的事情吗?

Since I have about 150K groups in my original data, the tidyr solution is taking more than hour to complete. I am assuming that speed would be gained using data.table. Can the same thing be done in data.table?

数据中也提出了类似的问题.table等同于tidyr :: complete(),但没有 group_by 子句。

推荐答案

基于一些初始基准测试, data.table 方法似乎更快

Based on some initial benchmarking the data.table approach seems to be faster

library(data.table)
setDT(df)[, .(date1 = seq(min(date1), length.out = 3, by = 'month'), date2 = date2[1]), id]



基准



Benchmarks

 df <- data_frame(
  id = rep(1:3000, each = 2), 
  date1 = rep(as.Date(c("2013-01-01", "2013-02-01", "2015-04-01", "2015-05-01")),
  length.out = 6000), 
  date2 = rep(as.Date(c("2012-12-09", "2012-12-09", "2015-03-10", "2015-03-10")), 
   length.out = 6000))

system.time({
df %>% 
  group_by(id) %>% 
  complete(date1 = seq.Date(from = min(date1), 
          length.out = 3, by = "month"), date2 = date2[1])
})
#user  system elapsed 
#64.05   21.27   86.05 

system.time({
setDT(df)[, .(date1 = seq(min(date1), length.out = 3, by = 'month'), date2 = date2[1]), id]
})
#user  system elapsed 
#  0.14    0.00    0.14 

这篇关于相当于tidyr :: data的data.table,具有group_by的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆