繁体   English   中英

汇总,重组R中的每小时时间序列数据

[英]Aggregating, restructuring hourly time series data in R

我在R的数据框中有一年的每小时数据价值:

> str(df.MHwind_load)   # compactly displays structure of data frame
'data.frame':   8760 obs. of  6 variables:
 $ Date         : Factor w/ 365 levels "2010-04-01","2010-04-02",..: 1 1 1 1 1 1 1 1 1 1 ...
 $ Time..HRs.   : int  1 2 3 4 5 6 7 8 9 10 ...
 $ Hour.of.Year : int  1 2 3 4 5 6 7 8 9 10 ...
 $ Wind.MW      : int  375 492 483 476 486 512 421 396 456 453 ...
 $ MSEDCL.Demand: int  13293 13140 12806 12891 13113 13802 14186 14104 14117 14462 ...
 $ Net.Load     : int  12918 12648 12323 12415 12627 13290 13765 13708 13661 14009 ...

在保留小时结构的同时,我想知道如何提取

  1. 特定月份/一组月份
  2. 每个月的第一天/第一周等
  3. 一年中的所有星期一,星期二等

我尝试使用“切割”但没有结果,并且在网上浏览后认为“润滑”可能可以,但没有找到合适的例子。 非常感谢您在此问题上的帮助。

编辑:数据框中的数据示例如下:

  Date Hour.of.Year  Wind.MW  datetime
1  2010-04-01  1  375  2010-04-01  00:00:00
2  2010-04-01  2  492  2010-04-01  01:00:00
3  2010-04-01  3  483  2010-04-01  02:00:00
4  2010-04-01  4  476  2010-04-01  03:00:00
5  2010-04-01  5  486  2010-04-01  04:00:00
6  2010-04-01  6  512  2010-04-01  05:00:00
7  2010-04-01  7  421  2010-04-01  06:00:00
8  2010-04-01  8  396  2010-04-01  07:00:00
9  2010-04-01  9  456  2010-04-01  08:00:00
10  2010-04-01  10  453  2010-04-01  09:00:00
..  ..  ...  ..........  ........
8758  2011-03-31  8758  302  2011-03-31  21:00:00
8759  2011-03-31  8759  378  2011-03-31  22:00:00
8760  2011-03-31  8760  356  2011-03-31  23:00:00

编辑:我想对同一数据集执行其他基于时间的操作1.对所有数据点进行逐小时平均,即一年中每天第一个小时中所有值的平均值。 输出将是整个年度(24个时间点)的“每小时配置文件”。2.每周和每月执行相同的操作,即分别获取52和12个每小时配置文件。3.执行季节性平均值,例如6月至9月

将日期转换为lubridate可以理解的格式,然后分别使用monthmdaywday函数。

假设您有一个data.frame,其时间存储在Date列中,那么您的问题的答案将是:

 ###dummy data.frame
 df <- data.frame(Date=c("2012-01-01","2012-02-15","2012-03-01","2012-04-01"),a=1:4) 
 ##1. Select rows for particular month
 subset(df,month(Date)==1)

 ##2a. Select the first day of each month
 subset(df,mday(Date)==1)

 ##2b. Select the first week of each month
 ##get the week numbers which have the first day of the month
 wkd <- subset(week(df$Date),mday(df$Date)==1)
 ##select the weeks with particular numbers
 subset(df,week(Date) %in% wkd)     

 ##3. Select all mondays 
 subset(df,wday(Date)==1)
  1. 首先切换到Date表示形式: as.Date(df.MHwind_load$Date)
  2. 然后在日期向量上调用weekdays以获取标有星期几的新因子
  3. 然后在日期向量上调用months以获取一个标记为month的新因子
  4. (可选)创建years变量(请参见下文)。

现在,使用这些元素的相关组合对数据帧进行subset设置。 步骤2。获得任务3的答案。步骤3和步骤4。获得任务1的任务。任务2可能需要R的一行或两行。或者只选择对应于一个月中所有星期一和星期一的行。调用unique ,或者在结果上duplicated其alter-ego。

为了让你走...

newdf <- df.MHwind_load ## build an augmented data set
newdf$d <- as.Date(newdf$Date)
newdf$month <- months(newdf$d)
newdf$day <- weekdays(newdf$d)

## for some reason R has no years function.  Here's one
years <- function(x){ format(as.Date(x), format = "%Y") }

newdf$year <- years(newdf$d)

# get observations from January to March of every year
subset(newdf, month %*% in c('January', 'February', 'March'))

# get all Monday observations
subset(newdf, day == 'Monday')

# get all Mondays in 1999
subset(newdf, day == 'Monday' & year == '1999')

# slightly fancier: _first_ Monday of each month
# get the first weeks
first.week.of.month <- !duplicated(cbind(newdf$month, newdf$day)) 
# now pull out the mondays
subset(newdf, first.monday.of.month & day=='Monday')

由于您不是在询问数据的时间(小时)部分,因此最好将数据存储为Date对象。 否则,您可能会对chron感兴趣,它还具有一些便捷功能,如下所示。

关于Conjugate Prior的答案,您应该将日期数据存储为Date对象。 由于您的数据已经遵循默认格式('yyyy-mm-dd'),因此您可以在其上调用as.Date。 否则,您将必须指定您的字符串格式。 我还要在您的因素上使用as.character,以确保您不会内联错误。 我知道出于这个原因我已经遇到了因素因素(可能在当前版本中已解决)。

df.MHwind_load <- transform(df.MHwind_load, Date = as.Date(as.character(Date)))

现在,您可以很好地创建包装函数,以提取所需的信息。 您可以像上面一样使用transform来简单地添加代表月,日,年等的列,然后在逻辑上对其进行子集化。 或者,您可以执行以下操作:

getMonth <- function(x, mo) {  # This function assumes w/in single year vector
  isMonth <- month(x) %in% mo  # Boolean of matching months
  return(x[which(isMonth)]     # Return vector of matching months
}  # end function

或者,简写形式

getMonth <- function(x, mo) x[month(x) %in% mo]

这只是在存储该信息(转换帧)或在需要时对其进行处理(使用访问器方法)之间的权衡。

例如,一个更复杂的过程是您需要一个月的第一天。 但是,这并不完全困难。 下面是一个将返回所有这些值的函数,但仅对给定月份的排序后的值向量进行子集并采用它们的第一个就相当简单。

getFirstDay <- function(x, mo) {
  isMonth <- months(x) %in% mo
  x <- sort(x[isMonth])  # Look at only those in the desired month.
                         # Sort them by date. We only want the first day.
  nFirsts <- rle(as.numeric(x))$len[1]  # Returns length of 1st days
  return(x[seq(nFirsts)])
}  # end function

更容易的选择是

getFirstDayOnly <- function(x, mo) {sort(x[months(x) %in% mo])[1]}

由于您没有提供任何数据样本,因此我没有为它们提供原型,但这是可以帮助您获取所需信息的一种方法。 由您自己决定如何将它们放入您的工作流程中。 例如,假设您要获得给定年份每个月的第一天(假设我们只查看一年;您可以创建包装器或将向量预先处理为一年)。

# Return a vector of first days for each month
df <- transform(df, date = as.Date(as.character(date)))
sapply(unique(months(df$date)),  # Iterate through months in Dates
       function(month) {getFirstDayOnly(df$date, month)})

上面的内容也可以设计为使用其他访问器功能的单独的便捷功能。 这样,您可以创建一系列直接而简洁的方法来获取所需的信息。 然后,您只需将它们组合在一起即可创建非常简单易懂的函数,您可以在脚本中使用这些函数,从而以最有效的方式使您精确地掌握所需的内容。

您应该能够使用上面的示例来弄清楚如何为其他包装器提供原型,以访问所需的日期信息。 如果您需要这些方面的帮助,请随时在评论中提问。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM