Дубликат вектора в скользящей манере в R

Скажем, я хочу запустить регрессию, при которой входные данные для DV должны браться скользящим образом. Поэтому, чтобы облегчить этот процесс, я сначала хотел бы «дублировать» этот вектор, посредством чего я соответствующим образом сворачиваю наблюдения. В качестве примера см. структуру данных ниже.

# libraries #
library(dplyr)

# reproducible data # 
df1 <- tibble(ID = as.factor(rep(c(1, 2), each = 40)),
              YEAR = rep(rep(c(2001:2010), each = 4), 2),
              QTR = rep(c(1:4), 20),
              DV = rnorm(80))

df2 <- tibble(ID = as.factor(rep(c(1, 2), each = 120)),
              YEAR = rep(rep(c(2005:2010), each = 20), 2),
              IV = rnorm(240))

Причина, по которой данные структурированы таким образом, заключается в том, что данные в df2 являются остатками ранее выполненных регрессий, которые также использовали " скользящие" данные.

Затем цель состоит в том, чтобы запустить модель, в которой наблюдения в df1 «прокручиваются»:

  • регрессия 1: DV = строки 1-20 в df1, IV = строки 1-20 в df2
  • регрессия 2: DV = строки 5-25 в df1, IV = строки 21-40 в df2
  • регрессия 3: DV = строки 10-30 в df1, IV = строки 41-60 в df2
  • и так далее

Я подошел к этой проблеме, попытавшись «дублировать» df1 в скользящей манере, чтобы было легче выполнить регрессию.

На данный момент я попытался прокрутить его через функцию embed() в пакете base, но это очень быстро превращается в беспорядок, поскольку мой реальный набор данных намного больше. Будет ли альтернатива elegent dplyr?

Спасибо!


person Oscar    schedule 08.05.2019    source источник


Ответы (1)


Мы могли бы использовать

v1 <- c(1, seq(5, nrow(df1), by = 4))
v2 <- seq(20, nrow(df1), by = 4)
i1 <- seq_len(min(c(length(v1), length(v2))))
lst1 <- map2(v1[i1], v2[i1], ~ df1 %>% 
                           slice(.x:.y))

Точно так же сделайте это с 'df2'

v11 <- seq(1, nrow(df2), by = 20)
v22 <- seq(20, nrow(df2), by = 20)
i2 <- seq_len(min(c(length(v11), length(v22))))
lst2 <- map2(v11[i2], v22[i2], ~ df2 %>% 
                           slice(.x:.y))

а затем используйте map2 для применения функций к соответствующим элементам обоих lists

Обновлять

Как упоминалось в OP о группировке по «ID», один из вариантов — group_split по «ID», а затем выполните те же действия, что и выше.

df1 %>%
    group_split(ID) %>% 
    map(~ {
      v1 <- c(1, seq(5, nrow(.x), by = 4))
      v2 <- seq(20, nrow(.), by = 4)
      i1 <- seq_len(min(c(length(v1), length(v2))))
      map2(v1[i1], v2[i1], function(x, y) .x %>%
           slice(x:y))
   })
person akrun    schedule 08.05.2019
comment
@Oscar Это исправлено, с i1 (проверьте 3-ю строку) - person akrun; 08.05.2019