我有数据,其中每5分钟测量一次MV_1,MV_2,MV_3 ...,MV_40变量。现在,我必须每小时汇总一次,并绘制一个time_series图(每个变量应为单独的图-变量随时间的变化)。数据类型如下(仅一小部分-超过1000个时间点)。
date MV_1 MV_2
2017-07-08 01:19:37 212 163
2017-07-08 01:24:41 222 162
2017-07-08 01:29:37 207 162
2017-07-08 01:34:41 189 161
2017-07-08 01:39:37 220 161
2017-07-08 01:44:41 186 16
2017-07-08 01:49:37 193 16
2017-07-08 01:54:40 186 159
2017-07-08 01:59:37 194 159
2017-07-08 02:04:40 193 159
2017-07-08 02:09:37 183 159
2017-07-08 02:14:40 215 158
2017-07-08 02:19:37 213 158
2017-07-08 02:24:40 209 157
第一列包含小时数为POSIXct格式(%Y-%M-%D%h:%m:%S格式)的数据,第二和第三列为数字。
对于这种类型的聚合,一小时的平均测量(通常是平均的),我已经完成了以下操作
aggregate(my_data[MV_1], list(hour=cut(as.POSIXct(my_data$date)-1, "hour")), mean)
然后绘图。这适用于所有列(MV_2,MV_3等)。
但是有没有一种方法可以使它更简单并使过程自动化?
答案 0 :(得分:1)
假设数据帧DF
在结尾处的注释中可重复显示:
DF$date <- as.POSIXct(DF$date)
hour <- as.POSIXct(trunc(DF$date, "hour"))
avg <- aggregate(DF[-1], data.frame(hour), mean)
avg
## hour MV_1 MV_2
## 1 2017-07-08 01:00:00 201.0 128.7778
## 2 2017-07-08 02:00:00 202.6 158.2000
matplot(avg[[1]], avg[-1], type = "l", xaxt = "n")
Axis(DF[[1]], side = 1)
或者要使用时间序列表示形式转换为Zoo,请使用aggregate.zoo并使用经典或ggplot2图形进行绘制,如图所示。这些图在同一图上绘制每个系列的图。如果要单独绘制,则分别省略screen=1
和facet=NULL
。
library(zoo)
z <- read.zoo(DF)
hour <- as.POSIXct(trunc(time(z), "hour"))
zavg <- aggregate(z, hour, mean)
zavg
## MV_1 MV_2
## 2017-07-08 01:00:00 201.0 128.7778
## 2017-07-08 02:00:00 202.6 158.2000
# classic graphics
plot(zavg, screen = 1)
# or ggplot2 graphics
library(ggplot2)
autoplot(zavg, facet = NULL)
Lines <- "date MV_1 MV_2
2017-07-08 01:19:37 212 163
2017-07-08 01:24:41 222 162
2017-07-08 01:29:37 207 162
2017-07-08 01:34:41 189 161
2017-07-08 01:39:37 220 161
2017-07-08 01:44:41 186 16
2017-07-08 01:49:37 193 16
2017-07-08 01:54:40 186 159
2017-07-08 01:59:37 194 159
2017-07-08 02:04:40 193 159
2017-07-08 02:09:37 183 159
2017-07-08 02:14:40 215 158
2017-07-08 02:19:37 213 158
2017-07-08 02:24:40 209 157"
L <- trimws(readLines(textConnection(Lines)))
L <- gsub(" +", ",", L)
L <- sub(",", " ", L)
L[1] <- sub(" ", ",", L[1])
DF <- read.csv(text = L)
答案 1 :(得分:0)
使用tidyverse
和lubridate
:
df %>%
group_by(hour = floor_date(date, unit = "hour")) %>%
summarise_at(vars(contains("MV")), funs(mean(., na.rm = TRUE))) %>%
melt(id = "hour") %>%
ggplot(aes(x = hour, y = value, colour = variable)) +
geom_line() +
facet_grid( ~ variable) +
theme_bw()
或者,如果您决定将所有时间序列都放在一个图中:
df %>%
group_by(hour = floor_date(date, unit = "hour")) %>%
summarise_at(vars(contains("MV")), funs(mean(., na.rm = TRUE))) %>%
melt(id = "hour") %>%
ggplot(aes(x = hour, y = value, colour = variable, group = variable)) + geom_line()