#r #dataframe #for-loop
Вопрос:
Передо мной была поставлена задача по созданию индикаторов запаздывания для ряда фреймов данных. Каждый фрейм данных имеет два столбца: дата и значение. Для каждого столбца «значение» мне нужно создать 12 новых столбцов, в которых задержка увеличивается на одну единицу.
Данный фрейм данных выглядит следующим образом:
date | value | 01-01-2021 1 02-01-2021 2 03-01-2021 3 04-01-2021 4 05-01-2021 5 06-01-2021 6 07-01-2021 7 08-01-2021 8
И мне нужно добавить новые столбцы, чтобы они выглядели так:
date | value | lag1 | ... | lag12 01-01-2021 1 2 13 02-01-2021 2 3 14 03-01-2021 3 4 15 04-01-2021 4 5 16 05-01-2021 5 6 17 06-01-2021 6 7 18 07-01-2021 7 8 19 08-01-2021 8 9 20
Приведенные значения приведены в иллюстративных целях, реальные данные носят экономический характер и, следовательно, не следуют какой-либо определенной закономерности.
До сих пор мне удавалось выяснить, как создавать по одному столбцу за раз для одного фрейма данных, но это не очень эффективно. Мне нужен способ перебрать все фреймы данных и создать дополнительные столбцы.
Заранее спасибо за любую помощь!
Ответ №1:
Зацикливайтесь на том количестве лагов, которое вам нужно, создавая список новых значений столбцов, а затем добавляйте их все сразу.
lagfun lt;- function(x,n) c(tail(x,-n), rep(NA,n)) dat[paste0("lag", 1:7)] lt;- lapply(1:7, lagfun, x=dat$value) dat # date value lag1 lag2 lag3 lag4 lag5 lag6 lag7 #1 01-01-2021 1 2 3 4 5 6 7 8 #2 02-01-2021 2 3 4 5 6 7 8 NA #3 03-01-2021 3 4 5 6 7 8 NA NA #4 04-01-2021 4 5 6 7 8 NA NA NA #5 05-01-2021 5 6 7 8 NA NA NA NA #6 06-01-2021 6 7 8 NA NA NA NA NA #7 07-01-2021 7 8 NA NA NA NA NA NA #8 08-01-2021 8 NA NA NA NA NA NA NA
Вы , конечно, могли бы использовать lag
функцию от dplyr
или аналогичную функцию вместо моей lagfun
, но это будет автономно.
Комментарии:
1. Спасибо, это работает отлично! Как бы вы поступили, если бы понадобился опережающий индикатор?
2.
leadfun lt;- function(x,n) c(rep(NA,n), head(x,-n))
или воспользуйтесьlead
функцией из dplyr.
Ответ №2:
Другое решение, основанное на purrr::map_dfc
:
library(tidyverse) df lt;- data.frame( stringsAsFactors = FALSE, date = c("01-01-2021", "02-01-2021","03-01-2021","04-01-2021","05-01-2021", "06-01-2021","07-01-2021","08-01-2021"), value = c(1L, 2L, 3L, 4L, 5L, 6L, 7L, 8L) ) n lt;- 7 df %gt;% bind_cols(map_dfc(1:n, ~ lead(select(df,2), .x) %gt;% setNames(str_c("lag", .x)))) #gt; date value lag1 lag2 lag3 lag4 lag5 lag6 lag7 #gt; 1 01-01-2021 1 2 3 4 5 6 7 8 #gt; 2 02-01-2021 2 3 4 5 6 7 8 NA #gt; 3 03-01-2021 3 4 5 6 7 8 NA NA #gt; 4 04-01-2021 4 5 6 7 8 NA NA NA #gt; 5 05-01-2021 5 6 7 8 NA NA NA NA #gt; 6 06-01-2021 6 7 8 NA NA NA NA NA #gt; 7 07-01-2021 7 8 NA NA NA NA NA NA #gt; 8 08-01-2021 8 NA NA NA NA NA NA NA