运行 财务数据的滞后回归
Run lagged regressions for finance data
我正在尝试 运行 对我的数据框中的 30 项资产中的每一项进行滞后回归。
我的 table 看起来像这样:
date rx1 rx2 rx3
1930-01-31 0 0 0
1930-02-28 0 0 -0.3
1930-03-31 0 0 -0.1
.... -0.1 ...
1975-02-28 -0.4 -0.2 ...
2016-12-31 -0.03 ... ...
然后我尝试运行用这条线进行滞后回归(数据框:Rx3.df):
model <- dyn$lm(Rx3.df$rx1 ~ lag(Rx3.df$rx1, 1) + lag(Rx3.df$rx1, 2))
但我一直得到这个没有任何意义的结果:
Call:
lm(formula = dyn(Rx3.df$rx1 ~ lag(Rx3.df$rx1, 1) + lag(Rx3.df$rx1,
2)))
Coefficients:
(Intercept) lag(Rx3.df$rx1, 1) lag(Rx3.df$rx1, 2)
3.297e-16 1.000e+00 NA
谁能解决这个问题?谢谢!
对于冗长的回答,我提前表示歉意。似乎出于某种原因(不知道为什么?)dyn$lm
没有省略 NA
。例如,如果您键入 summary(model)
,您将收到此警告消息:
Warning message:
In summary.lm(lm(rx1 ~ lag(rx1, 1), data = df, model = T)) :
essentially perfect fit: summary may be unreliable
此外,如果您键入 nobs(model)
,您将得到与 nrow(Rx3.df)
相同的结果,这不应该发生,因为您将在每个滞后时至少丢弃 1 个观察值。
我重新创建了你的部分数据如下:
> df<- data.frame(rx1 = runif(1000, 1, 100))
> head(df, 5)
rx1
1 56.63239
2 89.99562
3 37.35498
4 7.47771
5 92.77819
在你的情况下,我得到:
> summary(dyn$lm(rx1~lag(rx1, 1) + lag(rx1, 2), data=df))
Call:
lm(formula = dyn(rx1 ~ lag(rx1, 1) + lag(rx1, 2)), data = df)
Residuals:
Min 1Q Median 3Q Max
-3.982e-13 -5.400e-16 3.600e-16 1.230e-15 1.211e-14
Coefficients: (1 not defined because of singularities)
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.876e-14 8.219e-16 3.499e+01 <2e-16 ***
lag(rx1, 1) 1.000e+00 1.424e-17 7.024e+16 <2e-16 ***
lag(rx1, 2) NA NA NA NA
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 1.275e-14 on 998 degrees of freedom
Multiple R-squared: 1, Adjusted R-squared: 1
F-statistic: 4.934e+33 on 1 and 998 DF, p-value: < 2.2e-16
Warning message:
In summary.lm(dyn$lm(rx1 ~ lag(rx1, 1) + lag(rx1, 2), data = df)) :
essentially perfect fit: summary may be unreliable
但是,如果我手动滞后变量:
> library(dplyr)
> df_lag<- mutate(df, lag1_rx1 = lag(rx1), lag2_rx1 = lag(rx1, 2))
> head(df_lag, 5)
rx1 lag1_rx1 lag2_rx1
1 56.63239 NA NA
2 89.99562 56.63239 NA
3 37.35498 89.99562 56.63239
4 7.47771 37.35498 89.99562
5 92.77819 7.47771 37.35498
结果正确:
> summary(dyn$lm(rx1~lag1_rx1+lag2_rx1, data=df_lag))
Call:
lm(formula = dyn(rx1 ~ lag1_rx1 + lag2_rx1), data = df_lag)
Residuals:
Min 1Q Median 3Q Max
-50.325 -23.271 -0.471 24.763 50.864
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 50.84681 2.46790 20.603 <2e-16 ***
lag1_rx1 -0.03664 0.03170 -1.156 0.248
lag2_rx1 0.02494 0.03170 0.787 0.432
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 28.34 on 995 degrees of freedom
(2 observations deleted due to missingness)
Multiple R-squared: 0.002033, Adjusted R-squared: 2.741e-05
F-statistic: 1.014 on 2 and 995 DF, p-value: 0.3633
请注意,在第二种情况下,就在 Residual standard error
下方,我收到 (2 observations deleted due to missingness)
的通知,这应该会发生!这也反映在自由度上,自由度应该等于您拥有的观察数量减去您正在估计的参数数量。
希望对您有所帮助!
多个变量的主要编辑
对于此解决方案,您将需要使用 data.table
。我还创建了一个新的 df
来匹配您给出的示例。
library(data.table)
> df<- data.table(date= sample(seq(as.Date('1900/01/01'), as.Date('2000/01/01'), by="day"), 1000), rx1 = runif(1000, 1, 100), rx2 = rnorm(1000), rx3 = rpois(1000, 1))
> head(df, 5)
date rx1 rx2 rx3
1: 1989-01-16 9.642232 -1.14117351 0
2: 1964-05-10 55.946293 1.21938225 1
3: 1911-11-24 8.609234 -0.77489439 1
4: 1914-09-29 57.253969 0.02277709 0
5: 1902-08-09 69.454322 -0.10850359 1
接下来的两段代码造成了滞后:
> df[, paste0("lag1_", names(df)[like(names(df), "^rx")]) := shift(.SD), .SDcols = like(names(df), "^rx")]
> df[, paste0("lag2_", names(df)[like(names(df), "^rx")]) := shift(.SD, 2), .SDcols = like(names(df), "^rx")]
> head(df, 5)
date rx1 rx2 rx3 lag1_rx1 lag1_rx2 lag1_rx3 lag2_rx1 lag2_rx2
1: 1989-01-16 9.642232 -1.14117351 0 NA NA NA NA NA
2: 1964-05-10 55.946293 1.21938225 1 9.642232 -1.14117351 0 NA NA
3: 1911-11-24 8.609234 -0.77489439 1 55.946293 1.21938225 1 9.642232 -1.1411735
4: 1914-09-29 57.253969 0.02277709 0 8.609234 -0.77489439 1 55.946293 1.2193823
5: 1902-08-09 69.454322 -0.10850359 1 57.253969 0.02277709 0 8.609234 -0.7748944
lag2_rx3
1: NA
2: NA
3: 0
4: 1
5: 1
最后结果:
> formula<- paste0(paste0("rx", 1:3),"~", paste0("lag1_rx", 1:3), "+", paste0("lag2_rx", 1:3))
> results<- lapply(formula, function(x) lm(x, data=df))
> names(results)<- paste0("rx", 1:3)
显然,将上面的 3 更改为您拥有的变量数量。我没有提供输出,因为它太大了。对于 rx1
,您可以通过键入 summary(results[["rx1"]]
.
来访问结果
PS:与常规的旧 lm
.
相比,使用 dyn$lm
似乎没有什么区别
看起来你的时间序列一点都不滞后。这也是为什么第一个回归变量的系数为 1 的原因。
要解决您的问题,您可以使用 dplyr
包的 lag
/ lead
函数(取决于您的数据格式):
> library(dplyr)
> x <- 1:10
> stats::lag(x)
[1] 1 2 3 4 5 6 7 8 9 10
attr(,"tsp")
[1] 0 9 1
> dplyr::lead(x)
[1] 2 3 4 5 6 7 8 9 10 NA
> dplyr::lag(x)
[1] NA 1 2 3 4 5 6 7 8 9
或 lag
时间序列的 zoo
函数:
> library(zoo)
> y <- zoo(1:10)
> stats::lag(y, 1, na.pad = TRUE)
1 2 3 4 5 6 7 8 9 10
2 3 4 5 6 7 8 9 10 NA
> stats::lag(y, -1, na.pad = TRUE)
1 2 3 4 5 6 7 8 9 10
NA 1 2 3 4 5 6 7 8 9
我正在尝试 运行 对我的数据框中的 30 项资产中的每一项进行滞后回归。
我的 table 看起来像这样:
date rx1 rx2 rx3
1930-01-31 0 0 0
1930-02-28 0 0 -0.3
1930-03-31 0 0 -0.1
.... -0.1 ...
1975-02-28 -0.4 -0.2 ...
2016-12-31 -0.03 ... ...
然后我尝试运行用这条线进行滞后回归(数据框:Rx3.df):
model <- dyn$lm(Rx3.df$rx1 ~ lag(Rx3.df$rx1, 1) + lag(Rx3.df$rx1, 2))
但我一直得到这个没有任何意义的结果:
Call:
lm(formula = dyn(Rx3.df$rx1 ~ lag(Rx3.df$rx1, 1) + lag(Rx3.df$rx1,
2)))
Coefficients:
(Intercept) lag(Rx3.df$rx1, 1) lag(Rx3.df$rx1, 2)
3.297e-16 1.000e+00 NA
谁能解决这个问题?谢谢!
对于冗长的回答,我提前表示歉意。似乎出于某种原因(不知道为什么?)dyn$lm
没有省略 NA
。例如,如果您键入 summary(model)
,您将收到此警告消息:
Warning message:
In summary.lm(lm(rx1 ~ lag(rx1, 1), data = df, model = T)) :
essentially perfect fit: summary may be unreliable
此外,如果您键入 nobs(model)
,您将得到与 nrow(Rx3.df)
相同的结果,这不应该发生,因为您将在每个滞后时至少丢弃 1 个观察值。
我重新创建了你的部分数据如下:
> df<- data.frame(rx1 = runif(1000, 1, 100))
> head(df, 5)
rx1
1 56.63239
2 89.99562
3 37.35498
4 7.47771
5 92.77819
在你的情况下,我得到:
> summary(dyn$lm(rx1~lag(rx1, 1) + lag(rx1, 2), data=df))
Call:
lm(formula = dyn(rx1 ~ lag(rx1, 1) + lag(rx1, 2)), data = df)
Residuals:
Min 1Q Median 3Q Max
-3.982e-13 -5.400e-16 3.600e-16 1.230e-15 1.211e-14
Coefficients: (1 not defined because of singularities)
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2.876e-14 8.219e-16 3.499e+01 <2e-16 ***
lag(rx1, 1) 1.000e+00 1.424e-17 7.024e+16 <2e-16 ***
lag(rx1, 2) NA NA NA NA
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 1.275e-14 on 998 degrees of freedom
Multiple R-squared: 1, Adjusted R-squared: 1
F-statistic: 4.934e+33 on 1 and 998 DF, p-value: < 2.2e-16
Warning message:
In summary.lm(dyn$lm(rx1 ~ lag(rx1, 1) + lag(rx1, 2), data = df)) :
essentially perfect fit: summary may be unreliable
但是,如果我手动滞后变量:
> library(dplyr)
> df_lag<- mutate(df, lag1_rx1 = lag(rx1), lag2_rx1 = lag(rx1, 2))
> head(df_lag, 5)
rx1 lag1_rx1 lag2_rx1
1 56.63239 NA NA
2 89.99562 56.63239 NA
3 37.35498 89.99562 56.63239
4 7.47771 37.35498 89.99562
5 92.77819 7.47771 37.35498
结果正确:
> summary(dyn$lm(rx1~lag1_rx1+lag2_rx1, data=df_lag))
Call:
lm(formula = dyn(rx1 ~ lag1_rx1 + lag2_rx1), data = df_lag)
Residuals:
Min 1Q Median 3Q Max
-50.325 -23.271 -0.471 24.763 50.864
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 50.84681 2.46790 20.603 <2e-16 ***
lag1_rx1 -0.03664 0.03170 -1.156 0.248
lag2_rx1 0.02494 0.03170 0.787 0.432
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 28.34 on 995 degrees of freedom
(2 observations deleted due to missingness)
Multiple R-squared: 0.002033, Adjusted R-squared: 2.741e-05
F-statistic: 1.014 on 2 and 995 DF, p-value: 0.3633
请注意,在第二种情况下,就在 Residual standard error
下方,我收到 (2 observations deleted due to missingness)
的通知,这应该会发生!这也反映在自由度上,自由度应该等于您拥有的观察数量减去您正在估计的参数数量。
希望对您有所帮助!
多个变量的主要编辑
对于此解决方案,您将需要使用 data.table
。我还创建了一个新的 df
来匹配您给出的示例。
library(data.table)
> df<- data.table(date= sample(seq(as.Date('1900/01/01'), as.Date('2000/01/01'), by="day"), 1000), rx1 = runif(1000, 1, 100), rx2 = rnorm(1000), rx3 = rpois(1000, 1))
> head(df, 5)
date rx1 rx2 rx3
1: 1989-01-16 9.642232 -1.14117351 0
2: 1964-05-10 55.946293 1.21938225 1
3: 1911-11-24 8.609234 -0.77489439 1
4: 1914-09-29 57.253969 0.02277709 0
5: 1902-08-09 69.454322 -0.10850359 1
接下来的两段代码造成了滞后:
> df[, paste0("lag1_", names(df)[like(names(df), "^rx")]) := shift(.SD), .SDcols = like(names(df), "^rx")]
> df[, paste0("lag2_", names(df)[like(names(df), "^rx")]) := shift(.SD, 2), .SDcols = like(names(df), "^rx")]
> head(df, 5)
date rx1 rx2 rx3 lag1_rx1 lag1_rx2 lag1_rx3 lag2_rx1 lag2_rx2
1: 1989-01-16 9.642232 -1.14117351 0 NA NA NA NA NA
2: 1964-05-10 55.946293 1.21938225 1 9.642232 -1.14117351 0 NA NA
3: 1911-11-24 8.609234 -0.77489439 1 55.946293 1.21938225 1 9.642232 -1.1411735
4: 1914-09-29 57.253969 0.02277709 0 8.609234 -0.77489439 1 55.946293 1.2193823
5: 1902-08-09 69.454322 -0.10850359 1 57.253969 0.02277709 0 8.609234 -0.7748944
lag2_rx3
1: NA
2: NA
3: 0
4: 1
5: 1
最后结果:
> formula<- paste0(paste0("rx", 1:3),"~", paste0("lag1_rx", 1:3), "+", paste0("lag2_rx", 1:3))
> results<- lapply(formula, function(x) lm(x, data=df))
> names(results)<- paste0("rx", 1:3)
显然,将上面的 3 更改为您拥有的变量数量。我没有提供输出,因为它太大了。对于 rx1
,您可以通过键入 summary(results[["rx1"]]
.
PS:与常规的旧 lm
.
dyn$lm
似乎没有什么区别
看起来你的时间序列一点都不滞后。这也是为什么第一个回归变量的系数为 1 的原因。
要解决您的问题,您可以使用 dplyr
包的 lag
/ lead
函数(取决于您的数据格式):
> library(dplyr)
> x <- 1:10
> stats::lag(x)
[1] 1 2 3 4 5 6 7 8 9 10
attr(,"tsp")
[1] 0 9 1
> dplyr::lead(x)
[1] 2 3 4 5 6 7 8 9 10 NA
> dplyr::lag(x)
[1] NA 1 2 3 4 5 6 7 8 9
或 lag
时间序列的 zoo
函数:
> library(zoo)
> y <- zoo(1:10)
> stats::lag(y, 1, na.pad = TRUE)
1 2 3 4 5 6 7 8 9 10
2 3 4 5 6 7 8 9 10 NA
> stats::lag(y, -1, na.pad = TRUE)
1 2 3 4 5 6 7 8 9 10
NA 1 2 3 4 5 6 7 8 9