移动窗口

时间:2017-03-03 17:08:54

标签: r linear-regression

我有一个庞大的数据集,并希望在60的窗口上执行滚动线性回归。但是,我希望只有60个先前的值被考虑用于线性回归。

我的Dataframe DF包含以下列:

Date          Company   Y     X1   X2
01.01.2015    Mill     0.13   -1    -3
01.02.2015    Mill     0.16   1    5 
01.03.2015    Mill     0.83   3    4
01.04.2015    Mill     -0.83  23   4
01.01.1988    Hall    0.23    1    3
01.02.1988    Hall    0.24    23   2
01.03.1988    Hall    0.78    19   -9
01.04.1988    Hall    0.73    4    12
01.05.1988    Hall    0.72    5    12
01.11.2008    Jopo    0.12    0.9  32
01.12.2008    Jopo    0.13    10   32
01.01.2009    Jopo    0.32    0.2  10
01.02.2009    Jopo    0.32    2    -1

我为每家公司提供了数千个公司和数据,为期数月。必须在公司的每个月进行回归,这个特定公司的前60个滚动窗口。

在给定的例子中,假设只有3的滚动窗口,我希望公司Mill在01.04.2015回归,数据来自01.01-01.03-2015。对于公司大厅我希望在01.04和1988年5月1日回归,而对于Jopo,我希望在2009年2月1日回归。

理想情况下,结果将与公司和日期一起粘贴到新数据框中,因为我必须继续处理这些数据,并且必须对其进行更多分析。

以下代码应该为滚动回归提供技巧,但它不使用前60个日期,而是59并包括当前日期:

库(动物园)

rolled <- function(df) {                                    
    rollapply(df, width = 60,
        FUN = function(z) coef(lm(Y ~ X1+X2, data = as.data.frame(z))),
        by.column = FALSE, align = "right"
)
}    

以下代码的回归取决于​​公司名称,因为我想对每个公司进行回归,独立于其他公司。

Test <- do.call("rbind", by(DF[c("Y", "X1", "X2")], DF[c( "Name")], rolled))

如何合并,只有60个以前的值用于回归?也许有人知道如何展示&#34;公司&#34;和&#34;日期&#34;在结果?谢谢你的帮助!

1 个答案:

答案 0 :(得分:1)

假设DF在最后的注释中可重复使用。使用byDF拆分为公司行,并使用rollapplyr应用匿名函数。请注意rollapplyr可以使用width列表参数以及要使用的位置的偏移量。例如,list(-seq(3))表示使用前3行(如问题中所示)但不使用当前行(位置为0)。

library(zoo)

# w <- 60    
w <- 3
Coef <- function(x) coef(lm(as.data.frame(x)))
do.call("rbind", by(DF, DF$Company, function(x) 
    cbind(x, rollapplyr(x[3:5], list(-seq(w)), Coef, fill = NA, by.column = FALSE))))

,并提供:

              Date Company     Y   X1 X2 (Intercept)         X1         X2
Hall.5  01.01.1988    Hall  0.23  1.0  3          NA         NA         NA
Hall.6  01.02.1988    Hall  0.24 23.0  2          NA         NA         NA
Hall.7  01.03.1988    Hall  0.78 19.0 -9          NA         NA         NA
Hall.8  01.04.1988    Hall  0.73  4.0 12     0.37711 -0.0017480 -0.0484553
Hall.9  01.05.1988    Hall  0.72  5.0 12     1.30333 -0.0433333 -0.0333333
Jopo.10 01.11.2008    Jopo  0.12  0.9 32          NA         NA         NA
Jopo.11 01.12.2008    Jopo  0.13 10.0 32          NA         NA         NA
Jopo.12 01.01.2009    Jopo  0.32  0.2 10          NA         NA         NA
Jopo.13 01.02.2009    Jopo  0.32  2.0 -1     0.41104  0.0010989 -0.0091259
Mill.1  01.01.2015    Mill  0.13 -1.0 -3          NA         NA         NA
Mill.2  01.02.2015    Mill  0.16  1.0  5          NA         NA         NA
Mill.3  01.03.2015    Mill  0.83  3.0  4          NA         NA         NA
Mill.4  01.04.2015    Mill -0.83 23.0  4     0.21611  0.2994444 -0.0711111

你也可以试试这个:

library(broom)
fun <- function(x) unlist(tidy(lm(as.data.frame(x)))[, -1]) 
do.call("rbind", by(DF, DF$Company, function(x) 
 cbind(x, rollapplyr(x[3:5], list(-(seq(w))), fun, fill = NA, by.column = FALSE))))

给出:

              Date Company     Y   X1 X2 estimate1    estimate2    estimate3
Hall.5  01.01.1988    Hall  0.23  1.0  3        NA           NA           NA
Hall.6  01.02.1988    Hall  0.24 23.0  2        NA           NA           NA
Hall.7  01.03.1988    Hall  0.78 19.0 -9        NA           NA           NA
Hall.8  01.04.1988    Hall  0.73  4.0 12 0.3771138 -0.001747967 -0.048455285
Hall.9  01.05.1988    Hall  0.72  5.0 12 1.3033333 -0.043333333 -0.033333333
Jopo.10 01.11.2008    Jopo  0.12  0.9 32        NA           NA           NA
Jopo.11 01.12.2008    Jopo  0.13 10.0 32        NA           NA           NA
Jopo.12 01.01.2009    Jopo  0.32  0.2 10        NA           NA           NA
Jopo.13 01.02.2009    Jopo  0.32  2.0 -1 0.4110390  0.001098901 -0.009125874
Mill.1  01.01.2015    Mill  0.13 -1.0 -3        NA           NA           NA
Mill.2  01.02.2015    Mill  0.16  1.0  5        NA           NA           NA
Mill.3  01.03.2015    Mill  0.83  3.0  4        NA           NA           NA
Mill.4  01.04.2015    Mill -0.83 23.0  4 0.2161111  0.299444444 -0.071111111
        std.error1 std.error2 std.error3 statistic1 statistic2 statistic3
Hall.5          NA         NA         NA         NA         NA         NA
Hall.6          NA         NA         NA         NA         NA         NA
Hall.7          NA         NA         NA         NA         NA         NA
Hall.8         NaN        NaN        NaN        NaN        NaN        NaN
Hall.9         NaN        NaN        NaN        NaN        NaN        NaN
Jopo.10         NA         NA         NA         NA         NA         NA
Jopo.11         NA         NA         NA         NA         NA         NA
Jopo.12         NA         NA         NA         NA         NA         NA
Jopo.13        NaN        NaN        NaN        NaN        NaN        NaN
Mill.1          NA         NA         NA         NA         NA         NA
Mill.2          NA         NA         NA         NA         NA         NA
Mill.3          NA         NA         NA         NA         NA         NA
Mill.4         NaN        NaN        NaN        NaN        NaN        NaN
        p.value1 p.value2 p.value3
Hall.5        NA       NA       NA
Hall.6        NA       NA       NA
Hall.7        NA       NA       NA
Hall.8       NaN      NaN      NaN
Hall.9       NaN      NaN      NaN
Jopo.10       NA       NA       NA
Jopo.11       NA       NA       NA
Jopo.12       NA       NA       NA
Jopo.13      NaN      NaN      NaN
Mill.1        NA       NA       NA
Mill.2        NA       NA       NA
Mill.3        NA       NA       NA
Mill.4       NaN      NaN      NaN
> 

<强>替代

另一种可能性是使用宽度w+1,然后删除最后一个组件。

# w <- 60    
w <- 3 
Coef1 <- function(x) coef(lm(as.data.frame(head(x, -1))))
do.call("rbind", by(DF, DF$Company, function(x) 
    cbind(x, rollapplyr(x[3:5], w+1, Coef1, fill = NA, by.column = FALSE))))

公司少于w + 1行

如果有少于w + 1行的公司,请尝试这样做。它使用partial=TRUE rollapplyr参数来计算lm行数较少,并相应地修改Coef以便它可以继续工作:

# w <- 60    
w <- 3
Coef <- function(x) coef(lm(as.data.frame(matrix(x, c(nrow(x), 1)))))
do.call("rbind", by(DF, DF$Company, function(x) cbind(x, 
  rollapplyr(x[3:5], list(-seq(w)), Coef, partial = TRUE, by.column = FALSE))))

注意:输入DF为:

Lines <- "Date          Company   Y     X1   X2
01.01.2015    Mill     0.13   -1    -3
01.02.2015    Mill     0.16   1    5 
01.03.2015    Mill     0.83   3    4
01.04.2015    Mill     -0.83  23   4
01.01.1988    Hall    0.23    1    3
01.02.1988    Hall    0.24    23   2
01.03.1988    Hall    0.78    19   -9
01.04.1988    Hall    0.73    4    12
01.05.1988    Hall    0.72    5    12
01.11.2008    Jopo    0.12    0.9  32
01.12.2008    Jopo    0.13    10   32
01.01.2009    Jopo    0.32    0.2  10
01.02.2009    Jopo    0.32    2    -1"
DF <- read.table(text = Lines, header = TRUE, as.is = TRUE)