Morway, Eric
2017-Sep-13 16:52 UTC
[R] compounding precipitation based on whether falls within a day
Using the small reproducible example below, I'm wondering how best to complete the following task: In the small reproducible example below, the 3D array prec has indexes that correspond to time, x, y (i.e., prec[time, x, y]). In this case, the time index is hours since some predefined start time. I'd like to add up all the time indexes in 'prec' based on whether or not the corresponding hours fall within a given day. So, at the end of the small example below, there are two variables that I'm left with, prec_idx (an hourly sequence from beg_time to end_time) whose length is equal to the first index (the time index) of the 3D array of precipitation called prec. That is, I'd like to get a 3D array called prec*_daily* that has dimension prec*_daily*[21, 3, 4], where 21 is the number of days and the value in say prec*_daily*[1,x,y] is equal to prec[1,x,y] + prec[2,x,y] + ... + prec[24,x,y] ndays <- 21 base_time <- as.character('2001-12-31T23:00:00Z') hrs_since_base <- 1 # adding an extra second to the end b/c I'm paranoid about the midnight time stamp not being explicit beg_time <- as.POSIXct(base_time, format = "%Y-%m-%dT%H:%M:%SZ") + (hrs_since_base * 60 * 60) + 1 max_hr_since <- 24 * ndays end_time <- as.POSIXct(base_time, format = "%Y-%m-%dT%H:%M:%SZ") + (max_hr_since * 60 * 60) + 1 prec_idx <- seq(beg_time, end_time, by='hour') prec <- array(abs(rnorm((24*ndays) * 3 * 4)) , dim=c(24*ndays, 3, 4)) length(prec_idx) # 504 dim(prec) # 504 3 4 # How do I aggregate prec to get daily sums of precipitation based on the prec_idx array? [[alternative HTML version deleted]]
Bert Gunter
2017-Sep-13 18:06 UTC
[R] compounding precipitation based on whether falls within a day
Thanks for the reprex. Wouldn't have bothered without it. The following is I believe **almost** what you want. It seems a bit clumsy to me, so others may provide you something neater. But anyway... ## Convert POSIXct vector to dates ## There are 22 different days, not 21 date <- as.Date(prec_idx) ## Sum results by date at each i,j of the last 2 array dimensions z <- lapply(unique(date),function(d) apply(prec[date==d,,],2:3,sum) ) ## This gives a list with 22 3x4 matrices of sums. ## Convert to 3x4x22 array with prec_daily <- array(unlist(z),dim=c(3,4,22)) ## This is the **almost** part. You can use the aperm() function to reshape the array if you like. I leave those pleasures to you. HTH. Cheers, Bert Bert Gunter "The trouble with having an open mind is that people keep coming along and sticking things into it." -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) On Wed, Sep 13, 2017 at 9:52 AM, Morway, Eric <emorway at usgs.gov> wrote:> Using the small reproducible example below, I'm wondering how best to > complete the following task: > > In the small reproducible example below, the 3D array prec has indexes that > correspond to time, x, y (i.e., prec[time, x, y]). In this case, the time > index is hours since some predefined start time. I'd like to add up all > the time indexes in 'prec' based on whether or not the corresponding hours > fall within a given day. So, at the end of the small example below, there > are two variables that I'm left with, prec_idx (an hourly sequence from > beg_time to end_time) whose length is equal to the first index (the time > index) of the 3D array of precipitation called prec. That is, I'd like to > get a 3D array called prec*_daily* that has dimension prec*_daily*[21, 3, > 4], > where 21 is the number of days and the value in say prec*_daily*[1,x,y] is > equal to prec[1,x,y] + prec[2,x,y] + ... + prec[24,x,y] > > > ndays <- 21 > base_time <- as.character('2001-12-31T23:00:00Z') > hrs_since_base <- 1 > > # adding an extra second to the end b/c I'm paranoid about the midnight > time stamp not being explicit > beg_time <- as.POSIXct(base_time, format = "%Y-%m-%dT%H:%M:%SZ") + > (hrs_since_base * 60 * 60) + 1 > > max_hr_since <- 24 * ndays > end_time <- as.POSIXct(base_time, format = "%Y-%m-%dT%H:%M:%SZ") + > (max_hr_since * 60 * 60) + 1 > > prec_idx <- seq(beg_time, end_time, by='hour') > > prec <- array(abs(rnorm((24*ndays) * 3 * 4)) , dim=c(24*ndays, 3, 4)) > > length(prec_idx) > # 504 > dim(prec) > # 504 3 4 > > # How do I aggregate prec to get daily sums of precipitation based on the > prec_idx array? > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/ > posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
Eric Berger
2017-Sep-15 07:42 UTC
[R] compounding precipitation based on whether falls within a day
Hi Eric, Bert's solution is very elegant. His final comment prompted me to check out the aperm() function which I have never used. The final step to complete his response is prec_daily2 <- aperm(prec_daily, c(3,1,2)) Regards On Wed, Sep 13, 2017 at 9:06 PM, Bert Gunter <bgunter.4567 at gmail.com> wrote:> Thanks for the reprex. Wouldn't have bothered without it. > > The following is I believe **almost** what you want. It seems a bit clumsy > to me, so others may provide you something neater. But anyway... > > ## Convert POSIXct vector to dates > ## There are 22 different days, not 21 > date <- as.Date(prec_idx) > > ## Sum results by date at each i,j of the last 2 array dimensions > z <- lapply(unique(date),function(d) > apply(prec[date==d,,],2:3,sum) > ) > > ## This gives a list with 22 3x4 matrices of sums. > ## Convert to 3x4x22 array with > > prec_daily <- array(unlist(z),dim=c(3,4,22)) > > ## This is the **almost** part. You can use the aperm() function to reshape > the array if you like. I leave those pleasures to you. > > HTH. > > Cheers, > Bert > > > > Bert Gunter > > "The trouble with having an open mind is that people keep coming along and > sticking things into it." > -- Opus (aka Berkeley Breathed in his "Bloom County" comic strip ) > > On Wed, Sep 13, 2017 at 9:52 AM, Morway, Eric <emorway at usgs.gov> wrote: > > > Using the small reproducible example below, I'm wondering how best to > > complete the following task: > > > > In the small reproducible example below, the 3D array prec has indexes > that > > correspond to time, x, y (i.e., prec[time, x, y]). In this case, the > time > > index is hours since some predefined start time. I'd like to add up all > > the time indexes in 'prec' based on whether or not the corresponding > hours > > fall within a given day. So, at the end of the small example below, > there > > are two variables that I'm left with, prec_idx (an hourly sequence from > > beg_time to end_time) whose length is equal to the first index (the time > > index) of the 3D array of precipitation called prec. That is, I'd like > to > > get a 3D array called prec*_daily* that has dimension prec*_daily*[21, 3, > > 4], > > where 21 is the number of days and the value in say prec*_daily*[1,x,y] > is > > equal to prec[1,x,y] + prec[2,x,y] + ... + prec[24,x,y] > > > > > > ndays <- 21 > > base_time <- as.character('2001-12-31T23:00:00Z') > > hrs_since_base <- 1 > > > > # adding an extra second to the end b/c I'm paranoid about the midnight > > time stamp not being explicit > > beg_time <- as.POSIXct(base_time, format = "%Y-%m-%dT%H:%M:%SZ") + > > (hrs_since_base * 60 * 60) + 1 > > > > max_hr_since <- 24 * ndays > > end_time <- as.POSIXct(base_time, format = "%Y-%m-%dT%H:%M:%SZ") + > > (max_hr_since * 60 * 60) + 1 > > > > prec_idx <- seq(beg_time, end_time, by='hour') > > > > prec <- array(abs(rnorm((24*ndays) * 3 * 4)) , dim=c(24*ndays, 3, 4)) > > > > length(prec_idx) > > # 504 > > dim(prec) > > # 504 3 4 > > > > # How do I aggregate prec to get daily sums of precipitation based on the > > prec_idx array? > > > > [[alternative HTML version deleted]] > > > > ______________________________________________ > > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > > https://stat.ethz.ch/mailman/listinfo/r-help > > PLEASE do read the posting guide http://www.R-project.org/ > > posting-guide.html > > and provide commented, minimal, self-contained, reproducible code. > > > > [[alternative HTML version deleted]] > > ______________________________________________ > R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see > https://stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide http://www.R-project.org/ > posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]