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.
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.
# --- 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 ...
# 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
}
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
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)
}
deudaext vs resultadodeudanac 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.")
}
write.csv(resumen, "resumen_basicos.csv", row.names = TRUE)