Home > front end >  Vectorialised column addition
Vectorialised column addition

Time:12-28

Given this tibble:

tibble(x = c(1:9))

I want to add a column x_lag_1 = c(NA,1:8), a column x_lag_2 = c(NA,NA,1:7), etc.

Up to x_lag_n.

CodePudding user response:

This can be quick with data.table:

library(data.table)

n <- seq(4)
setDT(df)[, paste0('x_lag_', n) := shift(x, n)]

df
  x x_lag_1 x_lag_2 x_lag_3 x_lag_4
1: 1      NA      NA      NA      NA
2: 2       1      NA      NA      NA
3: 3       2       1      NA      NA
4: 4       3       2       1      NA
5: 5       4       3       2       1
6: 6       5       4       3       2
7: 7       6       5       4       3
8: 8       7       6       5       4
9: 9       8       7       6       5

CodePudding user response:

You may use map_dfc to add n new columns.

library(dplyr)
library(purrr)

df <- tibble(x = c(1:9))
n <- 3
bind_cols(df, map_dfc(seq_len(n), ~df %>% 
                      transmute(!!paste0('x_lag', .x) := lag(x, .x))))

#      x x_lag1 x_lag2 x_lag3
#  <int>  <int>  <int>  <int>
#1     1     NA     NA     NA
#2     2      1     NA     NA
#3     3      2      1     NA
#4     4      3      2      1
#5     5      4      3      2
#6     6      5      4      3
#7     7      6      5      4
#8     8      7      6      5
#9     9      8      7      6

CodePudding user response:

We can also use purrr::walk() to do it. Not terribly useful here as each iteration is independent from one another, but it is possible.

library(tidyverse)

df <- tibble(x = c(1:9))

n <- 5

walk(str_c("x_lag_", 1:n), ~ {
  df[[.]] <<- lag(df$x, parse_number(.))
})

df
#> # A tibble: 9 × 6
#>       x x_lag_1 x_lag_2 x_lag_3 x_lag_4 x_lag_5
#>   <int>   <int>   <int>   <int>   <int>   <int>
#> 1     1      NA      NA      NA      NA      NA
#> 2     2       1      NA      NA      NA      NA
#> 3     3       2       1      NA      NA      NA
#> 4     4       3       2       1      NA      NA
#> 5     5       4       3       2       1      NA
#> 6     6       5       4       3       2       1
#> 7     7       6       5       4       3       2
#> 8     8       7       6       5       4       3
#> 9     9       8       7       6       5       4

Created on 2021-12-28 by the reprex package (v2.0.1)

  • Related