First, R is a vectorized programming language. This means that the double for
cycle is not necessary. Since each member of lista1
is a vector, we can multiply the integer vector by 8.
for (i in 1:5) {
novalista[[i]] <- lista1[[i]]*8
}
And the code is already simpler and faster.
In the example of the question, you can do even better.
What the question asks is to apply a function to each member of the lista1
list, or else that's exactly what lapply
does. No need to index list members . Just apply the function directly to each of them. It is also necessary to take into account that lapply
does not eliminate the cycle, lapply
is also a cycle form.
novalista2 <- lapply(lista1, '*', 8)
identical(novalista, novalista2)
#[1] TRUE
Here the function is the multiplication, *
, with the extra argument 8
, the multiplier.
This almost always gives simpler code, but unlike many R users, it's not always faster. To test this I will use the microbenchmark
package. The two ways to create novalista
are written in function form and then tested.
f <- function(lst){
novalista <- vector(mode = "list", length=length(lst))
for (i in seq_along(lst)) {
novalista[[i]] <- lst[[i]]*8
}
novalista
}
g <- function(lst) lapply(lst, '*', 8)
First with the short list of the question.
microbenchmark::microbenchmark(f(lista1), g(lista1), times = 1e4)
Now with a large list.
lista2 <- lapply(1:1000, function(i) sample(1000, 100))
microbenchmark::microbenchmark(f(lista2), g(lista2))
As you can see, in both cases for
was faster.