R: Групповая линейная регрессия скользящего окна с rollapply и ddply

У меня есть набор данных с несколькими группирующими переменными, по которым я хочу запустить линейную регрессию скользящего окна. Конечная цель состоит в том, чтобы извлечь 10 линейных регрессий с самыми низкими уклонами и усреднить их вместе, чтобы обеспечить среднюю минимальную скорость изменения. Я нашел примеры использования rollapply для вычисления линейных регрессий скользящего окна, но у меня есть дополнительное осложнение, которое я хотел бы применить эти линейные регрессии к группам в наборе данных.

Вот пример набора данных и мой текущий код, который близок и не совсем работает.

dat<-data.frame(w=c(rep(1,27), rep(2,27),rep(3,27)), z=c(rep(c(1,2,3),27)), 
x=c(rep(seq(1,27),3)), y=c(rnorm(27,10,3), rnorm(27,3,2.2), rnorm(27, 6,1.3)))

где w и z - две группирующие переменные, а x и y - члены регрессии.

Из моих поисков в Интернете здесь приведен код линейной регрессии основного скользящего окна, в котором размер окна равен 6, последовательные регрессии разделены 3 точками данных, и я извлекаю только коэффициент наклона (lm...)[2]

library(zoo)    
slopeData<-rollapply(zoo(dat), width=6, function(Z) { 
coef(lm(formula=y~x, data = as.data.frame(Z), na.rm=T))[2]
}, by = 3, by.column=FALSE, align="right")

Теперь я хочу применить регрессию скользящего окна к группам, указанным двумя группирующими переменными w и z. Поэтому я попробовал что-то подобное, используя пакет ddply из пакета plyr. Сначала я пытаюсь переписать приведенный выше код как функцию.

rolled<-function(df) {
    rollapply(zoo(df), width=6, function(Z) { 
    coef(lm(formula=y~x, data = as.data.frame(Z), na.rm=T))[2]
    }, by = 3, by.column=FALSE, align="right")
}

А затем запустите применить эту функцию, используя ddply

groupedSlope <- ddply(dat, .(w,z), function(d) rolled(d))

Это, однако, не работает, так как я получаю серию предупреждений и ошибок. Я предполагаю, что некоторые из ошибок могут быть связаны с объединением форматов зоопарка и фреймов данных, и это становится слишком сложным. Это то, над чем я работал до сих пор, но знает ли кто-нибудь о способах получения сгруппированных линейных регрессий с скользящим окном, потенциально более простых, чем этот метод?

Спасибо за любую помощь, Нейт

1 ответ

Решение

1) rollapply работает и с фреймами данных, поэтому не нужно конвертировать df в зоопарк

2) lm использования na.actionне na.rmи по умолчанию na.omit поэтому мы можем просто отбросить этот аргумент.

3) rollapplyr это более краткий способ написать rollapply(..., align = "right"),

При условии, что rolled в противном случае делает то, что вы хотите, и включение этих изменений в rolled, ddply утверждение в вопросе должно работать, или мы могли бы использовать by от основания R, который мы покажем ниже:

rolled <- function(df) {
    rollapplyr(df, width = 6, function(m) { 
          coef(lm(formula = y ~ x, data = as.data.frame(m)))[2]
       }, by = 3, by.column = FALSE
   )
}
do.call("rbind", by(dat, dat[c("w", "z")], rolled))
Другие вопросы по тегам