按连续值和组聚合

时间:2016-02-09 21:47:41

标签: r sequence

在以下数据集中,我已经按自行车计数等于零的情况过滤了JSON间隔。 station_summary_id代表一个时间间隔并按连续整数增加(在示例中,您看到64129与" 2014-10-01 07:00:00"相关联,然后64130与&#相关联34; 2014-10-01 07:10:00"等等。station_id是电台的唯一ID。

我的目标是:通过station_id找到最长的连续整数链 - 换句话说 - 找出每个站空的最长时间段。我知道这需要先按station_id进行分组,然后计算station_summary_id中最长的连续序列,但不确定如何为所有站点ID自动执行此操作。

> dim(data)
[1] 307039      7


> head(data)
      station_id status available_bike_count          created_at station_summary_id month year
13694          2 Active                    0 2014-10-01 07:00:00              64129    10 2014
13702         10 Active                    0 2014-10-01 07:00:00              64129    10 2014
13706         14 Active                    0 2014-10-01 07:00:00              64129    10 2014
13710         18 Active                    0 2014-10-01 07:00:00              64129    10 2014
13713         21 Active                    0 2014-10-01 07:00:00              64129    10 2014
13728         36 Active                    0 2014-10-01 07:00:00              64129    10 2014

可重复的例子:

> dput(dat)
structure(list(station_id = c(2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 
2L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 4L), status = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L), .Label = "Active", class = "factor"), available_bike_count = c(0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 
0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L), station_summary_id = c(64129L, 
64130L, 64131L, 64132L, 64133L, 64134L, 64136L, 64138L, 64139L, 
64140L, 64141L, 64142L, 64143L, 64144L, 64145L, 64146L, 64147L, 
64148L, 64149L, 64150L, 64152L, 64161L, 64162L, 64170L, 64273L, 
64322L, 64324L, 64341L, 64884L, 64886L, 64896L, 64897L, 64898L, 
64899L, 64900L, 64901L, 64902L, 64903L, 64904L, 64905L, 64906L, 
64907L, 64908L, 64909L, 64910L, 64911L, 64912L, 64913L, 64917L, 
64918L, 65214L, 65219L, 66314L, 66439L, 66450L, 66583L, 66587L, 
66589L, 66600L, 66872L, 66880L, 67037L, 67048L, 82854L, 82855L, 
82856L, 82857L, 82858L, 82859L, 82860L, 82861L, 82862L, 82863L, 
82867L, 82868L), month = c(10L, 10L, 10L, 10L, 10L, 10L, 10L, 
10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 
10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 
10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 
10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 
10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 
10L, 10L, 10L), year = c(2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 
2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 
2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 
2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 
2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 
2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 
2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 2014L, 
2014L, 2014L, 2014L, 2015L, 2015L, 2015L, 2015L, 2015L, 2015L, 
2015L, 2015L, 2015L, 2015L, 2015L, 2015L)), .Names = c("station_id", 
"status", "available_bike_count", "station_summary_id", "month", 
"year"), row.names = c(NA, -75L), class = "data.frame")

2 个答案:

答案 0 :(得分:2)

有关运行长度编码的可能用途,请参阅?rle

使用您的新数据:

> max( rle( diff(dat$station_summary_id) )$lengths )
[1] 12

在修订后的示例中有多个station_id,我发现aggregate工作得相当好:

 aggregate( dat$station_summary_id, dat['station_id'], FUN= function(d) max( rle( diff(d) )$lengths ) )
#---------
  station_id  x
1          2 12
2          3 17
3          4  9

这也成功使用了data.table语法:

dat <- setDT(dat)
dat[,   max( rle( diff(station_summary_id) )$lengths ) , by='station_id']
#-----
   station_id V1
1:          2 12
2:          3 17
3:          4  9

答案 1 :(得分:1)

您可以使用dplyrdata.tablebase R按电台ID查找最长持续时间。请参阅@ 42在电话中心提及的函数rle

#dplyr
library(dplyr)
data %>% group_by(station_id) %>% 
  summarise(with(rle(station_summary_id), values[which.max(lengths)]))

#data.table
library(data.table)
setDT(data)[,list(with(rle(station_summary_id),
               values[which.max(lengths)])),by=station_id]

#base R
lapply(split(data$station_summary_id, data$station_id), 
       function(x) with(rle(x), values[which.max(lengths)]))

修改

使用新数据:

dt[,with(rle(diff(station_summary_id) > 1), max(lengths[!values])), by=station_id]