将每小时的年度数据融化以按月创建每日平均值,然后进行比较

时间:2017-07-13 05:45:39

标签: r time ggplot2 dplyr melt

我有一个多阶段的问题,我一直试图使用现有的线程解决,但我还没有完全有效,所以我想在这里提出它。我正在从excel过渡到R,因为我尝试使用的数据量很大。我在R中有一些背景,但下面的大部分内容是从各种堆栈帖子中拼凑出来的,所以如果有不同的方法来解决这个问题,我很满意。

我的原始数据连续多年有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循环来创建平均天数的向量,但无济于事。

对于这篇长篇文章感到抱歉,我非常感谢您对我迄今采取的方法以及我应该如何进行的见解。

1 个答案:

答案 0 :(得分:1)

我不会在您的代码中发现任何严重错误,因此只需清除它即可。

例如,您可以使用tidyr&#39; gather代替旧版melt,我会dplyr::mutate使用lubridate &#39; 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必须映射到两个变量,而且&# 39;为什么我们使用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以符合示例,并且因为数据是随机噪声,会产生丑陋的图形)