基于新创建的列创建 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
我需要根据新列在数据框中创建多个列。为此,我有一个工作正常但需要大量时间才能产生结果的循环。你能建议我一个比我的循环更有效的方法吗?如果这有一个 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