在一天内获取事件总和

时间:2015-03-12 03:39:13

标签: r sum frequency

我有一个如下所示的数据集(15年的数据)半小时间隔数据和事件的发生(1表示它发生,0表示它没有)

Date                    Event
2002-04-27 19:30:00      0
2002-04-27 20:00:00      0
2002-04-27 20:30:00      0
2002-04-27 21:00:00      0
2002-04-27 21:30:00      1
2002-04-27 22:00:00      1
2002-04-27 22:30:00      0
2002-04-27 23:00:00      0
2002-04-27 23:30:00      1
2002-04-28 00:00:00      1
2002-04-28 00:30:00      1
2002-04-28 01:00:00      1
2002-04-28 01:30:00      0
2002-04-28 02:00:00      0
2002-04-28 02:30:00      0
2002-04-28 03:00:00      0
2002-04-28 03:30:00      0
2002-04-28 04:00:00      0
2002-04-28 04:30:00      0
2002-04-28 05:00:00      0
2002-04-28 05:30:00      0
2002-04-28 06:00:00      0
2002-04-28 06:30:00      0
2002-04-28 07:00:00      0

我想要做的是计算每一天(例如2002-04-27)发生的事件的数量。但是,连续的1表示它只是一个事件,而且也是1天越过一天,比如说2002-04-27 21:30:00有1,所以2002-04-28 00:00:00也是2002-04-27仅被认为是Date No_Event 2002-04-27 2 2002-04-28 0 上发生的1个事件。像下面这样的输出是理想的。

{{1}}

那么,我该怎么做呢?非常感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

使用lubridate(按日分组)和data.table

library(data.table)
library(lubridate)
setDT(df)
df[Event!=shift(Event, fill=0), sum(Event), by=floor_date(Date, unit="day")]

#   floor_date V1
#1: 2002-04-27  2
#2: 2002-04-28  0

上面示例中使用的

df

 df <- data.frame(Date=seq(as.POSIXct("2002-04-27 19:30:00 ", tz="GMT"), as.POSIXct("2002-04-28 07:00:00 ", tz="GMT"), by="30 min"),
                     Event=c(0L, 0L, 0L, 0L, 1L, 1L, 0L, 0L, 1L, 1L, 1L, 1L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L))

答案 1 :(得分:3)

以下是一些不同的方法:

1)base 这是一个基本解决方案。首先,我们创建一个逻辑向量,如果当前事件为1且先前事件为0(当diff == 1时发生),则为TRUE,然后我们将其与Date相加:

No_Events <- tapply(diff(c(0, df$Event)) == 1, as.Date(df$Date), sum)

,并提供:

> No_Events
2002-04-27 2002-04-28 
         2          0 

如果输出是数据框很重要,请尝试as.data.frame(No_Events)data.frame(Date = as.Date(names(No_Events)), No_Event = unname(No_Events))

1a)以下是使用aggregate代替tapply的变体,我们首先创建一个包含tr列的数据框Date只有日期和一个No_Event列标记任何1,而不是1.然后我们执行aggregate

tr <- transform(df, No_Event = diff(c(0, df$Event)) == 1, Date = as.Date(Date))
aggregate(No_Event ~ Date, tr, sum)

,并提供:

        Date No_Event
1 2002-04-27        2
2 2002-04-28        0

2)动物园这是一个动物园解决方案。将数据框读入动物园对象,将其与diff == 1列适当填充并aggregate合并:

library(zoo)
z <- read.zoo(df, tz = "")
m <- merge(z, No_Event = diff(z) == 1, fill = coredata(z[1]))
z.ag <- aggregate(m, as.Date(format(time(z))), sum)

,并提供:

> z.ag
           z No_Event
2002-04-27 3        2
2002-04-28 3        0

忽略z列,或通过z.ag[, -1]z.ag[, -1, drop = FALSE]将其删除。

答案 2 :(得分:1)

首先制作“日期”栏目

dat$day <- strftime(x = dat$Date, format = "%D") # try %F as well

找到连续的1并且只保留第一个

for(i in nrow(dat):2) {
  if(dat$Event[i]==1 && dat$Event[i-1]==1)
      dat$Event[i] <- 0
}

然后聚集结果

by(data = dat$Event, INDICES = dat$day, FUN = sum)

dat$day: 04/27/02
[1] 2
-----------------------------------------------------------------
dat$day: 04/28/02
[1] 0