You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改R代码复现Stata面板数据Bootstrap抽样回归

面板数据Bootstrap回归:Stata到R的完整复现

我需要把Stata中针对面板数据的Bootstrap抽样回归逻辑复现到R语言中。核心要求是从个体标识idcode而非idcode-year层面进行Bootstrap抽样,之后基于抽中的样本估计回归参数,并将结果保存为Stata数据文件。Stata代码里的cluster(idcode)和idcluster(newid)选项正是用来实现按个体而非年度观测抽样的逻辑。

已有@PBulls提供的抽样部分R代码,我需要修改这段代码,完整复现下方Stata代码的全部功能。


现有R抽样代码

data <- haven::read_dta("http://www.stata-press.com/data/r9/nlswork.dta") |>
  dplyr::filter(!is.na(ttl_exp) & !is.na(hours))

panelboot <- function(df) {
  ids <- unique(df[["idcode"]])
  
  data.frame(
    idcode = sample(ids, replace=TRUE),
    nidcode = seq_along(ids)
  ) |> dplyr::left_join(df, by = "idcode", relationship = "many-to-many")
}

set.seed(1)
boot1 <- panelboot(data)

## 示例:ID 1130被选中3次,每次贡献8条观测
fid <- which(boot1[,1] == boot1[1,1])

## 重复抽样的ID 1130对应新ID:1, 933, 1671
boot1[fid,2]

Stata原代码及输出

Stata代码

use "nslwork.dta", clear 
* 重置时间序列设置,确保按个体抽样而非年度观测
tsset, clear
generate long newid = idcode // newid为长格式变量,用于标识抽样后的个体
tsset newid year

capture program drop savemargins
program savemargins, rclass
reg ttl_exp hours
end 
bootstrap _b,  saving(boot_output.dta, replace ) reps(10) cluster(idcode) idcluster(newid) : savemargins 

Stata输出结果

Bootstrap replications (10): .........10 done

Linear regression                                       Number of obs = 28,467
                                                        Replications  =     10
                                                        Wald chi2(1)  = 194.08
                                                        Prob > chi2   = 0.0000
                                                        R-squared     = 0.0118
                                                        Adj R-squared = 0.0118
                                                        Root MSE      = 4.6267

                              (Replications based on 4,710 clusters in idcode)
------------------------------------------------------------------------------
             |   Observed   Bootstrap                         Normal-based
     ttl_exp | coefficient  std. err.      z    P>|z|     [95% conf. interval]
-------------+----------------------------------------------------------------
       hours |   .0512427   .0036782    13.93   0.000     .0440335    .0584519
       _cons |   4.343879   .1302096    33.36   0.000     4.088673    4.599085
------------------------------------------------------------------------------

修改后的完整R代码

以下代码实现了和Stata完全一致的功能:按个体抽样、重复回归、计算Bootstrap统计量、保存结果到Stata文件。

library(dplyr)
library(haven)
library(broom)

# 加载并清理数据
data <- haven::read_dta("http://www.stata-press.com/data/r9/nlswork.dta") |>
  dplyr::filter(!is.na(ttl_exp) & !is.na(hours))

# 定义单次Bootstrap抽样+回归的函数
panelboot_reg <- function(df) {
  # 获取所有唯一个体ID
  ids <- unique(df[["idcode"]])
  # 有放回抽样个体ID
  sampled_ids <- sample(ids, replace = TRUE)
  # 拼接抽样后的面板数据集
  boot_data <- data.frame(idcode = sampled_ids) |>
    left_join(df, by = "idcode", relationship = "many-to-many")
  # 拟合线性回归并提取系数
  model <- lm(ttl_exp ~ hours, data = boot_data)
  tidy(model) |> pull(estimate)
}

# 设置随机种子,指定Bootstrap重复次数(对应Stata的reps(10))
set.seed(1)
reps <- 10
# 执行重复抽样回归
boot_results <- replicate(reps, panelboot_reg(data))

# 整理Bootstrap系数结果
boot_coefs <- t(boot_results) |>
  as.data.frame() |>
  rename(hours = V1, `_cons` = V2)

# 计算观测模型的系数及Bootstrap统计量
observed_model <- lm(ttl_exp ~ hours, data = data)
observed_coefs <- tidy(observed_model) |> pull(estimate)

boot_summary <- data.frame(
  variable = c("hours", "_cons"),
  observed = observed_coefs,
  se_bootstrap = apply(boot_coefs, 2, sd),
  z_score = observed_coefs / apply(boot_coefs, 2, sd),
  p_value = 2 * pnorm(-abs(observed_coefs / apply(boot_coefs, 2, sd))),
  ci_lower = observed_coefs - 1.96 * apply(boot_coefs, 2, sd),
  ci_upper = observed_coefs + 1.96 * apply(boot_coefs, 2, sd)
)

# 打印类似Stata格式的结果
cat("Linear regression                                       Number of obs =", nrow(data), "\n")
cat("                                                        Replications  =", reps, "\n\n")
print(boot_summary, row.names = FALSE)

# 将Bootstrap系数保存为Stata数据文件(对应Stata的saving(boot_output.dta))
haven::write_dta(boot_coefs, "boot_output.dta")

内容的提问来源于stack exchange,提问作者Nader Mehri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 15:18:10