我有一个如下所示的数据集(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}}
那么,我该怎么做呢?非常感谢任何帮助。
答案 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