简体   繁体   中英

Most (memory and time) efficient way to add element to vector in loop R?

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?

This method may be bad because it copies the vector on each iteration?

vec <- c()
for (i in 1:10) {
  vec <- c(vec, i)
}

This may be optimal?

vec <- c()
for (i in 1:10) {
  vec <- append(vec, i)
}

This could get fiddly for complicated loops

vec <- c()
for (i in 1:10) {
  vec[i] <- i
}

Other methods?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM