如何为脉冲响应计算自助法置信区间?R语言实现求助
解决VAR脉冲响应的自助法置信区间问题
我来帮你搞定这个自助法置信区间的问题!首先得明确,自助法的核心是从原始数据重新抽样并重复整个IRF计算流程,而不是直接对已经得到的irfs结果抽样——这是很多人容易踩的坑。下面一步步给你拆解解决方案:
步骤1:加载依赖包与基础数据(复用你的原有代码)
library(vars) library(varexternalinstrument) library(boot) # 别忘了加载boot包! data(GKdata) # 提前定义VAR用到的变量集,后续代码复用更方便 var_vars <- c("logip", "logcpi", "gs1", "ebp")
步骤2:编写自助抽样核心函数
这个函数是boot工具的核心,它需要接受抽样后的行索引(我们用stype="i"更直观,代表按行索引抽样),然后完整复刻从模型估计到IRF计算的全流程:
# 定义自助函数:输入原始数据+抽样索引,输出所有时点的IRF向量 boot_irf_func <- function(data, indices) { # 1. 用抽样后的子集构建新数据 boot_data <- data[indices, ] # 2. 重新估计VAR模型 boot_gkvar <- VAR(boot_data[, var_vars], p = 12, type = "const") # 3. 重新计算外部工具变量对应的冲击项 boot_shockcol <- externalinstrument(boot_gkvar, boot_data$ff4_tc, "gs1") # 4. 重新生成脉冲响应的MA表示 boot_ma <- Phi(boot_gkvar, 50) # 保持和你原代码一致的50期 boot_irfs <- apply(boot_ma, 3, function(x) x %*% boot_shockcol) # 5. 将IRF整理为一维向量(boot要求统计量是单个向量) # 顺序为:第1期4个变量 → 第2期4个变量 → ... → 第50期4个变量 as.vector(t(boot_irfs)) }
步骤3:运行自助抽样
注意这里传入的是原始数据GKdata,而不是已经计算好的irfs!因为每次自助都要模拟完整的模型估计误差:
# 设置随机种子保证结果可重复 set.seed(123) # 运行1000次自助抽样 boot_result <- boot(data = GKdata, statistic = boot_irf_func, R = 1000, stype = "i")
步骤4:提取并整理置信区间
boot_result$t里存储了1000次抽样得到的所有IRF值,我们可以循环提取每个变量每个时点的置信区间:
n_vars <- length(var_vars) n_periods <- 50 # 用列表存储每个变量的置信区间 boot_ci_list <- list() for (var_idx in 1:n_vars) { # 定位该变量对应的所有统计量索引(每4个元素取第var_idx个) var_indices <- seq(var_idx, n_vars * n_periods, by = n_vars) # 计算95%百分位数置信区间 var_ci <- apply(boot_result$t[, var_indices], 2, function(x) { quantile(x, c(0.025, 0.975)) }) # 整理为易读的数据框 boot_ci_list[[var_vars[var_idx]]] <- as.data.frame(t(var_ci)) colnames(boot_ci_list[[var_vars[var_idx]]]) <- c("lower_95", "upper_95") } # 查看logip变量的置信区间示例 head(boot_ci_list$logip)
关键补充说明
- 如果需要多种类型的置信区间(比如norm、basic、perc),可以用
boot.ci函数,但它一次只能处理单个统计量,所以需要循环每个IRF时点和变量单独计算。 - 自助抽样的次数
R可以根据你的计算资源调整,一般1000次足够,若追求更高精度可以加到2000次。
内容的提问来源于stack exchange,提问作者Rollo99




