按 R 中等间隔的时间间隔聚合数据
Aggregate data by equally spaced time intervals in R
我的数据集是这样的
Section Time x
s3 9:35 2
s4 9:35 2
s1 9:36 1
s2 10:01 1
s8 11:00 2
所以,我想按小时间隔对数据部分进行明智的分组,并对位于该间隔内的 x 值求和
我的预期输出是
sec Time x
s1 9:00-10:00 1
s2 9:00-10:00 0
s3 9:00-10:00 2
s4 9:00-10:00 2
s8 9:00-10:00 0
s1 10.00-11.00 0
s2 10.00-11.00 1
s3 10.00-11.00 0
s4 10.00-11.00 0
s8 10.00-11.00 1
我试图从这个 post in stack overflow 中获得一些帮助,但是我的这个查询出现了以下错误。这里x是我的框架
data.frame(value = tapply(cbind(x$x),
list(sec= x$section,cut(x$Time, breaks="1 hour")),
sum))
Error in cut.default(x$Time, breaks = "1 hour") : 'x' must be numeric
我什至不确定这是对还是错。我从来没有在 R 中处理过时间数据。所以任何关于如何实现它的帮助都会很有帮助。
我认为问题在于您的 Time
列是字符格式 ?
无论如何,这里有一个使用 dplyr 的快速而肮脏的方法:
library(dplyr)
x <- data.frame(section = c("s3", "s4", "s1", "s2", "s8", "s1", "s2", "s3"),
Time = c("9:35", "9:35", "9:36", "10:01", "11:00", "9:45", "10:05", "10:05"),
x = c(2, 2, 1, 1, 2, 6, 2, 4), stringsAsFactors = FALSE)
x %>%
rowwise %>%
mutate(aux = as.numeric(strsplit(Time, ":")[[1]][1]),
time = paste0(aux, ":00-", aux+1, ":00")) %>%
select(-aux, -Time) %>%
ungroup %>%
group_by(time, section) %>%
summarise(x = sum(x)) %>%
ungroup
这是一个替代版本:
m1 <- as.data.frame(matrix(c("s3","9:35",2,"s4","9:35",2,"s1","9:36",1,"s2","10:01",1,"s8","11:00",2),byrow=T,ncol=3))
colnames(m1) <- c("Section", "Time","x")
times <- as.character(m1$Time)
hours <- sapply(sapply(times,function(x)strsplit(x,":")),function(x)x[1])
small_hours <- hours[which(as.numeric(hours)<10)]
small_hours <- sapply(small_hours,function(x) paste0("0",x))
hours[which(as.numeric(hours)<10)]<-small_hours
hour_range <- sapply(hours,function(x) paste0(x,":00-",as.character(as.numeric(x)+1),":00"))
m1$Time <- hour_range
m1$x <- as.numeric(m1$x)
require (plyr)
m1 <- ddply(m1, .(Time,Section), summarise, x = sum(x))
m1 <- m1[,c("Section","Time","x")]
这给出了以下数据框:
> m1
Section Time x
1 s1 09:00-10:00 1
2 s3 09:00-10:00 2
3 s4 09:00-10:00 2
4 s2 10:00-11:00 1
5 s8 11:00-12:00 2
这里的技巧是,就像@Tutuchan 的建议一样,忽略时间实际上是 POSIXct 对象中的时间,而是将它们简单地视为字符字符串。希望对您有所帮助。
更新/编辑
正如我之前在评论中提到的,我以前的代码版本没有执行落入同一时间范围内的相等部分的请求的 x 总和。这在上面发布的更新版本中得到了纠正,但我决定放弃尝试在 base R 中完成所有这些工作。
最终,我使用了 plyr
包。
另一个选项是使用 class POSIXct
,然后在应用于日期时间对象的函数 cut
中,在参数 breaks
中指定 "hour" .见 ?cut.POSIXt
:
library(dplyr)
df <- data.frame(section= c("s3", "s4", "s1", "s2", "s8"),
time = strptime(c("09:35", "09:35", "09:36", "10:01", "11:00"), "%H:%M"),
x = c(2, 2, 1, 1, 2))
df2 <- df %>%
group_by(intervals = cut(time, breaks = "hour")) %>%
select(section, intervals, x)
df2$intervals <- format(as.POSIXct(df2$intervals, "%H:%M"), "%H:%M")
输出:
>df2
Source: local data frame [5 x 3]
Groups: intervals
section intervals x
1 s3 09:00 2
2 s4 09:00 2
3 s1 09:00 1
4 s2 10:00 1
5 s8 11:00 2
我的数据集是这样的
Section Time x
s3 9:35 2
s4 9:35 2
s1 9:36 1
s2 10:01 1
s8 11:00 2
所以,我想按小时间隔对数据部分进行明智的分组,并对位于该间隔内的 x 值求和
我的预期输出是
sec Time x
s1 9:00-10:00 1
s2 9:00-10:00 0
s3 9:00-10:00 2
s4 9:00-10:00 2
s8 9:00-10:00 0
s1 10.00-11.00 0
s2 10.00-11.00 1
s3 10.00-11.00 0
s4 10.00-11.00 0
s8 10.00-11.00 1
我试图从这个 post in stack overflow 中获得一些帮助,但是我的这个查询出现了以下错误。这里x是我的框架
data.frame(value = tapply(cbind(x$x),
list(sec= x$section,cut(x$Time, breaks="1 hour")),
sum))
Error in cut.default(x$Time, breaks = "1 hour") : 'x' must be numeric
我什至不确定这是对还是错。我从来没有在 R 中处理过时间数据。所以任何关于如何实现它的帮助都会很有帮助。
我认为问题在于您的 Time
列是字符格式 ?
无论如何,这里有一个使用 dplyr 的快速而肮脏的方法:
library(dplyr)
x <- data.frame(section = c("s3", "s4", "s1", "s2", "s8", "s1", "s2", "s3"),
Time = c("9:35", "9:35", "9:36", "10:01", "11:00", "9:45", "10:05", "10:05"),
x = c(2, 2, 1, 1, 2, 6, 2, 4), stringsAsFactors = FALSE)
x %>%
rowwise %>%
mutate(aux = as.numeric(strsplit(Time, ":")[[1]][1]),
time = paste0(aux, ":00-", aux+1, ":00")) %>%
select(-aux, -Time) %>%
ungroup %>%
group_by(time, section) %>%
summarise(x = sum(x)) %>%
ungroup
这是一个替代版本:
m1 <- as.data.frame(matrix(c("s3","9:35",2,"s4","9:35",2,"s1","9:36",1,"s2","10:01",1,"s8","11:00",2),byrow=T,ncol=3))
colnames(m1) <- c("Section", "Time","x")
times <- as.character(m1$Time)
hours <- sapply(sapply(times,function(x)strsplit(x,":")),function(x)x[1])
small_hours <- hours[which(as.numeric(hours)<10)]
small_hours <- sapply(small_hours,function(x) paste0("0",x))
hours[which(as.numeric(hours)<10)]<-small_hours
hour_range <- sapply(hours,function(x) paste0(x,":00-",as.character(as.numeric(x)+1),":00"))
m1$Time <- hour_range
m1$x <- as.numeric(m1$x)
require (plyr)
m1 <- ddply(m1, .(Time,Section), summarise, x = sum(x))
m1 <- m1[,c("Section","Time","x")]
这给出了以下数据框:
> m1
Section Time x
1 s1 09:00-10:00 1
2 s3 09:00-10:00 2
3 s4 09:00-10:00 2
4 s2 10:00-11:00 1
5 s8 11:00-12:00 2
这里的技巧是,就像@Tutuchan 的建议一样,忽略时间实际上是 POSIXct 对象中的时间,而是将它们简单地视为字符字符串。希望对您有所帮助。
更新/编辑
正如我之前在评论中提到的,我以前的代码版本没有执行落入同一时间范围内的相等部分的请求的 x 总和。这在上面发布的更新版本中得到了纠正,但我决定放弃尝试在 base R 中完成所有这些工作。
最终,我使用了 plyr
包。
另一个选项是使用 class POSIXct
,然后在应用于日期时间对象的函数 cut
中,在参数 breaks
中指定 "hour" .见 ?cut.POSIXt
:
library(dplyr)
df <- data.frame(section= c("s3", "s4", "s1", "s2", "s8"),
time = strptime(c("09:35", "09:35", "09:36", "10:01", "11:00"), "%H:%M"),
x = c(2, 2, 1, 1, 2))
df2 <- df %>%
group_by(intervals = cut(time, breaks = "hour")) %>%
select(section, intervals, x)
df2$intervals <- format(as.POSIXct(df2$intervals, "%H:%M"), "%H:%M")
输出:
>df2
Source: local data frame [5 x 3]
Groups: intervals
section intervals x
1 s3 09:00 2
2 s4 09:00 2
3 s1 09:00 1
4 s2 10:00 1
5 s8 11:00 2