不规则时间序列的年度、月度或日均值

5

我是“R”语言的新用户,但我找不到一个好的解决方案来解决问题。我有一个如下格式的时间序列:

>dates  temperature depth   salinity
>12/03/2012 11:26   9.7533  0.48073 37.607
>12/03/2012 11:56   9.6673  0.33281 37.662
>12/03/2012 12:26   9.6673  0.33281 37.672

我有一个不规则频率的变量测量,每15或30分钟一次,具体取决于时间段。我想计算每个变量的年度、月度和日度平均值,无论一天/一个月/一年内的数据数量是多少。我阅读了很多关于zoo、timeseries、xts等软件包的内容,但我无法清楚地了解我需要什么(可能是因为我对R不够熟练...)。
希望我的帖子表达清楚,如果不清楚,请告诉我。
4个回答

8

将您的数据转换为xts对象,然后使用apply.daily等函数计算您想要的任何值。

library(xts)
d <- structure(list(dates = c("12/03/2012 11:26", "12/03/2012 11:56", 
"12/03/2012 12:26"), temperature = c(9.7533, 9.6673, 9.6673), 
    depth = c(0.48073, 0.33281, 0.33281), salinity = c(37.607, 
    37.662, 37.672)), .Names = c("dates", "temperature", "depth", 
"salinity"), row.names = c(NA, -3L), class = "data.frame")
x <- xts(d[,-1], as.POSIXct(d[,1], format="%m/%d/%Y %H:%M"))
apply.daily(x, colMeans)
#                     temperature     depth salinity
# 2012-12-03 12:26:00    9.695967 0.3821167   37.647

非常感谢您的回答。使用xts的好处是我可以要求每周平均值。我尝试了您的代码,但我的整个数据集出现了一些问题,所以我会尝试修复它并与您保持联系!再次感谢! - Doc Martin's
没关系,日期和月份只是颠倒了(%m/%d >>> %d/%m)。谢谢! - Doc Martin's

3

我会将日、月和年添加到数据框中,然后使用aggregate()

首先将您的date列转换为POSIXct对象:

d$timestamp <- as.POSIXct(d$dates,format = "%m/%d/%Y %H:%M",tz ="GMT")

如果您想将日期(例如12/03/2012)放入名为Date的列中,请尝试以下操作:

d$Date <- format(d$timestamp,"%y-%m-%d",tz = "GMT")

接下来,按日期进行聚合:

aggregate(cbind("temperature.mean" = temperature,
                "salinity.mean" = salinity) ~ Date,
          data = d,
          FUN = mean)

同样地,您可以将月份放入一个列中(我们称之为M),然后...
d$M <- format(d$timestamp,"%B",tz = "GMT")

aggregate(cbind("temperature.mean" = temperature,
                "salinity.mean" = salinity) ~ M,
          data = d,
          FUN = mean)

或者如果你需要年-月

d$YM <- format(d$timestamp,"%y-%B",tz = "GMT")

aggregate(cbind("temperature.mean" = temperature,
                "salinity.mean" = salinity) ~ YM,
          data = d,
          FUN = mean)

如果您的数据中存在任何NA值,您可能需要考虑这些问题:
aggregate(cbind("temperature.mean" = temperature,
                "salinity.mean" = salinity) ~ YM,
          data = d,
          function(x) mean(x,na.rm = TRUE))

最后,如果你想按周平均,也可以这样做。首先生成周数,然后再次使用aggregate()

d$W <- format(d$timestamp,"%W",tz = "GMT")

aggregate(cbind("temperature.mean" = temperature,
                "salinity.mean" = salinity) ~ W,
          data = d,
          function(x) mean(x,na.rm = TRUE))

这个版本的周数将第一周定义为一年中的第一个星期一。每周从星期一到星期日。


你调用 format 的操作不起作用。dates列不是一个 POSIXct 对象。它可能是一个字符或(更可能)是一个因素。 - Joshua Ulrich
@JoshuaUlrich 已经注意到了。已修复。 - Andy Clifton
非常感谢您的回答!在我对第一个答案进行了更改后,它完美地运行了(日期和月份颠倒了,我猜这是国家的差异,因为在法国我们先给出日期再给出月份;)。就像我问Jdbaba的那样,是否有一种方法可以使用库播放器计算每周平均值,就像使用xts库一样? - Doc Martin's

1

hydroTSM 包含多项功能,可用于创建年度及其他摘要:

daily2annual(x, ...)
subdaily2annual(x, ...)
monthly2annual(x, ...)
annualfunction(x, FUN, na.rm = TRUE, ...)

1

然而,另一种使用plyr的方法:

df <- structure(list(dates = c("12/03/2012 11:26", "12/03/2012 11:56", 
   "12/03/2012 12:26"), temperature = c(9.7533, 9.6673, 9.6673), 
   depth = c(0.48073, 0.33281, 0.33281), salinity = c(37.607, 
   37.662, 37.672)), .Names = c("dates", "temperature", "depth",                                                                                                
  "salinity"), row.names = c(NA, -3L), class = "data.frame")

library(plyr)

# Change date to POSIXct
df$dates <- with(d,as.POSIXct(dates,format="%m/%d/%Y %H:%M"))

# Make new variables, year and month
df <- transform(d,month=as.numeric(format(dates,"%m")),year=as.numeric(format(dates,"%Y")))

## According to year
ddply(df,.(year),summarize,meantemp=mean(temperature),meandepth=mean(depth),meansalinity=mean(salinity))
  year meantemp meandepth meansalinity
1 2012 9.695967 0.3821167       37.647

## According to month
ddply(df,.(month),summarize,meantemp=mean(temperature),meandepth=mean(depth),meansalinity=mean(salinity))
  month meantemp meandepth meansalinity
1    12 9.695967 0.3821167       37.647

非常感谢您的回答!在我对第一个答案进行了更改后,它完美地运行了(我猜这是因为日期和月份颠倒了,在法国我们先写日再写月)。是否有一种类似于xts库的方式可以使用player库计算每周平均值? - Doc Martin's

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接