1 Objetivo

Calcular media, mediana, moda, desvío estándar y coeficiente de variación para todas las columnas numéricas y producir gráficos: - Univariados (histograma + densidad) para algunas variables continuas. - Dispersión con suavizado LOESS para deudaext vs resultado y deudanac vs resultado.

El enfoque usa muy pocos paquetes y código simple, pensado para clase.


2 Paquetes

Instalamos y cargamos solo lo necesario.

need <- c("ggplot2")
to_install <- setdiff(need, rownames(installed.packages()))
if (length(to_install)) install.packages(to_install, dependencies = TRUE)
library(ggplot2)

# Si vas a leer desde Excel, se usará readxl automáticamente si es necesario.

3 Cargar/Seleccionar la base

# --- Carga robusta de datos: .xlsx/.xls/.xlsm o .csv/.txt con encoding ---
get_df <- function() {
  # 0) ¿Ya existe en memoria con algunos nombres conocidos?
  if (exists("X1996_2002_valores_nominales_4_")) return(get("X1996_2002_valores_nominales_4_"))
  if (exists("X1996_2002_valores_nominales_5_")) return(get("X1996_2002_valores_nominales_5_"))

  # 1) Buscar automáticamente archivos candidatos en el working directory
  cand <- c(
    "X1996_2002_valores_nominales_4_.xlsx",
    "X1996_2002_valores_nominales_5_.xlsx",
    "X1996_2002_valores_nominales_4_.xls",
    "X1996_2002_valores_nominales_5_.xls",
    "X1996_2002_valores_nominales_4_.csv",
    "X1996_2002_valores_nominales_5_.csv",
    "X1996_2002_valores_nominales_4_.txt",
    "X1996_2002_valores_nominales_5_.txt"
  )
  cand <- cand[file.exists(cand)]

  # 2) Elegir archivo: si no hay candidatos, abrir diálogo
  f <- if (length(cand) >= 1) cand[1] else {
    message("Seleccione el archivo de datos (.xlsx/.xls/.xlsm o .csv/.txt)…")
    file.choose(new = FALSE)
  }
  message("Leyendo: ", f)

  # 3) Leer según la extensión
  ext <- tolower(tools::file_ext(f))

  # Excel: .xlsx / .xls / .xlsm
  if (ext %in% c("xlsx","xls","xlsm")) {
    if (!requireNamespace("readxl", quietly = TRUE)) install.packages("readxl")
    df <- readxl::read_excel(f)
    return(df)
  }

  # Texto/CSV: .csv / .txt — probar separador y encoding
  if (ext %in% c("csv","txt")) {
    # funciones de lectura candidatas
    readers <- list(
      function(ff, enc) utils::read.csv(ff, fileEncoding = enc, check.names = FALSE),
      function(ff, enc) utils::read.csv2(ff, fileEncoding = enc, check.names = FALSE)
    )
    encodings <- c("UTF-8", "latin1", "windows-1252", "ISO-8859-1")

    for (enc in encodings) {
      for (rd in readers) {
        out <- try(rd(f, enc), silent = TRUE)
        if (!inherits(out, "try-error")) {
          message("OK con encoding=", enc, " (", if (identical(rd, readers[[1]])) "read.csv" else "read.csv2", ")")
          return(out)
        }
      }
    }
    stop("No se pudo leer el archivo de texto con los encodings probados.")
  }

  stop("Extensión de archivo no soportada: ", ext)
}

df <- get_df()

# Asegurar nombres de columnas válidos (por si vienen con caracteres raros)
names(df) <- make.names(names(df), allow_ = TRUE)

# Vista rápida
str(df)
## tibble [168 × 8] (S3: tbl_df/tbl/data.frame)
##  $ Provincias         : chr [1:168] "Buenos Aires" "CABA" "Catamarca" "Chaco" ...
##  $ año                : num [1:168] 1996 1996 1996 1996 1996 ...
##  $ reestructuracion   : num [1:168] 1 0 1 1 1 1 1 1 1 1 ...
##  $ resultado          : num [1:168] -290927 139269 -56502 -45543 -94511 ...
##  $ deudanac           : num [1:168] 1112753 1642020 154029 345047 89683 ...
##  $ deudaext           : num [1:168] 1887658 496080 110441 177188 181164 ...
##  $ deseq..vertical    : num [1:168] 0.4536 0.0821 0.8961 0.8435 0.633 ...
##  $ Bancos.privatizados: num [1:168] 0 0 1 0 0 0 0 1 1 1 ...

4 Funciones auxiliares (simples)

# Moda "estadística" (el valor más frecuente). Si hay empate, devuelve el primero.
modo <- function(x) {
  x <- x[!is.na(x)]
  if (length(x) == 0) return(NA)
  ux <- unique(x)
  ux[which.max(tabulate(match(x, ux)))]
}

# Coeficiente de variación en %
cv_pct <- function(x) {
  x <- x[!is.na(x)]
  m <- mean(x)
  if (is.na(m) || m == 0) return(NA_real_)
  100 * sd(x) / m
}

5 Estadísticos básicos (todas las numéricas)

nums <- sapply(df, is.numeric)
if (!any(nums)) stop("No se encontraron columnas numéricas en df.")

var_numericas <- names(df)[nums]

resumen <- t(sapply(df[ , nums, drop = FALSE], function(x) {
  c(
    n       = sum(!is.na(x)),
    media   = mean(x, na.rm = TRUE),
    mediana = median(x, na.rm = TRUE),
    moda    = suppressWarnings(modo(x)),   # puede ser no entero si es continuo
    sd      = sd(x, na.rm = TRUE),
    cv_pct  = cv_pct(x)
  )
}))

resumen <- as.data.frame(resumen)
# Redondeo “amigable” para clase
resumen$media   <- round(resumen$media,   3)
resumen$mediana <- round(resumen$mediana, 3)
resumen$moda    <- round(resumen$moda,    3)
resumen$sd      <- round(resumen$sd,      3)
resumen$cv_pct  <- round(resumen$cv_pct,  2)

cat("\n=== Estadísticos básicos por variable (numéricas) ===\n")
## 
## === Estadísticos básicos por variable (numéricas) ===
resumen
##                       n      media    mediana        moda          sd  cv_pct
## año                 168   1999.000   1999.000    1996.000       2.006    0.10
## reestructuracion    168      0.750      1.000       1.000       0.434   57.91
## resultado           168 -47677.607 -11057.000 -290927.000  294430.175 -617.54
## deudanac            168 571047.750 233897.500   51146.000 1893225.544  331.54
## deudaext            168 477861.452 298199.000 1887658.000  848091.484  177.48
## deseq..vertical     168      0.669      0.692       0.454       0.200   29.96
## Bancos.privatizados 168      0.583      1.000       1.000       0.494   84.77

6 Gráficos univariados (histograma + densidad)

Se generan para algunas variables de interés (editá la lista vars_univariadas).
Tip: Si una variable tiene muchos ceros o pocos valores distintos, la densidad puede verse “chata” — es normal.

vars_univariadas <- intersect(var_numericas, c("resultado", "deudaext", "deudanac"))

for (v in vars_univariadas) {
  x <- df[[v]]
  d <- data.frame(val = x)

  # Histograma con densidad suavizada
  p_hist <- ggplot(d, aes(x = val)) +
    geom_histogram(aes(y = after_stat(density)), bins = 30,
                   fill = "#6BAED6", color = "white", alpha = 0.9) +
    geom_density(linewidth = 1.2, color = "#08519C", alpha = 0.9) +
    labs(title = paste("Distribución de", v),
         x = v, y = "Densidad") +
    theme_minimal(base_size = 12)
  print(p_hist)

  # Solo densidad (suavizado)
  p_dens <- ggplot(d, aes(x = val)) +
    geom_density(fill = "#9ECAE1", alpha = 0.7, linewidth = 1.1, color = "#08519C") +
    labs(title = paste("Densidad suavizada de", v),
         x = v, y = "Densidad") +
    theme_minimal(base_size = 12)
  print(p_dens)
}


7 Dispersión con suavizado

  • deudaext vs resultado
  • deudanac vs resultado
# a) deuda externa vs resultado
if (all(c("deudaext", "resultado") %in% names(df))) {
  p_sc1 <- ggplot(df, aes(x = deudaext, y = resultado)) +
    geom_point(size = 2.2, alpha = 0.75, color = "#2B8CBE") +
    geom_smooth(method = "loess", se = TRUE, linewidth = 1.1, color = "#045A8D") +
    labs(title = "deuda externa vs resultado",
         x = "deuda externa (deudaext)",
         y = "resultado") +
    theme_minimal(base_size = 12)
  print(p_sc1)
} else {
  message("Nota: No se encontró alguna de las columnas: deudaext, resultado.")
}

# b) deuda en moneda nacional vs resultado (asumo columna 'deudanac')
if (all(c("deudanac", "resultado") %in% names(df))) {
  p_sc2 <- ggplot(df, aes(x = deudanac, y = resultado)) +
    geom_point(size = 2.2, alpha = 0.75, color = "#31A354") +
    geom_smooth(method = "loess", se = TRUE, linewidth = 1.1, color = "#006D2C") +
    labs(title = "deuda en moneda nacional vs resultado",
         x = "deuda en moneda nacional (deudanac)",
         y = "resultado") +
    theme_minimal(base_size = 12)
  print(p_sc2)
} else {
  message("Nota: No se encontró alguna de las columnas: deudanac, resultado.")
}


8 (Opcional) Exportar tabla de estadísticos

write.csv(resumen, "resumen_basicos.csv", row.names = TRUE)