I have 4-dimension array x(lat,lon,time,var) I am using "apply" to calculate over time new = apply(x,c(1,2,4),FUN=function(y) {length(which(y>=70))}) This is very slow. Is there anyway make it faster? -Debasish [[alternative HTML version deleted]]
function(y) {sum(y>=70)} -- Sent from my phone. Please excuse my brevity. On July 9, 2016 1:19:27 PM PDT, Debasish Pai Mazumder <pai1981 at gmail.com> wrote:>I have 4-dimension array x(lat,lon,time,var) > >I am using "apply" to calculate over time > new = apply(x,c(1,2,4),FUN=function(y) {length(which(y>=70))}) > >This is very slow. Is there anyway make it faster? > >-Debasish > > [[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.
On Sat, 9 Jul 2016, Debasish Pai Mazumder wrote:> I have 4-dimension array x(lat,lon,time,var) > > I am using "apply" to calculate over time > new = apply(x,c(1,2,4),FUN=function(y) {length(which(y>=70))}) > > This is very slow. Is there anyway make it faster?If dim(x)[3] << prod(dim(x)[-3]), new <- Reduce("+",lapply(1:dim(x)[3],function(z) x[,,z,]>=70)) will be faster. However, if you can follow Peter Langfelder's suggestion to use rowSums, that would be best. Even using rowSums(aperm(x,c(1,2,4,3)>=70,dims=3) and paying the price of aperm() might be better. Chuck
Hi Everyone, Thanks for your help. It works. I have similar problem when I am calculating number of spell. I am also calculation spell (definition: period of two or more days where x exceeds 70) using similar way: *new = apply(x,c(1,2,4),FUN=function(y) {fun.spell.deb(y, 70)})* where fun.spell.deb.R: *## Calculate spell durationfun.spell.deb <- function(data, threshold = 1, direction = c("above", "below")){ #coln <- grep(weather, names(data))# var <- data[,8] if(missing(direction)) {direction <- "above"} if(direction=="below") {b <- (data <= threshold)} else {b <- (data >threshold)} b[b==TRUE] = 1 y <-rle(b) ans <-length(subset((y$lengths[y$values==1]), (y$lengths[y$values==1])>=2)) return(ans)}* Do you have any idea how to make the "apply" faster here? -Deb On Sat, Jul 9, 2016 at 3:46 PM, Charles C. Berry <ccberry at ucsd.edu> wrote:> On Sat, 9 Jul 2016, Debasish Pai Mazumder wrote: > > I have 4-dimension array x(lat,lon,time,var) >> >> I am using "apply" to calculate over time >> new = apply(x,c(1,2,4),FUN=function(y) {length(which(y>=70))}) >> >> This is very slow. Is there anyway make it faster? >> > > If dim(x)[3] << prod(dim(x)[-3]), > > new <- Reduce("+",lapply(1:dim(x)[3],function(z) x[,,z,]>=70)) > > will be faster. > > However, if you can follow Peter Langfelder's suggestion to use rowSums, > that would be best. Even using rowSums(aperm(x,c(1,2,4,3)>=70,dims=3) and > paying the price of aperm() might be better. > > Chuck >[[alternative HTML version deleted]]