Reputation: 11
I have a large array with monthly precipitation values (dimensions=144(longitude)*72(latitude)*395(time)), where time starts at 1979-01-03 (year/month/day) and ends at 2011-11-03.
I need to calculate means and sd, first for each month (i.e. one mean and one sd for each month and each point of the domain). Here's how I did this:
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)
}
and then (this is where I'm having trouble) the means and sd for each trimester (DJF,MAM,JJA,SON). Is it a good idea to first extract each trimester's data and then do something similar to what I did before?
Upvotes: 0
Views: 189
Reputation: 269644
Questions should include all data but we have provided some for you this time in the Note at the end. Also the question did not include explanation of what was wanted so we assume that what is wanted is the mean over all January instances for each precip[i, j, ], the mean over all Feb instances and so on all formed into a 3d array in which one dimension is 12. Similarly for sd and similarly for trimesters.
Define the dates in the last deimnsion of precip
as tt
and then define moy
and toy
as functions which take a Date
vector and return the months of the year (numbers from 1 to 12) and trimester quarter of the year (numbers from 1 to 4). These use yearmon
and yearqtr
classes which represent dates as year plus fraction and in the case of toy
1/12 is added to move Dec into Jan, Jan into Feb, etc. so that the trimester quarters are transformed to calendar quarters.
Using these functions define cyc12
as a vector of month numbers (1 to 12) and cyc4 as a vector of trimester quarter numbers (1 to 4). Their values could alternately be expressed as rep(1:12, length = 395)
and rep(1:4, each = 3, length = 396)[-1]
.
Using cyc12
and cyc4
we use apply
and tapply
as shown.
For the first two apply
instances we get arrays of dimension c(12, 144, 72) and for the last two we get c(4, 144, 72). (If you want permutated dimensions use 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))
To make this reproducible, assme the input data is as follows
Dims <- c(144, 72, 395)
precip <- array(seq_len(prod(Dims)), Dims)
Upvotes: 0