Reputation: 52308
I can think of a few ways to add an element to a vector in a loop. For large loops time and memory become important. Which is most memory/time efficient?
vec <- c()
for (i in 1:10) {
vec <- c(vec, i)
}
vec <- c()
for (i in 1:10) {
vec <- append(vec, i)
}
vec <- c()
for (i in 1:10) {
vec[i] <- i
}
Upvotes: 2
Views: 172
Reputation: 51998
When using a for loop when you know the number of iterations (hence the size of the resulting vector) ahead of time, it makes more sense to preallocate:
vec <- numeric(10)
for(i in 1:10){
vec[i] <- i
}
That way you are not creating new vectors in each pass through the loop.
To get a feel for the time-complexity, you can experiment with the following code (which uses the microbenchmark
package):
f1 <- function(n) {
vec <- c()
for (i in 1:n) {
vec <- c(vec, i)
}
vec
}
f2 <- function(n) {
vec <- c()
for (i in 1:n) {
vec <- append(vec, i)
}
vec
}
f3 <- function(n) {
vec <- c()
for (i in 1:n) {
vec[i] <- i
}
vec
}
f4 <- function(n) {
vec <- numeric(n)
for(i in 1:n) {
vec[i] <- i
}
vec
}
test <- function(n) {
print(microbenchmark::microbenchmark(f1(n),f2(n),f3(n),f4(n)))
}
For example:
> test(10)
Unit: nanoseconds
expr min lq mean median uq max neval
f1(n) 1411 1763.5 20001.06 1764.0 2117.0 1765199 100
f2(n) 8816 8992.0 33756.65 9521.5 11108.5 2183403 100
f3(n) 2116 2469.0 29077.37 2469.0 3879.5 2565287 100
f4(n) 705 1058.0 20699.22 1059.0 1764.0 1906246 100
> test(100)
Unit: microseconds
expr min lq mean median uq max neval
f1(n) 21.158 22.5680 23.11462 22.9205 23.450 28.562 100
f2(n) 95.913 98.3805 100.45053 100.1440 101.554 112.838 100
f3(n) 19.747 20.8050 21.96511 21.1580 22.568 38.435 100
f4(n) 5.290 5.6420 5.91758 5.6430 5.995 9.521 100
> test(1000)
Unit: microseconds
expr min lq mean median uq max neval
f1(n) 842.402 856.8590 2526.95373 875.3715 1060.4950 8562.944 100
f2(n) 1622.390 1642.4890 2772.92502 1669.4640 1710.5440 9472.342 100
f3(n) 185.125 192.5295 267.38981 194.9980 199.0525 7266.019 100
f4(n) 49.367 51.1300 54.43051 52.8930 55.3610 128.000 100
For n = 10 the differences are minor, but by the time you get to n = 1000, the differences are dramatic.
Upvotes: 5