📊 r_estout.R

R 语言 estout 风格回归表格导出工具 | 类似 Stata 的 estout/esttab 命令

# =============================================================================
# R 语言 estout 风格回归表格导出工具
# 类似 Stata 的 estout/esttab 命令,简单易用
# =============================================================================

# 安装包(首次使用需要)
# install.packages(c("modelsummary", "fixest", "broom", "dplyr"))

# -----------------------------------------------------------------------------
# 主函数:estout()
# -----------------------------------------------------------------------------
estout <- function(..., 
                   file = NULL,
                   format = c("markdown", "latex", "html", "word", "text"),
                   digits = 3,
                   stars = TRUE,
                   star_levels = c(0.1, 0.05, 0.01),
                   star_symbols = c("*", "**", "***"),
                   coef_format = "f{digits}",
                   stat_names = c("se", "t", "p"),
                   add_stats = NULL,
                   title = NULL,
                   notes = NULL,
                   width = 80,
                   output = "console") {
  
  # 加载包
  if (!requireNamespace("modelsummary", quietly = TRUE)) {
    stop("请先安装 modelsummary 包:install.packages('modelsummary')")
  }
  
  format <- match.arg(format)
  
  # 收集模型
  models <- list(...)
  if (length(models) == 0) {
    stop("请至少提供一个模型对象")
  }
  
  # 构建 star 参数
  stars_param <- paste0(star_symbols, collapse = "")
  
  # 构建输出格式
  fmt <- paste0(coef_format, " ", stars_param)
  
  # 调用 modelsummary
  result <- modelsummary::modelsummary(
    models,
    output = if (is.null(file)) "return" else file,
    fmt = fmt,
    statistic = stat_names,
    stars = if (stars) star_levels else NULL,
    title = title,
    notes = notes,
    add_columns = add_stats,
    ...
  )
  
  return(result)
}

# -----------------------------------------------------------------------------
# 简化版本:esttab() - 更像 Stata esttab 的语法
# -----------------------------------------------------------------------------
esttab <- function(..., 
                   using = NULL,
                   replace = TRUE,
                   b = 3,      # 系数小数位
                   se = 3,     # 标准误小数位
                   star = c("*" = 0.1, "**" = 0.05, "***" = 0.01),
                   r2 = TRUE,  # 显示 R²
                   ar2 = FALSE,# 显示调整 R²
                   N = TRUE,   # 显示样本量
                   mtitle = NULL,
                   title = NULL,
                   notes = NULL,
                   booktabs = TRUE,
                   style = "markdown") {
  
  if (!requireNamespace("modelsummary", quietly = TRUE)) {
    stop("请先安装 modelsummary 包:install.packages('modelsummary')")
  }
  
  models <- list(...)
  if (length(models) == 0) stop("请至少提供一个模型对象")
  
  # 构建统计量
  stats <- c()
  if (r2) stats <- c(stats, "r.squared")
  if (ar2) stats <- c(stats, "adj.r.squared")
  if (N) stats <- c(stats, "nobs")
  
  # 输出
  output <- if (is.null(using)) "return" else using
  
  result <- modelsummary::modelsummary(
    models,
    output = output,
    fmt = paste0(b, " + ", se, " stars"),
    stars = star,
    statistic = "se",
    gof_map = stats,
    title = title,
    notes = notes,
    ...
  )
  
  return(result)
}

# -----------------------------------------------------------------------------
# 使用示例
# -----------------------------------------------------------------------------
# 示例数据
data(mtcars)

# 拟合多个模型
model1 <- lm(mpg ~ wt, data = mtcars)
model2 <- lm(mpg ~ wt + hp, data = mtcars)
model3 <- lm(mpg ~ wt + hp + cyl, data = mtcars)

# 方法 1: 简单输出到控制台
estout(model1, model2, model3)

# 方法 2: 输出到文件
estout(model1, model2, model3, 
       file = "regression_table.md",
       format = "markdown")

# 方法 3: esttab 风格
esttab(model1, model2, model3,
       using = "table.rtf",
       r2 = TRUE, N = TRUE)

# 方法 4: 自定义格式
estout(model1, model2,
       stars = TRUE,
       digits = 4,
       title = "回归分析结果",
       notes = "标准误括号内; * p<0.1, ** p<0.05, *** p<0.01")

cat("✓ estout 工具已加载!\n")
cat("使用方法:estout(model1, model2, file='table.md', format='markdown')\n")