← Catálogo · Capítulo 3

T03_CP02_mECO_Tobit_Donaciones.R

Ver crudo
# =============================================================================
# TEMA 03 — CP2: Modelo Tobit — Donaciones Benéficas Anuales
# =============================================================================
# Manual de Microeconometría — Carlos de Anta Puig
# Profesor de Econometría y Microeconometría — UNIR
# https://github.com/carlanta/MicroEconometrics  Versión 1.0 — 2026
#
# OBJETIVO: Analizar los determinantes de las donaciones benéficas con Tobit.
#           El 46.4% de la muestra no dona nada (censura en 0).
# INSTRUCCIONES: Session > Set Working Directory > To Source File Location
# =============================================================================

pausa <- function(msg="\n>>> Pulsa ENTER para continuar...") {
  if (interactive()) readline(msg) else Sys.sleep(0.5)
}
pkgs <- c("AER","lmtest")
for (p in pkgs) if (!requireNamespace(p,quietly=TRUE)) install.packages(p,quiet=TRUE)
suppressPackageStartupMessages({ library(AER); library(lmtest) })
.get_script_dir <- function() {
  args <- commandArgs(trailingOnly = FALSE)
  for (a in args) {
    if (startsWith(a, "--file=")) return(dirname(normalizePath(substring(a, 8))))
  }
  for (i in seq_len(sys.nframe())) {
    ofile <- tryCatch(sys.frame(i)$ofile, error = function(e) NULL)
    if (!is.null(ofile)) return(dirname(normalizePath(ofile)))
  }
  return(normalizePath("."))
}
.sdir <- .get_script_dir()
DATA_DIR <- normalizePath(file.path(.sdir, "..", "data"), mustWork=FALSE)

cat("\n================================================================\n")
cat("  CP02 — Donaciones Benéficas: Modelo Tobit\n")
cat("================================================================\n\n")

load(file.path(DATA_DIR,"T03_CP02_donaciones.RData"))
cat("Dataset:", nrow(donaciones), "obs. |", ncol(donaciones), "variables\n")
n_d <- sum(donaciones$donacion==0)
cat(sprintf("  Ceros: %d (%.1f%%) | Media positivos: %.1f€\n\n",
            n_d, 100*n_d/nrow(donaciones),
            mean(donaciones$donacion[donaciones$donacion>0])))

cat("--- EDA RÁPIDA: medias por grupos ---\n\n")
for (v in c("ingreso","edad","religiosidad","educacion")) {
  m0 <- mean(donaciones[[v]][donaciones$donacion==0])
  m1 <- mean(donaciones[[v]][donaciones$donacion>0])
  cat(sprintf("  %-15s | No dona: %5.2f | Dona: %5.2f | Dif: %+.2f\n",
              v, m0, m1, m1-m0))
}
cat(sprintf("  %-15s | No dona: %4.1f%%  | Dona: %4.1f%%\n",
            "% con hijos",
            100*mean(donaciones$tiene_hijos[donaciones$donacion==0]),
            100*mean(donaciones$tiene_hijos[donaciones$donacion>0])))

pausa()

cat("\n--- ESTIMACIÓN MCO vs TOBIT ---\n\n")
fml_d <- donacion ~ ingreso + edad + religiosidad + educacion + tiene_hijos + sexo
mco_d <- lm(fml_d, data=donaciones)
tob_d <- AER::tobit(fml_d, left=0, data=donaciones)

ct_d  <- coef(summary(tob_d))
vars_d <- c("ingreso","edad","religiosidad","educacion","tiene_hijos","sexo")
cat("  Variable       | MCO     | Tobit   | Ratio\n")
cat("  -----------------------------------------------\n")
for (v in vars_d) {
  sig <- ifelse(ct_d[v,4]<0.001,"***",ifelse(ct_d[v,4]<0.01,"**",
               ifelse(ct_d[v,4]<0.05,"*","   ")))
  cat(sprintf("  %-14s | %7.3f | %7.3f %s | %.2f\n", v,
              coef(mco_d)[v], coef(tob_d)[v], sig,
              coef(tob_d)[v]/coef(mco_d)[v]))
}
cat(sprintf("  sigma:          | %-7s | %7.3f\n", "—", tob_d$scale))

pausa()

cat("\n--- EFECTOS MARGINALES AME ---\n\n")
beta_d <- coef(tob_d); sig_d <- tob_d$scale
xb_d   <- predict(tob_d, newdata=donaciones, type="lp")
z_d    <- xb_d / sig_d
Phi_d  <- pnorm(z_d); imr_d <- dnorm(z_d)/Phi_d

ame_d    <- mean(Phi_d) * beta_d[vars_d]
ame_cond <- mean(1-as.numeric(z_d)*as.numeric(imr_d)-as.numeric(imr_d)^2) * beta_d[vars_d]

cat("  Variable       | AME E[y|x]  | AME E[y|y>0]\n")
cat("  ---------------------------------------------------\n")
for (v in vars_d) {
  cat(sprintf("  %-14s | %+10.3f  | %+10.3f\n", v, ame_d[v], ame_cond[v]))
}

cat("\n▶ INTERPRETACIÓN CLAVE:\n")
cat(sprintf("  · Religiosidad: el predictor más potente (AME=%.2f€/año).\n",
            ame_d["religiosidad"]))
cat("    Un punto más en el índice 0-5 aumenta la donación esperada\n")
cat(sprintf("    en %.2f€ por año. El efecto es muy superior al del ingreso.\n",
            ame_d["religiosidad"]))
cat(sprintf("  · Ingreso: AME=%.2f€/año por cada €1.000 adicionales.\n",
            ame_d["ingreso"]))
cat(sprintf("  · Hijos: tener hijos REDUCE la donación en %.2f€/año. Las\n",
            abs(ame_d["tiene_hijos"])))
cat("    cargas familiares desplazan el gasto discrecional en donaciones.\n")

pausa()

cat("\n--- BONDAD DEL AJUSTE ---\n\n")
ll_0 <- as.numeric(logLik(glm(as.integer(donacion>0)~1, family=binomial, data=donaciones))) * 0
ll_n  <- as.numeric(logLik(AER::tobit(donacion~1, left=0, data=donaciones)))
ll_m  <- as.numeric(logLik(tob_d))
r2_mf <- 1 - ll_m/ll_n
lr_st <- -2*(ll_n - ll_m)
cat(sprintf("  Log-verosimilitud nulo:    %.2f\n", ll_n))
cat(sprintf("  Log-verosimilitud modelo:  %.2f\n", ll_m))
cat(sprintf("  McFadden R²:               %.4f\n", r2_mf))
cat(sprintf("  Test LR (vs nulo):         %.2f (p < 0.001)\n", lr_st))
cat(sprintf("  AIC:                       %.2f\n", AIC(tob_d)))

cat("\n================================================================\n")
cat("  FIN DEL SCRIPT T03_CP02_mECO_Tobit_Donaciones.R\n")
cat("================================================================\n\n")