[R] avoiding a loop
Duncan Murdoch
murdoch at stats.uwo.ca
Tue Oct 24 21:04:33 CEST 2006
On 10/24/2006 2:53 PM, Jerome Asselin wrote:
> On Tue, 2006-10-24 at 14:36 -0400, Leeds, Mark (IED) wrote:
>> I think I asked a similar question 3 years ago to the Splus list and I
>> think the answer was no or noone answered so noone should spend more
>> than 5 minutes on this
>> because it could definitely be a waste of time.
>>
>> My question is whether the function below can be rewritten without a for
>> loop. apply is fine if it can be done that way but i doubt it. I call it
>> a lot and would
>> prefer to not loop.
>>
>> #-----------------------------------------------------------------------
>> --------------------------
>>
>> constructLt<-function(invector) {
>>
>> outvector<-invector
>>
>> for ( i in 2:length(invector) ) {
>> if ( invector[i] < 1 ) {
>> outvector[i]<-invector[i]*outvector[i-1]
>> }
>> }
>>
>> return(outvector)
>>
>> }
>
> You sure can vectorize this. Try this below... I haven't tested, but it
> should be close to your solution. There's also
>
> a <- invector[-1]
> outvector <- invector
> wh <- which(a<1)+1
> outvector[wh] <- a[wh] * invector[-length(invector)][wh-1]
> outvector
I think this misses the fact that if a sequence of invector values are
less than 1, then the multiplication accumulates: e.g. with invector
equal to rep(0.5, 5) the output should be
> constructLt(rep(0.5,5))
[1] 0.50000 0.25000 0.12500 0.06250 0.03125
whereas your function gives
> asselin(rep(0.5,5))
[1] 0.50 0.25 0.25 0.25 NA
A function like filter() might be able to do this, but in general R
doesn't give a way to write recursive formulae in a simple vector form.
In this particular case, I'd just use the for loop; if it turned out to
be too slow, I'd rewrite it in C, in a nearly literal translation.
Duncan Murdoch
More information about the R-help
mailing list