2

I am attempting to create a loop that runs a function with specific values of i in a vector:

For example I would like to save i + 2 for when i is 1 and 5

test<- c()
for(i in c(1,5)){
  
  test[i] <- i + 2
  
}

This ends up printing NA for 2 ,3 and 4: [1] 3 NA NA NA 7

while the result I would like is: [1] 3 7

This is probably very elementary but I cannot seem to figure this out.

jay.sf
  • 60,139
  • 8
  • 53
  • 110
Kevin
  • 191
  • 4
  • If you are using `test[i]<-` then you'll be doing `test[1]<-` and `test[5]<-` since `i` will be 1 and 5. If you set the 1st and 5th values, then R needs to fill something in for the 2nd-4th. If you just want to add 2 to each element, just use `test <- c(1,5)+2`. There's no loop needed in R. – MrFlick Feb 16 '22 at 04:31
  • Your loop, `for(i in c(1,5))` only runs twice. Once with i=1 and once with i=5. To get it to run 1, 2, 3, 4, 5 you need `1:5` or `seq(5)`. R cannot create a vector with missing indices so it fills in 2, 3, and 4 with NAs. – dcarlson Feb 16 '22 at 04:33
  • If there is no way of avoiding the NA using the forloop, is there a function in r that will allow me to run a function using specific values? – Kevin Feb 16 '22 at 04:40
  • This is exactly the type of code we try to avoid when writing R code. Most functions are vectorized. The "expensive" part of operations is usually allocating memory. If you are growing an object one item at a time, that's very slow/inefficient for large collections. A more explicit mapping style makes more sense. Base R: `sapply(c(1,5), function(x) x+2)` with in a tidyverse style `purrr::map_dbl(c(1,5), ~.x+2)` – MrFlick Feb 16 '22 at 04:55
  • not exactly sure what your comment means, is this what you're trying to do? https://stackoverflow.com/a/62219373/2994949 – rawr Feb 16 '22 at 04:56

2 Answers2

2

R is vectorized, means you can do this:

c(1, 5) + 2
# [1] 3 7

for loops in R are often very slow, which is why they are implemented in C in functions of the *apply family, e.g.

sapply(c(1, 5), \(i) i + 2)
# [1] 3 7

If you really need to rely on a for loop, If you really need to rely on a "for" loop, you may want to loop over the indices rather than the values (a quite common mistake!):

v <- c(1, 5)
test <- vector('numeric', length(v))
for (i in seq_along(v)) {
  test[i] <- v[i] + 2
}
test
# [1] 3 7
jay.sf
  • 60,139
  • 8
  • 53
  • 110
  • 2
    Well, it's usually not the for loop part that's slow. It's the slowing increasing an object one item at a time that's slow. A for loop can be just as fast as apply long as you pre-allocate the result first (for anything more complicated than simple vectorized functions). – MrFlick Feb 16 '22 at 05:18
  • @MrFlick I'm aware of discussions like [this](https://stackoverflow.com/a/2276001/6574038), of course. I didn't want to write an unnecessarily long answer that has already been given elsewhere. – jay.sf Feb 16 '22 at 05:32
0

Use append

test<- c()
for(i in c(1,5)){
  test<-append(test,i+2)
}
Bensstats
  • 988
  • 5
  • 17