'Efficient iteration to create df columns based on newly created columns (alternative to loop)

I need to create multiple columns in a data frame based on the new columns. For this aim, I have a loop that works fine but requires quite a lot of time to produce the result. May you suggest me a more efficient approach than my loop? Happy if this has a dplyr/purrr approach such as map().

I put here a very simplified version of my real (more complicated and larger) code.

Defining input data for the function:

df <- 
  data.frame(data_2010 = c(1,2,3,4))

# Start and dnd of the loop
year_loopStart <- 2011
year_loopEnd <- 2015

Creating the function with a loop inside:

fun_lag <-
  function(df, year_loopStart, year_loopEnd){

    output <- df
    
    for(y in c(year_loopStart : year_loopEnd)){
      # Calculate population for the next years without considering the effect of air pollution 
      # Calculate population in the next years based on the row above
      output <-
        output%>%
        dplyr::mutate(
          "data_{y}" := 
            dplyr::lag(!!as.symbol(paste0("data_", y-1))))
    }
    
    return(output)
    }

Running the function with the loop (right output but slow when applied to many columns):

test1 <- 
  fun_lag(df, year_loopStart, year_loopEnd)

Desired output (obtained with fun_lag but it is slow): enter image description here

Failed attempt to use map() instead of a loop:

test2 <- 
  map_dfc(year_loopStart:year_loopEnd,
          ~ mutate(df,
                   "data_{.x}" :=
                     dplyr::lag(!!as.symbol(paste0("data_", .x -1)))))

Error message:

Error: Problem with `mutate()` column `data_2012`.
i `data_2012 = dplyr::lag(data_2011)`.
x Object 'data_2011' not found


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source