From: Oleg Sklyar <osklyar_at_ebi.ac.uk>

Date: Tue 30 Jan 2007 - 23:42:27 GMT

Date: Tue 30 Jan 2007 - 23:42:27 GMT

It is surely an elegant way of doing things (although far from being easy to parse visually) but is it really faster than a loop?

-- Dr Oleg Sklyar | EBI-EMBL, Cambridge CB10 1SD, UK | +44-1223-494466 Byron Ellis wrote: > Actually, why not use a closure to store previous value(s)? > > In the simple case, which depends on x_i and y_{i-1} > > gen.iter = function(x) { > y = NA > function(i) { > y <<- if(is.na(y)) x[i] else y+x[i] > } > } > > y = sapply(1:10,gen.iter(x)) > > Obviously you can modify the function for the bookkeeping required to > manage whatever lag you need. I use this sometimes when I'm > implementing MCMC samplers of various kinds. > > > On 1/30/07, Herve Pages <hpages@fhcrc.org> wrote:Received on Wed Jan 31 10:44:57 2007

>> Tom McCallum wrote:

>>> Hi Everyone, >>> >>> I have a question about for loops. If you have something like: >>> >>> f <- function(x) { >>> y <- rep(NA,10); >>> for( i in 1:10 ) { >>> if ( i > 3 ) { >>> if ( is.na(y[i-3]) == FALSE ) { >>> # some calculation F which depends on one or more of the previously >>> generated values in the series >>> y[i] = y[i-1]+x[i]; >>> } else { >>> y[i] <- x[i]; >>> } >>> } >>> } >>> y >>> } >>> >>> e.g. >>> >>>> f(c(1,2,3,4,5,6,7,8,9,10,11,12)); >>> [1] NA NA NA 4 5 6 13 21 30 40 >>> >>> is there a faster way to process this than with a 'for' loop? I have >>> looked at lapply as well but I have read that lapply is no faster than a >>> for loop and for my particular application it is easier to use a for loop. >>> Also I have seen 'rle' which I think may help me but am not sure as I have >>> only just come across it, any ideas?

>> Hi Tom,

>>

>> In the general case, you need a loop in order to propagate calculations

>> and their results across a vector.

>>

>> In _your_ particular case however, it seems that all you are doing is a

>> cumulative sum on x (at least this is what's happening for i >= 6).>> So you could do:

>>

>> f2 <- function(x)>> {

>> offset <- 3

>> start_propagate_at <- 6>> y_length <- 10>> init_range <- (offset+1):start_propagate_at>> y <- rep(NA, offset)>> y[init_range] <- x[init_range]>> y[start_propagate_at:y_length] <- cumsum(x[start_propagate_at:y_length])>> y>> }

>>

>> and it will return the same thing as your function 'f' (at least when 'x' doesn't

>> contain NAs) but it's not faster :-/

>>

>> IMO, using sapply for propagating calculations across a vector is not appropriate

>> because:

>>

>> (1) It requires special care. For example, this:

>>

>> > x <- 1:10

>> > sapply(2:length(x), function(i) {x[i] <- x[i-1]+x[i]})

>>

>> doesn't work because the 'x' symbol on the left side of the <- in the

>> anonymous function doesn't refer to the 'x' symbol defined in the global>> environment. So you need to use tricks like this:

>>

>> > sapply(2:length(x),

>> function(i) {x[i] <- x[i-1]+x[i]; assign("x", x, envir=.GlobalEnv); x[i]})

>>

>> (2) Because of this kind of tricks, then it is _very_ slow (about 10 times

>> slower or more than a 'for' loop).

>>

>> Cheers,

>> H.

>> >> >>> Many thanks >>> >>> Tom >>> >>> >>>

>> ______________________________________________

>> R-devel@r-project.org mailing list

>> https://stat.ethz.ch/mailman/listinfo/r-devel

>> > > ______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel

Archive maintained by Robert King, hosted by
the discipline of
statistics at the
University of Newcastle,
Australia.

Archive generated by hypermail 2.1.8, at Wed 31 Jan 2007 - 13:31:10 GMT.

*
Mailing list information is available at https://stat.ethz.ch/mailman/listinfo/r-devel.
Please read the posting
guide before posting to the list.
*