Автоматизация создания новых столбцов для списка кадров данных — R

#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