【问题标题】:Calculating means for trimesters from an array with monthly values从具有每月值的数组中计算三个月的平均值
【发布时间】:2020-03-19 02:22:48
【问题描述】:

我有一个大数组,其中包含每月降水值(维度=144(经度)*72(纬度)*395(时间)),其中时间从 1979-01-03(年/月/日)开始,结束于2011-11-03.

我需要首先计算每个月的均值和 sd(即每个月和域的每个点的一个均值和一个 sd)。我是这样做的:

months<-c(as.character(1:12))
years<-c(as.character(1979:2011))
lista<-list()
for (i in months){
  lista[[i]]<-which(format(time2,"%m")==i)   #time2 is the time dimension from the 
                                             # array, in format: 1979-01-03, 1979-02-03,etc.
}
monthly_means<-list(); monthly_sd<-list()
for(i in 1:length(lista)){
  medias_mensuales[[i]]<-apply(precipitacion[,,lista[[i]]],c(1,2),mean)
  sd_mensuales[[i]]<-apply(precipitacion[,,lista[[i]]],c(1,2),sd)
}

然后(这是我遇到麻烦的地方)每个学期(DJF、MAM、JJA、SON)的手段和 sd。首先提取每个三个月的数据然后做一些类似于我之前做的事情是不是一个好主意?

【问题讨论】:

标签: r multidimensional-array statistics mean


【解决方案1】:

问题应包括所有数据,但这次我们在最后的注释中为您提供了一些数据。此外,该问题不包括对所需内容的解释,因此我们假设所需内容是每个 precip[i, j, ] 的所有 1 月实例的平均值,所有 2 月实例的平均值等等都形成一个 3d 数组其中一维是 12。同样适用于 sd,同样适用于三个月。

precip 的最后一个定义中的日期定义为tt,然后将moytoy 定义为接受Date 向量并返回一年中的月份的函数(数字从1 到12 ) 和一年中的第三季度(数字从 1 到 4)。这些使用yearmonyearqtr 类将日期表示为年份加分数,在toy 的情况下添加1/12 以将Dec 移至Jan,Jan 移至Feb 等,以便将三个月的季度转换为日历季度。

使用这些函数将 cyc12 定义为月份数字(1 到 12)的向量,并将 cyc4 定义为三个月季度数字(1 到 4)的向量。它们的值可以交替表示为rep(1:12, length = 395)rep(1:4, each = 3, length = 396)[-1]

使用cyc12cyc4,我们使用applytapply,如图所示。

对于前两个 apply 实例,我们得到维度为 c(12, 144, 72) 的数组,对于后两个实例,我们得到 c(4, 144, 72)。 (如果您想要置换维度,请使用aperm。)

library(zoo)

tt <- seq(as.Date("1979-01-03"), as.Date("2011-11-03"), "month")

moy <- function(x) cycle(as.yearmon(x))
cyc12 <- moy(tt)  
means12 <- apply(precip, 1:2, function(x) tapply(x, cyc12, mean))
sd12 <- apply(precip, 1:2, function(x) tapply(x, cyc12, sd))

toy <- function(x) cycle(as.yearqtr(as.yearmon(x) + 1/12))
cyc4 <- toy(tt) 
means4 <- apply(precip, 1:2, function(x) tapply(x, cyc4, mean))
sd4 <- apply(precip, 1:2, function(x) tapply(x, cyc4, sd))

注意

为了使这个可重现,假设输入数据如下

Dims <- c(144, 72, 395)
precip <- array(seq_len(prod(Dims)), Dims)

【讨论】:

  • 嘿,在tt &lt;- seq(as.Date("1979-01-03"), as.Date("2011-11-03"), "day") 中,它不应该是“月”而不是“日”,因为数组包含一个月平均值吗?之后,我尝试了域中的一个随机点(lon=30,lat=25)并确保它没有任何 NA,所以我做了sds.mon &lt;- tapply(precipitacion[30,25,], as.yearmon(tt), sd),但结果都是(395)个 NA。然后我尝试了means.mon &lt;- tapply(precipitacion[30,25,], as.yearmon(tt), mean) 的平均值,结果与我已经拥有的值相同,这意味着它没有计算平均值。我没有看到错误。
  • 已完全修改答案。
  • 好的,现在这很完美,但我想了解function(x) tapply(x,.., sd)实际上在做什么,如果你不介意的话,我的意思是x是什么?
  • x 是函数的参数。如果将该函数应用于向量x,它将返回函数体计算的值。 apply(precip, 1:2, function(x)...) 将为每个 i 和 j 应用匿名函数到向量 precip[i, j, ] 所以每次运行匿名函数时 x 等于向量 precip[i, j, ] 一些 i 和 j 的值。
  • 抱歉,我不明白这是如何工作的 function(x) tapply(x, ..., ...) ,函数 (x) 是什么?它是在“tapply(x,...,...)”中求值还是乘法还是什么?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-03-03
  • 2020-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多