不平衡面板的滚动回归

Rolling regression with unbalanced panel

我正在尝试根据滚动回归公式计算环境复杂性的度量。 复杂度的公式定义如下: 对于连续三年,对于行业中的所有公司,年末的销售价值都根据年初的销售价值进行回归。回归系数定义为环境复杂性。

这是我 运行 遇到的一个问题:公司在几年之间加入和退出一个行业,使得回归方程中的初始 X 和 Y 在数量上不相等。

为了更好地说明这一点,给出以下示例数据集:

> set.seed(123)
> df <- data.table("Firm" = c("A","B","A","B","C","A","B","C","D","B","C","D","E","F"),
+                  "Year" = c(1980,1980,1981,1981,1981,1982,1982,1982,1982,1983,1983,1983,1983,1983),
+                  "Industry" = rep("I1",14),
+                  "Sale" = sample(1000:1500,14))
> df
    Firm Year Industry Sale
 1:    A 1980       I1 1414
 2:    B 1980       I1 1462
 3:    A 1981       I1 1178
 4:    B 1981       I1 1013
 5:    C 1981       I1 1194
 6:    A 1982       I1 1425
 7:    B 1982       I1 1305
 8:    C 1982       I1 1117
 9:    D 1982       I1 1298
10:    B 1983       I1 1228
11:    C 1983       I1 1243
12:    D 1983       I1 1497
13:    E 1983       I1 1373
14:    F 1983       I1 1152

要衡量 1983 年的复杂性,我必须查看 1981-1983 年的时间跨度。然而,1983 年该行业有 5 家公司,1981 年有 3 家公司,并且它们之间只有两家共同的公司(B 和 C)。 因此,为了衡量 1983 年的复杂性,我必须首先只采用公司 B 和 C,然后将它们在 1983 年的销售额(1228 和 1243)回归到它们在 1981 年的销售额(1178 和 1013),这将导致系数0.08287293.

所需的输出应如下所示:

> df
    Firm Year Industry Sale    compx
 1:    A 1980       I1 1414       NA
 2:    B 1980       I1 1462       NA
 3:    A 1981       I1 1178       NA
 4:    B 1981       I1 1013       NA
 5:    C 1981       I1 1194       NA
 6:    A 1982       I1 1425 -2.50000
 7:    B 1982       I1 1305 -2.50000
 8:    C 1982       I1 1117 -2.50000
 9:    D 1982       I1 1298 -2.50000
10:    B 1983       I1 1228 0.08287293
11:    C 1983       I1 1243 0.08287293
12:    D 1983       I1 1497 0.08287293
13:    E 1983       I1 1373 0.08287293
14:    F 1983       I1 1152 0.08287293

我为行业添加了一个变量,因为我想为每个行业迭代该过程。 data.table 解决方案会很棒,因为我的数据集相当大。

非常感谢。

编辑:抱歉,我输入了错误的期望输出。现已编辑。

一个简单的解决方案是编写一个 fit 函数,它获取数据的一个子集,使用 dcast 对其进行重塑以将第一年和最后一年作为单独的列,运行回归并提取系数。然后,您可以循环数年并将其合并回您的主数据集。

这里有两种不同的方法。第一个在开始和结束时进行重塑。第二个在循环内重塑。

第一个:

df_wide <- dcast(df, Firm + Industry ~ Year, value.var="Sale")

for (i in ncol(df_wide):3) {
  if (i < 5) {
    df_wide[[i]] <- NA_real_
  } else {
    f <- paste0("`", colnames(df_wide)[i], "`~`", colnames(df_wide)[i-2], "`")
    f <- as.formula(f)
    df_wide[[i]] <- coef(lm(f, df_wide))[2]
  }
}

melt(df_wide, 
     id.vars=c("Firm", "Industry"), 
     variable.name="Year",
     value.name="compx")
    

第二个:

fit <- function(year=1980) {
  year_min <- year - 2
  year_max <- year 
  if (all(year_min:year_max %in% df$Year)) {
    tmp <- df[Year %in% year_min:year_max]
    tmp <- dcast(tmp, Firm + Industry ~ Year, value.var="Sale")
    f <- as.formula(paste0("`", year_max, "`~`", year_min, "`"))
    out <- coef(lm(f, tmp))[2]
  } else {
    out <- NA
  }
  out <- data.table(Year=year, compx=out)
  return(out)
}

results <- list()
for (y in 1980:1985) {
  results[[y]] <- fit(y)
}
results <- rbindlist(results)

merge(df, results, on="Year")
#>     Year Firm Industry Sale       compx
#>  1: 1980    A       I1 1414          NA
#>  2: 1980    B       I1 1462          NA
#>  3: 1981    A       I1 1178          NA
#>  4: 1981    B       I1 1013          NA
#>  5: 1981    C       I1 1194          NA
#>  6: 1982    A       I1 1425 -2.50000000
#>  7: 1982    B       I1 1305 -2.50000000
#>  8: 1982    C       I1 1117 -2.50000000
#>  9: 1982    D       I1 1298 -2.50000000
#> 10: 1983    B       I1 1228  0.08287293
#> 11: 1983    C       I1 1243  0.08287293
#> 12: 1983    D       I1 1497  0.08287293
#> 13: 1983    E       I1 1373  0.08287293
#> 14: 1983    F       I1 1152  0.08287293