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))