Я придумала некоторый код для расчета скользящего среднего для данных панели (строка в данных содержит значения одного субъекта за один день). Поскольку у меня было несколько более конкретных требований, код стал довольно сложным. Слишком сложный для приложения, не слишком редкий, на мой взгляд.
Вот что мне нужно:
скользящее среднее (среднее значений (a) за предыдущие 3 дня, исключая «текущий» день), (b) , рассчитанное только при наличии минимума 2 не пропущенных значения в этом окне)
относительно структуры панели
Не слишком сложно, верно?
Для 1. Я решил использовать rollapplyr()
и mean( , na.rm = T)
, чтобы исключить текущий день. (А) Я решил использовать самодельную функцию запаздывания и для (б) оператор if. И для 2. Я завернул все в tapply()
(с unlist()
), чтобы соблюдать структуру панели.
Вот пример кода:
library(zoo)
# example data (with missings)
set.seed(1)
df = data.frame(subject = rep(c("a", "b"), each = 10), day = rep(1:10, 2), value = rnorm(20))
df$value[15:17] = NA
# lag function (sensitive to "single day" subjects)
lag <- function(x, l = 1) {
if (length(x) > 1) (c(rep(NA, l), x[1:(length(x)-l)])) else (NA)
}
# calculate rolling mean
df$roll_mean3 = unlist(tapply(df$value, df$subject,
FUN = function(x) lag(rollapplyr(x, width = 3, fill = NA, partial = T,
FUN = function(x) ifelse(sum(!is.na(x)) > 1, mean(x, na.rm = T), NA)))))
df
Как я сказал, это решение кажется слишком сложным для ситуации, которая, я думаю, не так уж и далеко.
У вас есть предложения, как сделать это более простым (менее подверженным ошибкам) способом?
Я пропустил некоторые основные функции, которые позволяют легче обрабатывать данные панели?
Для иллюстрации вывод моего кода:
subject day value roll_mean3
1 a 1 -0.6264538 NA
2 a 2 0.1836433 NA
3 a 3 -0.8356286 -0.221405243
4 a 4 1.5952808 -0.426146366
5 a 5 0.3295078 0.314431838
6 a 6 -0.8204684 0.363053321
7 a 7 0.4874291 0.368106730
8 a 8 0.7383247 -0.001177187
9 a 9 0.5757814 0.135095124
10 a 10 -0.3053884 0.600511703
11 b 1 1.5117812 NA
12 b 2 0.3898432 NA
13 b 3 -0.6212406 0.950812202
14 b 4 -2.2146999 0.426794608
15 b 5 NA -0.815365744
16 b 6 NA -1.417970234
17 b 7 NA NA
18 b 8 0.9438362 NA
19 b 9 0.8212212 NA
20 b 10 0.5939013 0.882528703