融化每年每小时的数据以按月创建每日平均值,然后绘制以进行比较
Melt yearly hourly data to create daily averages by month then plot for comparison
我有一个多阶段的问题,我一直在尝试使用现有的线程来解决,但我还没有完全有效,所以我想在这里提出。由于我要处理的数据量很大,我正在从 excel 过渡到 R。我有一些 R 方面的背景知识,但下面的大部分内容都是从各种堆栈 post 中拼凑而成的,所以如果有不同的方法来解决这个问题,我会洗耳恭听。
我的原始数据连续多年出现在 25 列(日期和一天中的 24 个单独的小时),如下例所示:
date_seq <- seq(as.POSIXct("2012-01-01"),
as.POSIXct("2015-02-01"),
by=("hour"))
df <- data.frame(Date = strftime(date_seq, format="%Y-%m-%d"),
replicate(24,sample(1:9,27049,rep=TRUE)))
headers<-c("Date", "1:00 AM", "2:00 AM","3:00 AM", "4:00 AM","5:00 AM", "6:00 AM","7:00 AM", "8:00 AM","9:00 AM", "10:00 AM","11:00 AM", "12:00 PM","1:00 PM", "2:00 PM","3:00 PM", "4:00 PM","5:00 PM", "6:00 PM","7:00 PM", "8:00 PM","9:00 PM", "10:00 PM","11:00 PM", "12:00 AM")
colnames(df)<-headers
最终目标:按月计算平均小时值,为每个月创建一个“平均天数”,这样我最终就可以逐月、逐季、逐年比较“平均天数”。例如,对于完成的数据,我可以做如下图所示的事情(只是最终数据的一个例子,尽管我需要用它做一些其他的计算)。
Chart to demonstrate final data form
To that end here is what I have done so far and the associated problems:
library(readr)
library(lubridate)
library(tidyr)
library(dplyr)
library(plyr)
library(ggplot2)
library(reshape2)
library(chron)
df2<-melt(df,variable.name="Time",value.name = "Load",id.vars = c("Date"))
times<- as.POSIXct(df2$Time, format = "%I:%M %p", tz = "GMT")
df2$Time<-times(strftime(times, format = "%H:%M:%S", tz = "GMT"))
df3<-as.data.frame(df2)
df3<-separate(data = df3, col = Date, into = c("Year", "Month","Day"), sep = "\-",remove=FALSE)
在这一点上似乎不错,但现在试图创造那些平均日子是我陷入困境的地方。当我 运行 下面的代码时,它会按月创建小时平均值。不幸的是,这也使日期和日期列变成了 NA,这对于最终比较和后续计算来说并不是什么大问题,但显然我没有做对。我试图减去列,但最终出现错误。
df_month<- df3 %>%
group_by(Month, Year, Time) %>%
summarise_each(funs(mean(.,na.rm=TRUE)))
在此之后,我真的很难从这种长格式中恢复平均天数。本质上,我需要取 2012 年 1 月的平均小时数 1,然后将其与其他小时数的平均值再次组合,并重复所有月份。
我试着回到原始数据的宽格式,但在 ggplot2 中绘制线图时出现了问题,即使我可以在 excel 中绘制这些线的宽格式。我也试过搞乱一些 for 循环来创建平均天数的向量,但无济于事。
抱歉这么久了 post 我非常感谢您对我目前采取的方法以及我应该如何进行的见解。
我在您的代码中没有发现任何严重错误,所以只需清理一下即可。
例如,您可以使用 tidyr
的 gather
而不是旧的 melt
,我会使用 dplyr::mutate
和 lubridate
的 year()
、month()
和 hour()
而不是 separate
,最后是 summarize_at
,而不是 summarize_each
(现已弃用并创建 NA
s).
library(dplyr)
library(tidyr)
library(lubridate)
df_month <- df %>%
gather(hours, Load, -Date) %>%
mutate(year = year(Date),
month = month(Date, label = TRUE),
hour = hour(as.POSIXct(hours, format = '%I:%M %p'))) %>%
group_by(year, month, hour) %>%
summarise_at(vars(Load), mean, na.rm = TRUE)
从这个 data.frame
创建一个 ggplot 很容易,唯一需要注意的是 color
aes
必须映射到两个变量,并且这就是为什么我们使用 interaction
:
library(ggplot2)
ggplot(df_month) +
geom_line(aes(hour, Load, color = interaction(month, year, sep = '-'))) +
scale_y_continuous(limits = c(2, NA)) +
scale_colour_discrete('')
(数据已在图中 filter
编辑以匹配示例,还因为数据是随机噪声,导致图表难看)
我有一个多阶段的问题,我一直在尝试使用现有的线程来解决,但我还没有完全有效,所以我想在这里提出。由于我要处理的数据量很大,我正在从 excel 过渡到 R。我有一些 R 方面的背景知识,但下面的大部分内容都是从各种堆栈 post 中拼凑而成的,所以如果有不同的方法来解决这个问题,我会洗耳恭听。
我的原始数据连续多年出现在 25 列(日期和一天中的 24 个单独的小时),如下例所示:
date_seq <- seq(as.POSIXct("2012-01-01"),
as.POSIXct("2015-02-01"),
by=("hour"))
df <- data.frame(Date = strftime(date_seq, format="%Y-%m-%d"),
replicate(24,sample(1:9,27049,rep=TRUE)))
headers<-c("Date", "1:00 AM", "2:00 AM","3:00 AM", "4:00 AM","5:00 AM", "6:00 AM","7:00 AM", "8:00 AM","9:00 AM", "10:00 AM","11:00 AM", "12:00 PM","1:00 PM", "2:00 PM","3:00 PM", "4:00 PM","5:00 PM", "6:00 PM","7:00 PM", "8:00 PM","9:00 PM", "10:00 PM","11:00 PM", "12:00 AM")
colnames(df)<-headers
最终目标:按月计算平均小时值,为每个月创建一个“平均天数”,这样我最终就可以逐月、逐季、逐年比较“平均天数”。例如,对于完成的数据,我可以做如下图所示的事情(只是最终数据的一个例子,尽管我需要用它做一些其他的计算)。
Chart to demonstrate final data form
To that end here is what I have done so far and the associated problems:
library(readr)
library(lubridate)
library(tidyr)
library(dplyr)
library(plyr)
library(ggplot2)
library(reshape2)
library(chron)
df2<-melt(df,variable.name="Time",value.name = "Load",id.vars = c("Date"))
times<- as.POSIXct(df2$Time, format = "%I:%M %p", tz = "GMT")
df2$Time<-times(strftime(times, format = "%H:%M:%S", tz = "GMT"))
df3<-as.data.frame(df2)
df3<-separate(data = df3, col = Date, into = c("Year", "Month","Day"), sep = "\-",remove=FALSE)
在这一点上似乎不错,但现在试图创造那些平均日子是我陷入困境的地方。当我 运行 下面的代码时,它会按月创建小时平均值。不幸的是,这也使日期和日期列变成了 NA,这对于最终比较和后续计算来说并不是什么大问题,但显然我没有做对。我试图减去列,但最终出现错误。
df_month<- df3 %>%
group_by(Month, Year, Time) %>%
summarise_each(funs(mean(.,na.rm=TRUE)))
在此之后,我真的很难从这种长格式中恢复平均天数。本质上,我需要取 2012 年 1 月的平均小时数 1,然后将其与其他小时数的平均值再次组合,并重复所有月份。
我试着回到原始数据的宽格式,但在 ggplot2 中绘制线图时出现了问题,即使我可以在 excel 中绘制这些线的宽格式。我也试过搞乱一些 for 循环来创建平均天数的向量,但无济于事。
抱歉这么久了 post 我非常感谢您对我目前采取的方法以及我应该如何进行的见解。
我在您的代码中没有发现任何严重错误,所以只需清理一下即可。
例如,您可以使用 tidyr
的 gather
而不是旧的 melt
,我会使用 dplyr::mutate
和 lubridate
的 year()
、month()
和 hour()
而不是 separate
,最后是 summarize_at
,而不是 summarize_each
(现已弃用并创建 NA
s).
library(dplyr)
library(tidyr)
library(lubridate)
df_month <- df %>%
gather(hours, Load, -Date) %>%
mutate(year = year(Date),
month = month(Date, label = TRUE),
hour = hour(as.POSIXct(hours, format = '%I:%M %p'))) %>%
group_by(year, month, hour) %>%
summarise_at(vars(Load), mean, na.rm = TRUE)
从这个 data.frame
创建一个 ggplot 很容易,唯一需要注意的是 color
aes
必须映射到两个变量,并且这就是为什么我们使用 interaction
:
library(ggplot2)
ggplot(df_month) +
geom_line(aes(hour, Load, color = interaction(month, year, sep = '-'))) +
scale_y_continuous(limits = c(2, NA)) +
scale_colour_discrete('')
(数据已在图中 filter
编辑以匹配示例,还因为数据是随机噪声,导致图表难看)