Is it possible to vectorize something to have it create an output similar to b_loop below? Thanks!

require(dplyr)

a <- data.frame(col1 = 1:10)
b_vectorize <- a %>%
mutate(col1 = lag(col1, 1))
b_loop <- a
for(i in 2:10){
b_loop$col1[i] <- b_loop$col1[i-1]
}
print(a)
print(b_vectorize)
print(b_loop)

1 Like
suppressPackageStartupMessages(library(dplyr))

a <- data.frame(col1 = 1:10)
a
#>    col1
#> 1     1
#> 2     2
#> 3     3
#> 4     4
#> 5     5
#> 6     6
#> 7     7
#> 8     8
#> 9     9
#> 10   10

b_vectorize <- a %>%
  mutate(col1 = lag(col1, 1))
b_vectorize
#>    col1
#> 1    NA
#> 2     1
#> 3     2
#> 4     3
#> 5     4
#> 6     5
#> 7     6
#> 8     7
#> 9     8
#> 10    9

b_loop <- a
for(i in 2:10){
  b_loop$col1[i] <- b_loop$col1[i-1]
}
b_loop
#>    col1
#> 1     1
#> 2     1
#> 3     1
#> 4     1
#> 5     1
#> 6     1
#> 7     1
#> 8     1
#> 9     1
#> 10    1

Created on 2022-07-24 by the reprex package (v2.0.1)

The loop in question only contains the first element of a$col1. Is it really what you want to obtain? In that case it's easy with

b_vectorize2 <- a
b_vectorize2$col1 <- b_vectorize2$col1[[1]]
b_vectorize2
#>    col1
#> 1     1
#> 2     1
#> 3     1
#> 4     1
#> 5     1
#> 6     1
#> 7     1
#> 8     1
#> 9     1
#> 10    1

Or if you wanted to create the vector, you could use rep(a$col1[[1]], nrow(a))

Otherwise, if your goal is to create a "shifted" col1, I don't see the problem with your current b_vectorize, looks good to me, and the b_loop would be corrected if you didn't take the values from the column you were modifying, you could create a new column:

b_loop <- a
for(i in 2:10){
  b_loop$col2[i] <- b_loop$col1[i-1]
}
b_loop %>%
  select(col1 = col2)

Or if you want to modify col1 in place, loop in the other direction, from the bottom to the top.