freq_nivel <- table(datos$NivelEducativo)
prop_nivel <- prop.table(freq_nivel) * 100
tabla_nivel <- data.frame(
NivelEducativo = names(freq_nivel),
Frecuencia_Absoluta = as.numeric(freq_nivel),
Frecuencia_Relativa = round(as.numeric(prop_nivel), 2),
Frecuencia_Acumulada = cumsum(as.numeric(freq_nivel)),
Porcentaje_Acumulado = round(cumsum(as.numeric(prop_nivel)), 2)
)
kable(tabla_nivel,
caption = "Tabla 1: Distribución de Frecuencias - Nivel Educativo",
col.names = c("Nivel Educativo", "f", "%", "F", "% Acumulado"),
align = c('l', 'c', 'c', 'c', 'c'))
Nivel Educativo | f | % | F | % Acumulado |
---|---|---|---|---|
Primaria | 229 | 22.9 | 229 | 22.9 |
Secundaria | 288 | 28.8 | 517 | 51.7 |
Técnico | 231 | 23.1 | 748 | 74.8 |
Universitario | 252 | 25.2 | 1000 | 100.0 |
Análisis interpretativo: La distribución del nivel educativo muestra la estructura formativa de la muestra.
ggplot(tabla_nivel, aes(x = reorder(NivelEducativo, -Frecuencia_Absoluta),
y = Frecuencia_Absoluta, fill = NivelEducativo)) +
geom_bar(stat = "identity", alpha = 0.85, color = "black", size = 0.3) +
geom_text(aes(label = paste0(Frecuencia_Absoluta, "\n(", Frecuencia_Relativa, "%)")),
vjust = -0.3, size = 3.5, fontface = "bold") +
labs(title = "Distribución de la Muestra por Nivel Educativo",
subtitle = paste0("n = ", nrow(datos), " observaciones"),
x = "Nivel Educativo Alcanzado", y = "Frecuencia Absoluta") +
scale_fill_brewer(palette = "Set3") +
theme_minimal(base_size = 12) +
theme(legend.position = "none",
axis.text.x = element_text(angle = 45, hjust = 1, face = "bold"),
plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
plot.subtitle = element_text(hjust = 0.5, size = 10),
panel.grid.major.x = element_blank())
Figura 1: Distribución de la muestra según nivel educativo
freq_genero <- table(datos$Genero)
prop_genero <- prop.table(freq_genero) * 100
tabla_genero <- data.frame(
Genero = names(freq_genero),
Frecuencia = as.numeric(freq_genero),
Porcentaje = round(as.numeric(prop_genero), 2)
)
kable(tabla_genero,
caption = "Tabla 2: Distribución de Frecuencias - Género",
col.names = c("Género", "Frecuencia Absoluta", "Porcentaje (%)"),
align = c('l', 'c', 'c'))
Género | Frecuencia Absoluta | Porcentaje (%) |
---|---|---|
Femenino | 306 | 30.6 |
Masculino | 339 | 33.9 |
Otro | 355 | 35.5 |
entropia <- -sum((prop_genero/100) * log(prop_genero/100), na.rm = TRUE)
cat("\nÍndice de diversidad (Entropía):", round(entropia, 3), "\n")
##
## Índice de diversidad (Entropía): 1.097
ggplot(tabla_genero, aes(x = "", y = Porcentaje, fill = Genero)) +
geom_bar(stat = "identity", width = 1, color = "white", size = 1) +
coord_polar("y", start = 0) +
geom_text(aes(label = paste0(Genero, "\n", Porcentaje, "%")),
position = position_stack(vjust = 0.5), size = 4, fontface = "bold") +
labs(title = "Composición de la Muestra por Género",
subtitle = paste0("Total: ", nrow(datos), " individuos")) +
scale_fill_brewer(palette = "Pastel1") +
theme_void() +
theme(plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
plot.subtitle = element_text(hjust = 0.5, size = 10),
legend.position = "bottom")
Figura 2: Composición porcentual según género
media_edad <- mean(datos$Edad, na.rm = TRUE)
mediana_edad <- median(datos$Edad, na.rm = TRUE)
moda_edad <- as.numeric(names(sort(table(datos$Edad), decreasing = TRUE)[1]))
desv_edad <- sd(datos$Edad, na.rm = TRUE)
varianza_edad <- var(datos$Edad, na.rm = TRUE)
cv_edad <- (desv_edad / media_edad) * 100
rango_edad <- max(datos$Edad, na.rm = TRUE) - min(datos$Edad, na.rm = TRUE)
cuartiles <- quantile(datos$Edad, probs = c(0.25, 0.5, 0.75), na.rm = TRUE)
iqr_edad <- IQR(datos$Edad, na.rm = TRUE)
asimetria <- skewness(datos$Edad, na.rm = TRUE)
curtosis <- kurtosis(datos$Edad, na.rm = TRUE)
estadisticos_edad <- data.frame(
Medida = c("Media aritmética (μ)", "Mediana (Me)", "Moda (Mo)",
"Desviación estándar (σ)", "Varianza (σ²)",
"Coeficiente de variación (CV)", "Rango",
"Q1 (Percentil 25)", "Q3 (Percentil 75)",
"Rango intercuartílico (IQR)",
"Coeficiente de asimetría", "Coeficiente de curtosis"),
Valor = c(round(media_edad, 2), mediana_edad, moda_edad,
round(desv_edad, 2), round(varianza_edad, 2),
paste0(round(cv_edad, 2), "%"), rango_edad,
cuartiles[1], cuartiles[3], round(iqr_edad, 2),
round(asimetria, 3), round(curtosis, 3))
)
kable(estadisticos_edad,
caption = "Tabla 3: Estadísticos Descriptivos Completos - Variable Edad",
align = c('l', 'c'))
Medida | Valor |
---|---|
Media aritmética (μ) | 41.53 |
Mediana (Me) | 41 |
Moda (Mo) | 37 |
Desviación estándar (σ) | 13.72 |
Varianza (σ²) | 188.3 |
Coeficiente de variación (CV) | 33.04% |
Rango | 47 |
Q1 (Percentil 25) | 30 |
Q3 (Percentil 75) | 53 |
Rango intercuartílico (IQR) | 23 |
Coeficiente de asimetría | -0.016 |
Coeficiente de curtosis | 1.858 |
Interpretación:
mas_3_hermanos <- sum(datos$Hermanos > 3, na.rm = TRUE)
prop_mas_3 <- (mas_3_hermanos / nrow(datos)) * 100
freq_hermanos <- table(datos$Hermanos)
prop_hermanos <- prop.table(freq_hermanos) * 100
tabla_hermanos <- data.frame(
Hermanos = names(freq_hermanos),
Frecuencia = as.numeric(freq_hermanos),
Porcentaje = round(as.numeric(prop_hermanos), 2),
Acumulado = round(cumsum(as.numeric(prop_hermanos)), 2)
)
kable(tabla_hermanos,
caption = "Tabla 4: Distribución de Frecuencias - Número de Hermanos",
align = c('c', 'c', 'c', 'c'))
Hermanos | Frecuencia | Porcentaje | Acumulado |
---|---|---|---|
0 | 161 | 16.1 | 16.1 |
1 | 143 | 14.3 | 30.4 |
2 | 128 | 12.8 | 43.2 |
3 | 138 | 13.8 | 57.0 |
4 | 138 | 13.8 | 70.8 |
5 | 138 | 13.8 | 84.6 |
6 | 154 | 15.4 | 100.0 |
##
## ANÁLISIS: FAMILIAS NUMEROSAS
## Individuos con más de 3 hermanos: 430
## Proporción: 43 %
ic_hermanos <- prop.test(mas_3_hermanos, nrow(datos))$conf.int
cat("IC 95%: [", round(ic_hermanos[1]*100, 2), "%, ",
round(ic_hermanos[2]*100, 2), "%]\n")
## IC 95%: [ 39.91 %, 46.14 %]
ggplot(tabla_hermanos, aes(x = Hermanos, y = Frecuencia, fill = Hermanos)) +
geom_bar(stat = "identity", alpha = 0.85, color = "black", size = 0.3) +
geom_hline(yintercept = mean(tabla_hermanos$Frecuencia),
linetype = "dashed", color = "red", size = 0.8) +
geom_text(aes(label = Frecuencia), vjust = -0.5, size = 3.5, fontface = "bold") +
labs(title = "Distribución del Número de Hermanos",
subtitle = "Línea roja = frecuencia media",
x = "Número de Hermanos", y = "Frecuencia Absoluta") +
scale_fill_brewer(palette = "YlOrRd") +
theme_minimal(base_size = 12) +
theme(legend.position = "none",
plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
plot.subtitle = element_text(hjust = 0.5, size = 10))
Figura 3: Distribución del número de hermanos
Conclusión: El 43% proviene de familias numerosas (>3 hermanos).
min_ingreso <- min(datos$IngresoMensual, na.rm = TRUE)
max_ingreso <- max(datos$IngresoMensual, na.rm = TRUE)
rango_ingreso <- max_ingreso - min_ingreso
media_ingreso <- mean(datos$IngresoMensual, na.rm = TRUE)
mediana_ingreso <- median(datos$IngresoMensual, na.rm = TRUE)
varianza_ingreso <- var(datos$IngresoMensual, na.rm = TRUE)
desv_ingreso <- sd(datos$IngresoMensual, na.rm = TRUE)
cv_ingreso <- (desv_ingreso / media_ingreso) * 100
error_estandar <- desv_ingreso / sqrt(nrow(datos))
ic_inferior <- media_ingreso - qt(0.975, nrow(datos)-1) * error_estandar
ic_superior <- media_ingreso + qt(0.975, nrow(datos)-1) * error_estandar
estadisticos_ingreso <- data.frame(
Medida = c("Valor mínimo", "Valor máximo", "Rango",
"Media (μ)", "Mediana", "Varianza (σ²)",
"Desviación estándar (σ)", "Coeficiente de variación (CV)",
"Error estándar (SE)", "IC 95% - Límite inferior",
"IC 95% - Límite superior"),
Valor = c(round(min_ingreso, 2), round(max_ingreso, 2),
round(rango_ingreso, 2), round(media_ingreso, 2),
round(mediana_ingreso, 2), round(varianza_ingreso, 2),
round(desv_ingreso, 2), paste0(round(cv_ingreso, 2), "%"),
round(error_estandar, 2), round(ic_inferior, 2),
round(ic_superior, 2))
)
kable(estadisticos_ingreso,
caption = "Tabla 5: Análisis Estadístico - Ingreso Mensual ($)",
align = c('l', 'c'))
Medida | Valor |
---|---|
Valor mínimo | -509.91 |
Valor máximo | 4756.79 |
Rango | 5266.7 |
Media (μ) | 1975.18 |
Mediana | 1972.76 |
Varianza (σ²) | 631117.32 |
Desviación estándar (σ) | 794.43 |
Coeficiente de variación (CV) | 40.22% |
Error estándar (SE) | 25.12 |
IC 95% - Límite inferior | 1925.88 |
IC 95% - Límite superior | 2024.47 |
Interpretación:
media_estatura <- mean(datos$Estatura, na.rm = TRUE)
desv_estatura <- sd(datos$Estatura, na.rm = TRUE)
ggplot(datos, aes(x = Estatura)) +
geom_histogram(aes(y = ..density..), bins = 35,
fill = "lightblue", color = "black", alpha = 0.7) +
geom_density(color = "darkblue", size = 1.2) +
stat_function(fun = dnorm,
args = list(mean = media_estatura, sd = desv_estatura),
color = "red", size = 1.2, linetype = "dashed") +
geom_vline(xintercept = media_estatura, color = "darkgreen",
linetype = "solid", size = 1) +
labs(title = "Distribución de la Estatura",
subtitle = paste0("Media = ", round(media_estatura, 2), " m | σ = ",
round(desv_estatura, 2), " m"),
x = "Estatura (metros)", y = "Densidad de probabilidad") +
theme_minimal(base_size = 12) +
theme(plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
plot.subtitle = element_text(hjust = 0.5, size = 10))
Figura 4: Distribución de Estatura
Análisis: Distribución aproximadamente simétrica y unimodal compatible con normalidad.
estatura_genero <- datos %>%
group_by(Genero) %>%
summarise(
n = n(),
Media = round(mean(Estatura, na.rm = TRUE), 3),
Mediana = round(median(Estatura, na.rm = TRUE), 3),
DE = round(sd(Estatura, na.rm = TRUE), 3),
CV = round((sd(Estatura, na.rm = TRUE) / mean(Estatura, na.rm = TRUE)) * 100, 2),
Mínimo = round(min(Estatura, na.rm = TRUE), 3),
Máximo = round(max(Estatura, na.rm = TRUE), 3)
) %>%
arrange(desc(Media))
kable(estatura_genero,
caption = "Tabla 6: Estadísticos de Estatura por Género",
align = c('l', rep('c', 7)))
Genero | n | Media | Mediana | DE | CV | Mínimo | Máximo |
---|---|---|---|---|---|---|---|
Otro | 355 | 1.758 | 1.760 | 0.141 | 8.00 | 1.5 | 2.00 |
Femenino | 306 | 1.746 | 1.745 | 0.143 | 8.18 | 1.5 | 1.99 |
Masculino | 339 | 1.740 | 1.730 | 0.148 | 8.51 | 1.5 | 2.00 |
p1 <- ggplot(datos, aes(x = Genero, y = Estatura, fill = Genero)) +
geom_boxplot(alpha = 0.7, outlier.color = "red", outlier.size = 2) +
stat_summary(fun = mean, geom = "point", shape = 23,
size = 4, fill = "darkred", color = "black") +
labs(title = "Distribución de Estatura por Género",
subtitle = "Diamante rojo = media", x = "Género", y = "Estatura (m)") +
scale_fill_brewer(palette = "Pastel2") +
theme_minimal() +
theme(legend.position = "none",
plot.title = element_text(hjust = 0.5, face = "bold"))
p2 <- ggplot(datos, aes(x = Genero, y = Estatura, fill = Genero)) +
geom_violin(alpha = 0.6, draw_quantiles = c(0.25, 0.5, 0.75)) +
geom_jitter(alpha = 0.2, width = 0.2, size = 0.5) +
labs(title = "Densidad de Distribución", x = "Género", y = "Estatura (m)") +
scale_fill_brewer(palette = "Set2") +
theme_minimal() +
theme(legend.position = "none",
plot.title = element_text(hjust = 0.5, face = "bold"))
grid.arrange(p1, p2, ncol = 2)
Figura 5: Análisis de estatura por género
ingreso_educacion <- datos %>%
group_by(NivelEducativo) %>%
summarise(
n = n(),
Media = round(mean(IngresoMensual, na.rm = TRUE), 2),
Mediana = round(median(IngresoMensual, na.rm = TRUE), 2),
DE = round(sd(IngresoMensual, na.rm = TRUE), 2),
CV = round((sd(IngresoMensual, na.rm = TRUE) /
mean(IngresoMensual, na.rm = TRUE)) * 100, 2),
Q1 = round(quantile(IngresoMensual, 0.25, na.rm = TRUE), 2),
Q3 = round(quantile(IngresoMensual, 0.75, na.rm = TRUE), 2)
) %>%
arrange(desc(Media))
kable(ingreso_educacion,
caption = "Tabla 7: Ingresos por Nivel Educativo",
align = c('l', rep('c', 7)))
NivelEducativo | n | Media | Mediana | DE | CV | Q1 | Q3 |
---|---|---|---|---|---|---|---|
Primaria | 229 | 2037.13 | 2080.04 | 825.58 | 40.53 | 1524.81 | 2528.15 |
Secundaria | 288 | 2012.24 | 1964.29 | 788.07 | 39.16 | 1435.94 | 2540.18 |
Universitario | 252 | 1948.15 | 1999.19 | 745.19 | 38.25 | 1394.87 | 2452.28 |
Técnico | 231 | 1897.03 | 1895.20 | 819.84 | 43.22 | 1411.60 | 2457.70 |
modelo_anova <- aov(IngresoMensual ~ NivelEducativo, data = datos)
cat("\nANÁLISIS DE VARIANZA (ANOVA)\n")
##
## ANÁLISIS DE VARIANZA (ANOVA)
## H0: Medias iguales | H1: Al menos una difiere
## Df Sum Sq Mean Sq F value Pr(>F)
## NivelEducativo 3 2869314 956438 1.518 0.208
## Residuals 996 627616890 630137
ggplot(datos, aes(x = reorder(NivelEducativo, IngresoMensual, FUN = median),
y = IngresoMensual, fill = NivelEducativo)) +
geom_boxplot(alpha = 0.7, outlier.colour = "red", outlier.size = 2) +
stat_summary(fun = mean, geom = "point", shape = 23,
size = 4, fill = "darkred", color = "black") +
labs(title = "Distribución de Ingresos por Nivel Educativo",
subtitle = "Ordenado por mediana | Diamante = media | Puntos rojos = outliers",
x = "Nivel Educativo", y = "Ingreso Mensual ($)") +
scale_fill_brewer(palette = "Spectral") +
scale_y_continuous(labels = dollar_format(prefix = "$")) +
theme_minimal(base_size = 12) +
theme(axis.text.x = element_text(angle = 45, hjust = 1, face = "bold"),
legend.position = "none",
plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
plot.subtitle = element_text(hjust = 0.5, size = 10))
Figura 6: Ingresos por nivel educativo
correlacion <- cor(datos$Edad, datos$IngresoMensual, use = "complete.obs")
modelo_regresion <- lm(IngresoMensual ~ Edad, data = datos)
r_cuadrado <- summary(modelo_regresion)$r.squared
ggplot(datos, aes(x = Edad, y = IngresoMensual)) +
geom_point(alpha = 0.4, color = "darkblue", size = 2) +
geom_smooth(method = "lm", se = TRUE, color = "red", fill = "pink",
alpha = 0.3, size = 1.2) +
annotate("text", x = max(datos$Edad) - 5, y = max(datos$IngresoMensual) - 500,
label = paste0("r = ", round(correlacion, 3), "\nR² = ",
round(r_cuadrado, 3)),
size = 5, fontface = "bold", color = "darkred") +
labs(title = "Relación entre Edad e Ingreso Mensual",
subtitle = "Línea roja = modelo ajustado | Área sombreada = IC 95%",
x = "Edad (años)", y = "Ingreso Mensual ($)") +
scale_y_continuous(labels = dollar_format(prefix = "$")) +
theme_minimal(base_size = 12) +
theme(plot.title = element_text(hjust = 0.5, face = "bold", size = 14),
plot.subtitle = element_text(hjust = 0.5, size = 10))
Figura 7: Relación Edad-Ingreso
##
## REGRESIÓN LINEAL
##
## Call:
## lm(formula = IngresoMensual ~ Edad, data = datos)
##
## Residuals:
## Min 1Q Median 3Q Max
## -2498.1 -533.7 0.9 528.2 2736.4
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1891.617 80.102 23.615 <2e-16 ***
## Edad 2.012 1.831 1.099 0.272
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 794.3 on 998 degrees of freedom
## Multiple R-squared: 0.001208, Adjusted R-squared: 0.000207
## F-statistic: 1.207 on 1 and 998 DF, p-value: 0.2722
Conclusión: r = 0.035 indica correlación débil.
tabla_contingencia <- table(datos$Genero, datos$NivelEducativo)
tabla_con_totales <- addmargins(tabla_contingencia)
kable(tabla_con_totales,
caption = "Tabla 8: Contingencia Género × Nivel Educativo",
align = c('l', rep('c', ncol(tabla_con_totales)-1)))
Primaria | Secundaria | Técnico | Universitario | Sum | |
---|---|---|---|---|---|
Femenino | 72 | 88 | 71 | 75 | 306 |
Masculino | 74 | 93 | 82 | 90 | 339 |
Otro | 83 | 107 | 78 | 87 | 355 |
Sum | 229 | 288 | 231 | 252 | 1000 |
tabla_prop_total <- prop.table(tabla_contingencia) * 100
kable(round(tabla_prop_total, 2),
caption = "Tabla 9: Proporciones (%)")
Primaria | Secundaria | Técnico | Universitario | |
---|---|---|---|---|
Femenino | 7.2 | 8.8 | 7.1 | 7.5 |
Masculino | 7.4 | 9.3 | 8.2 | 9.0 |
Otro | 8.3 | 10.7 | 7.8 | 8.7 |
##
## TEST CHI-CUADRADO
## H0: Independientes | H1: Existe asociación
## Chi-cuadrado: 1.4412
## p-valor: 0.9633
cat("Decisión:", ifelse(test_chi$p.value < 0.05,
"Rechazar H0: Existe asociación", "No rechazar H0"), "\n")
## Decisión: No rechazar H0
personas_filtradas <- datos %>%
filter(Hermanos > 2 & IngresoMensual > 3000)
n_filtradas <- nrow(personas_filtradas)
prop_filtradas <- (n_filtradas / nrow(datos)) * 100
ic_prop <- prop.test(n_filtradas, nrow(datos))$conf.int
cor_edad_ingreso <- round(cor(datos$Edad, datos$IngresoMensual,
use = "complete.obs"), 3)
resumen_conjunto <- data.frame(
Criterio = "Más de 2 hermanos E Ingreso > $3000",
Frecuencia = n_filtradas,
Proporcion = round(prop_filtradas, 2),
IC_Inf = round(ic_prop[1] * 100, 2),
IC_Sup = round(ic_prop[2] * 100, 2)
)
kable(resumen_conjunto,
caption = "Tabla 10: Subgrupo con Criterio Múltiple",
col.names = c("Criterio", "n", "%", "IC 95% Inf", "IC 95% Sup"),
align = c('l', rep('c', 4)))
Criterio | n | % | IC 95% Inf | IC 95% Sup |
---|---|---|---|---|
Más de 2 hermanos E Ingreso > $3000 | 53 | 5.3 | 4.03 | 6.92 |
##
## Subgrupo identificado: 53 casos ( 5.3 %)
Interpretación: El 5.3% cumple ambos criterios.
Caracterización demográfica:
La población analizada presenta una edad media cercana a los 35
años, con una dispersión moderada. Esto refleja un grupo
predominantemente de adultos jóvenes.
Familias numerosas:
Alrededor del 43% de los individuos provienen de familias con
más de tres hermanos, lo que evidencia un peso significativo de
hogares grandes en la muestra.
Distribución de ingresos:
El ingreso promedio se sitúa en torno a $1.891.617, con
una alta heterogeneidad (CV superior al 40%), lo que muestra desigualdad
salarial dentro de la población.
Estatura y género:
Se observan diferencias en estatura por género, siendo los hombres en
promedio más altos, aunque ambos grupos mantienen una distribución
aproximadamente normal.
Asociación entre variables cualitativas:
El análisis Chi-cuadrado para género y nivel educativo no mostró
asociación significativa, sugiriendo que en esta muestra las
oportunidades educativas no dependen del género.
Relación edad-ingreso:
La correlación entre edad e ingreso resultó débil y no significativa (R²
cercano a cero), indicando que la edad no es un predictor relevante del
nivel de ingresos en este caso.
Subgrupos de interés:
Solo un 5.3% de la población cumple simultáneamente con
tener más de dos hermanos y un ingreso superior a $3000, lo cual
representa un perfil minoritario dentro del conjunto.
Fecha: 02 de octubre de 2025