Jun
16

## R Sapply Problem

Any expert in R please educates me. I have got a problem about the sapply (or lapply), it made me headache for over two hours.

As "for loop" is very slow in R, we should try best to avoid using it, and to use vectorization instead. sapply is designed for this, for example, instead of:

we could use

It went well, but what if besides computing z, I need to update another variable, for example, with loop, it is

in this case, temp is changing every step (it doesn't have to be a function of z[i]). How to vectorize that and use sapply then? since sapply can't return two variables z and temp.

~~I tried to define a matrix and store z in the first column and temp in the second column and return the matrix, however, failed.~~

Many thanks.

~~ah, I worked it out, it can be done by passing z itself to sapply, that's good.~~

the following is a sapply example returning the same result for "for loop" and "sapply".

Hot posts:

15 Incredibly Stupid Ways People Made Their Millions

Online stock practice

Ino.com: Don't Join Marketclub until You Read This MarketClub Reviews

World Changing Mathematical Discoveries

Value at Risk xls

Random posts:

Unified Asian Option Pricing

A Fully Integrated Liquidity and Market Risk Model

David Heath Passed Away - Sad News

Quant Project Outsourcing

CDS Standard Model

As "for loop" is very slow in R, we should try best to avoid using it, and to use vectorization instead. sapply is designed for this, for example, instead of:

for (i in 1:10) {

z[i] <- mean(x[1:i])

}

z[i] <- mean(x[1:i])

}

we could use

z <- sapply(1:10, function(i, x) {mean(x[1:i])}, x)

It went well, but what if besides computing z, I need to update another variable, for example, with loop, it is

temp <- 3

for (i in 1:10) {

x[i] <- x[i]-temp

z[i] <- mean(x[1:i])

temp <- x[i]-z[i]

}

for (i in 1:10) {

x[i] <- x[i]-temp

z[i] <- mean(x[1:i])

temp <- x[i]-z[i]

}

in this case, temp is changing every step (it doesn't have to be a function of z[i]). How to vectorize that and use sapply then? since sapply can't return two variables z and temp.

Many thanks.

**PS**, NO, still not correct, working on it...the following is a sapply example returning the same result for "for loop" and "sapply".

sapply.example <- function(nsim = 10){

x <- rnorm(nsim)

y <- list()

z.for <- array(0, nsim)

temp <- 3

for (i in 1:nsim) {

x[i] <- x[i]-temp

z.for[i] <- mean(x[1:i])

temp <- x[i]-z.for[i]

}

y$z.for <- z.for

z.sapply <- array(0,2*nsim)

z.sapply[1] <- 3

z.sapply <- sapply(seq(1,2*nsim,by=2), function(i,x,z.sapply) {

temp <- z.sapply[i]

z.temp <- mean(x[1:((i+1)/2)])

temp <- x[((i+1)/2)]-z.temp

z.sapply[i] <- temp

z.sapply[i+1] <- z.temp

z.sapply[i:(i+1)]

}, x, z.sapply, simplify =TRUE)

y$z.sapply <- z.sapply[seq(2,2*nsim, by=2)]

y

}

x <- rnorm(nsim)

y <- list()

z.for <- array(0, nsim)

temp <- 3

for (i in 1:nsim) {

x[i] <- x[i]-temp

z.for[i] <- mean(x[1:i])

temp <- x[i]-z.for[i]

}

y$z.for <- z.for

z.sapply <- array(0,2*nsim)

z.sapply[1] <- 3

z.sapply <- sapply(seq(1,2*nsim,by=2), function(i,x,z.sapply) {

temp <- z.sapply[i]

z.temp <- mean(x[1:((i+1)/2)])

temp <- x[((i+1)/2)]-z.temp

z.sapply[i] <- temp

z.sapply[i+1] <- z.temp

z.sapply[i:(i+1)]

}, x, z.sapply, simplify =TRUE)

y$z.sapply <- z.sapply[seq(2,2*nsim, by=2)]

y

}

**People viewing this post also viewed:**

Hot posts:

Random posts:

temp.ini <- 3

x.ini <- rnorm(10)

## loop version

temp <- temp.ini

x <- x.ini

z <- NA

for(i in 1:length(x)){

x[i] <- x[i] - temp

z[i] <- mean(x[1:i])

temp <- x[i] - z[i]

}

## vectorized version

make.func <- function(temp, x){

z <- NA

function(i){

x[i] <<- x[i] - temp

z[i] <<- mean(x[1:i])

temp <<- x[i] - z[i]

list(temp=temp, x=x, z=z)

}

}

func <- make.func(temp.ini, x.ini)

l <- sapply(1:length(x.ini), func, simplify=F)

## check of result

all(temp == l[[10]]$temp)

all(x == l[[10]]$x)

all(z == l[[10]]$z)

This code depends on the order of calls of func.

I'm not sure that sapply always calls a function in the order func(1), func(2), ....

If this is not the case, the code doesn't work.