How to perform rolling regression in R with this dataset?
All columns of df
are the same
all(df == df[, 1])
## [1] TRUE
so it can perfectly predict X1 using X2 and the others are not needed so it gives NA.
Regarding the rollapply
code it only gave coefficients because that is what you asked for coef(lm(...))
. Your function should return a vector of whatever it is you want to get out.
It does a regression for rows 1:24, rows 2:25, ... rows 196:219 so clearly there are 196 such sets so the result has 196 rows. If you specify fill=NA
then it will pad it with NAs to give the same number of rows as df
.
Note that rollapplyr
is available which defaults to align = "right"
.
Here is a possible function that returns a variety of information:
library(broom)
stats <- function(x) {
fm <- lm(X1 ~., as.data.frame(x))
c(coef(fm), unlist(glance(fm)))
}
rollapplyr(df, width = 24, FUN = stats, by.column = FALSE)
Rollapply for rolling regression with different window sizes, save coefficients in matrixes
mov.reg
is not an lm
objct, so it does not make sense to take coefficients
of it. Also there is a reference to chron in the dput output so we need to load the chron package.
Xq
is not specified but rather two separate xts objects are shown so we have assumed that those two are called x
and y
. Then create a single zoo object z
from them. Now define a Coef
function which takes a matrix with x
and y
columns and performs the indicated regression returning the coefficients. Also define roll
which takes the width as input and runs rollapplyr
with the desired arguments. Now use lapply
to run roll
with each width producing a list of zoo objects. This list has one component for each element in widths
consisting of a zoo object with intercept and slope columns. Finally extract the intercepts from each component in the list and form a zoo object and do the same for the slopes. Note that if L
is a list of zoo objects then do.call("merge", L)
will produce a single zoo object from it.
library(xts) # this also loads zoo
library(chron)
# inputs are xts objects x and y
z <- cbind(x = as.zoo(x)[, 1], y = as.zoo(y)[, 1])
Coef <- function(m) coef(lm(y ~ x, as.data.frame(m)))
roll <- function(w) rollapplyr(z, w, Coef, by = 24, by.column = FALSE)
widths <- seq(24, 240, 24)
names(widths) <- widths # lapply will use these names for its output
L <- lapply(widths, roll)
intercepts <- do.call("merge", lapply(L, "[", TRUE, 1)) # extract 1st columns
slopes <- do.call("merge", lapply(L, "[", TRUE, 2)) # 2nd columns
Alternately do the rollapplyr
twice replacing the last 3 lines with:
intercepts <- do.call("merge", lapply(widths, function(w) roll(w)[, 1]))
slopes <- do.call("merge", lapply(widths, function(w) roll(w)[, 2]))
Rolling Regression in R
Define a function which returns the year and R squared given a subset of rows of df
(without ID
) and then use rollapply
with it.
library(dplyr)
library(zoo)
R2 <- function(x) {
x <- as.data.frame(x)
c(YEAR = tail(x$YEAR, 1), R2 = summary(lm(DV ~ IV, x))$r.squared)
}
df %>%
group_by(ID) %>%
do(data.frame(rollapply(.[-1], 20, by = 4, R2, by.column = FALSE))) %>%
ungroup
giving:
# A tibble: 12 x 3
ID YEAR R2
<fct> <dbl> <dbl>
1 1 2005 0.0133
2 1 2006 0.130
3 1 2007 0.0476
4 1 2008 0.0116
5 1 2009 0.00337
6 1 2010 0.00570
7 2 2005 0.0481
8 2 2006 0.00527
9 2 2007 0.0158
10 2 2008 0.0303
11 2 2009 0.235
12 2 2010 0.116
rolling regression by group in the tidyverse?
Define a function Coef
whose argument is formed from cbind(y, x)
and which regresses y on x with an intercept, returning the coefficients. Then apply rollapplyr
using the current and prior rows over each group. If by last you meant the 2 prior rows to the current row, i.e. exclude the current row, then replace 2 with list(-seq(2))
as an argument to rollapplyr
.
Coef <- . %>% as.data.frame %>% lm %>% coef
mydata %>%
group_by(group) %>%
do(cbind(reg_col = select(., y, x) %>% rollapplyr(2, Coef, by.column = FALSE, fill = NA),
date_col = select(., date))) %>%
ungroup
giving:
# A tibble: 8 x 4
group `reg_col.(Intercept)` reg_col.x date
<chr> <dbl> <dbl> <date>
1 a NA NA 2016-06-01
2 a 0 0.500 2016-06-02
3 a 0 0.500 2016-06-03
4 a 0 0.500 2016-06-04
5 b NA NA 2016-06-03
6 b 0.00000000000000126 0.333 2016-06-04
7 b - 0.00000000000000251 0.333 2016-06-05
8 b 0 0.333 2016-06-06
Variation
A variation of the above would be:
mydata %>%
group_by(group) %>%
do(select(., date, y, x) %>%
read.zoo %>%
rollapplyr(2, Coef, by.column = FALSE, fill = NA) %>%
fortify.zoo(names = "date")
) %>%
ungroup
Slope Only
If only the slope is needed there are further simplifications possible. We use the fact that the slope equals cov(x, y) / var(x)
.
slope <- . %>% { cov(.[, 2], .[, 1]) / var(.[, 2])}
mydata %>%
group_by(group) %>%
mutate(slope = rollapplyr(cbind(y, x), 2, slope, by.column = FALSE, fill = NA)) %>%
ungroup
Applying a rolling window regression to an XTS series in R
There are several problems here:
rollapply
passes a matrix butlm
requires adata.frame
.rollapply
applies the function to each column separately unless we
specifyby.column=FALSE
.- you may or may not want the result to be
right aligned with the dates but if you do userollapplyr
:
1) Incorporating the above we have:
dolm <- function(x) coef(lm(USDZAR ~ ., data = as.data.frame(x))))
rollapplyr(fxr, 62, dolm, by.column = FALSE)
2) An alternative to the lm
in the dolm
above is to use lm.fit
which directly works with matrices and is also faster:
dolm <- function(x) coef(lm.fit(cbind(Intercept = 1, x[,-1]), x[,1]))
Related Topics
Dygraph in R Multiple Plots at Once
How to Create a Bar and Line Plot with R Dygraphs
Error in Bind_Rows_(X, .Id):Argument 1 Must Have Names
Using Proxy Interface in Plotly/Shiny to Dynamically Change Data
Draw Bloxplots in R Given 25,50,75 Percentiles and Min and Max Values
Convert from K to Thousand (1000) in R
Saving Dynamic UI to Global R Workspace
Embedding Googlevis Charts into a Web Site
Web Scraping of Key Stats in Yahoo! Finance with R
R - Svd() Function - Infinite or Missing Values in 'X'