Создание среднего столбца, рассчитанного по временному окну, определенному категориальной переменной в R - PullRequest
0 голосов
/ 30 марта 2020

У меня есть фрейм данных, который выглядит следующим образом:

structure(list(week  = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10), 
               freq  = c(0, 4.34, 1.24, 0, 5.26, 0, 7.12, 3.70, 0, 0), 
               event = c(0, 0, 0, 0, 0, 0, 1, 0, 0, 0)), 
          row.names = c(NA, -10L), 
          class = c("tbl_df", "tbl", "data.frame"))

Мне нужно создать новый столбец, вычисляющий, в соответствии с событием = 1, среднее значение freq для окна между -2 и -4 предыдущих недель, определяемые переменной неделей. Например, поскольку событие = 1 на неделе 7, я бы хотел усреднить частоту для недель 2, 3, 4 и 5. Это должно повторяться каждый раз, когда событие равно 1. Это среднее значение должно быть указано в новом столбце. в строке, где событие = 1.

Точно так же мне нужно будет сгенерировать другой столбец со средним значением окна -1; +2 по отношению к событию = 1, поэтому в этом случае недели от 6 до 9.

Конечный результат должен выглядеть следующим образом:

week    freq    event     mean1     mean2
1       0       0         NA        NA
2       4.34    0         NA        NA
...
7       7.12    1         2.71      2.705
...

Буду признателен, если вы поможете мне по этому поводу я прочитал несколько похожих тем, но не смог найти решения этой конкретной c проблемы.

Ответы [ 2 ]

0 голосов
/ 30 марта 2020

Вот решение data.table, если я вас правильно понял:

library(data.table)
setDT(car_weekly)
car_weekly[, mean1 := fifelse(event == 1, shift(frollmean(freq, n = 4), 2), NA_real_) ]
car_weekly[, mean2 := fifelse(event == 1, shift(frollmean(freq, n = 4), -2), NA_real_)]


   week freq event mean1 mean2
 1:    1 0.00     0    NA    NA
 2:    2 4.34     0    NA    NA
 3:    3 1.24     0    NA    NA
 4:    4 0.00     0    NA    NA
 5:    5 5.26     0    NA    NA
 6:    6 0.00     0    NA    NA
 7:    7 7.12     1  2.71 2.705
 8:    8 3.70     0    NA    NA
 9:    9 0.00     0    NA    NA
10:   10 0.00     0    NA    NA
0 голосов
/ 30 марта 2020

Есть несколько проблем с вашим вопросом. Ваш dput не работал, поэтому я его починил. Во-вторых, вы говорите, что хотите отработать окно от -4 до -2 недель. Это будут недели 3, 4 и 5, а не недели 2, 3, 4 и 5. В этом примере я предположил, что вы имели в виду от -5 до -2 недель, хотя, как вы увидите, это легко изменить.

Следующая функция позволит вам указать относительную начальную и конечную позицию окна в вашем столбце frequency.

Эту функцию можно сделать более лаконичной и эффективной, используя такие библиотеки, как data.table, но я дал здесь базовое решение R и попытался написать его таким образом, чтобы сделать лог c просто следовать:

relative_window <- function(variable, start, stop)
{
  result <- rep(NA, length(variable))
  if(start > stop | start > length(variable) | stop > length(variable)) return(result)
  start_indices <- seq_along(variable) + start
  stop_indices  <- seq_along(variable) + stop
  ss <- which(start_indices > 0 & stop_indices <= length(variable))
  start_indices <- start_indices[ss]
  stop_indices <- stop_indices[ss]
  index <- seq_along(variable)[ss]
  for(i in seq_along(ss))
  {
    result[index[i]] <- mean(variable[start_indices[i]:stop_indices[i]])
  }
  return(result)
}

Так что теперь вы можете просто сделать:

df$mean1 <- ifelse(df$event == 1, relative_window(df$freq, -5, -2), NA)
df$mean2 <- ifelse(df$event == 1, relative_window(df$freq, -1, 2), NA)

Что дает вам

df
#>    week freq event mean1 mean2
#> 1     1 0.00     0    NA    NA
#> 2     2 4.34     0    NA    NA
#> 3     3 1.24     0    NA    NA
#> 4     4 0.00     0    NA    NA
#> 5     5 5.26     0    NA    NA
#> 6     6 0.00     0    NA    NA
#> 7     7 7.12     1  2.71 2.705
#> 8     8 3.70     0    NA    NA
#> 9     9 0.00     0    NA    NA
#> 10   10 0.00     0    NA    NA

Создано в 2020-03 -30 при представлении пакета (v0.3.0)

...