基于新创建的列创建 df 列的高效迭代(替代循环)

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

我需要根据新列在数据框中创建多个列。为此,我有一个工作正常但需要大量时间才能产生结果的循环。你能建议我一个比我的循环更有效的方法吗?如果这有一个 dplyr/purrr 方法,如 map().

我在这里放了一个非常简化的真实代码(更复杂更大)的版本。

正在为函数定义输入数据:

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

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

创建内部有循环的函数:

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)
    }

运行带循环的函数(输出正确但应用于多列时速度较慢):

test1 <- 
  fun_lag(df, year_loopStart, year_loopEnd)

期望的输出(通过fun_lag获得,但很慢):

尝试使用 map() 而不是循环失败:

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

错误信息:

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

您可以使用 imap -

lag 传递不同的 n
library(dplyr)
library(purrr)

bind_cols(df, 
          imap_dfc(year_loopStart:year_loopEnd, 
                   ~df %>% transmute("data_{.x}" := lag(data_2010, .y))))

#  data_2010 data_2011 data_2012 data_2013 data_2014 data_2015
#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