# ================================
# Cargar librerías
# ================================
library(wooldridge) # base de datos
## Warning: package 'wooldridge' was built under R version 4.5.3
library(dplyr) # manipulación de datos
## Warning: package 'dplyr' was built under R version 4.5.3
##
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tseries) # jarque bera
## Warning: package 'tseries' was built under R version 4.5.3
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
# ================================
# Cargar datos
# ================================
data(hprice1)
# Mostrar primeras 5 observaciones (como pide el ejercicio)
cat("=== PRIMERAS 5 OBSERVACIONES ===\n")
## === PRIMERAS 5 OBSERVACIONES ===
head(force(hprice1), n = 5)
## price assess bdrms lotsize sqrft colonial lprice lassess llotsize lsqrft
## 1 300 349.1 4 6126 2438 1 5.703783 5.855359 8.720297 7.798934
## 2 370 351.5 3 9903 2076 1 5.913503 5.862210 9.200593 7.638198
## 3 191 217.7 3 5200 1374 0 5.252274 5.383118 8.556414 7.225482
## 4 195 231.8 3 4600 1448 1 5.273000 5.445875 8.433811 7.277938
## 5 373 319.1 4 6095 2514 1 5.921578 5.765504 8.715224 7.829630
# ================================
# 1. Estimar modelo
# price = a + a1(lotsize) + a2(sqrft) + a3(bdrms) + e
# ================================
modelo <- lm(price ~ lotsize + sqrft + bdrms, data = hprice1)
# Mostrar resumen del modelo
cat("\n=== RESUMEN DEL MODELO ===\n")
##
## === RESUMEN DEL MODELO ===
summary(modelo)
##
## Call:
## lm(formula = price ~ lotsize + sqrft + bdrms, data = hprice1)
##
## Residuals:
## Min 1Q Median 3Q Max
## -120.026 -38.530 -6.555 32.323 209.376
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -2.177e+01 2.948e+01 -0.739 0.46221
## lotsize 2.068e-03 6.421e-04 3.220 0.00182 **
## sqrft 1.228e-01 1.324e-02 9.275 1.66e-14 ***
## bdrms 1.385e+01 9.010e+00 1.537 0.12795
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 59.83 on 84 degrees of freedom
## Multiple R-squared: 0.6724, Adjusted R-squared: 0.6607
## F-statistic: 57.46 on 3 and 84 DF, p-value: < 2.2e-16
# ================================
# Obtener residuos
# ================================
tabla <- hprice1 %>%
mutate(res = resid(modelo))
# ================================
# 2a. PRUEBA JARQUE - BERA (JB)
# ================================
jb <- jarque.bera.test(tabla$res)
# Mostrar resultado JB
cat("\n=== PRUEBA JARQUE-BERA ===\n")
##
## === PRUEBA JARQUE-BERA ===
print(jb)
##
## Jarque Bera Test
##
## data: tabla$res
## X-squared = 32.278, df = 2, p-value = 9.794e-08
# Tabla de resultados JB
resultados_jb <- data.frame(
Prueba = "Jarque-Bera",
Estadistico = round(jb$statistic, 4),
Valor_p = round(jb$p.value, 4)
)
print(resultados_jb)
## Prueba Estadistico Valor_p
## X-squared Jarque-Bera 32.2779 0
# Gráfica normalidad JB
hist(tabla$res,
probability = TRUE,
main = "Normalidad de residuos (JB)",
xlab = "Residuos",
col = "lightblue")
curve(dnorm(x, mean(tabla$res), sd(tabla$res)),
col = "red",
lwd = 2,
add = TRUE)

# ================================
# 2b. PRUEBA KOLMOGOROV - SMIRNOV (KS)
# ================================
# NOTA: La prueba KS correcta para normalidad requiere estandarizar los residuos
residuos_estandarizados <- (tabla$res - mean(tabla$res)) / sd(tabla$res)
# Prueba KS comparando con distribución normal estándar
ks <- ks.test(residuos_estandarizados, "pnorm")
# Mostrar resultado KS
cat("\n=== PRUEBA KOLMOGOROV-SMIRNOV ===\n")
##
## === PRUEBA KOLMOGOROV-SMIRNOV ===
print(ks)
##
## Exact one-sample Kolmogorov-Smirnov test
##
## data: residuos_estandarizados
## D = 0.075439, p-value = 0.67
## alternative hypothesis: two-sided
# Tabla de resultados KS
resultados_ks <- data.frame(
Prueba = "Kolmogorov-Smirnov",
Estadistico = round(ks$statistic, 4),
Valor_p = round(ks$p.value, 4)
)
print(resultados_ks)
## Prueba Estadistico Valor_p
## D Kolmogorov-Smirnov 0.0754 0.67
# Interpretación KS
if(ks$p.value > 0.05) {
cat("\n→ Conclusión KS: No se rechaza H0 → Los residuos siguen una distribución normal\n")
} else {
cat("\n→ Conclusión KS: Se rechaza H0 → Los residuos NO siguen una distribución normal\n")
}
##
## → Conclusión KS: No se rechaza H0 → Los residuos siguen una distribución normal
# Gráfico KS: función de distribución acumulada
plot(ecdf(residuos_estandarizados),
main = "Función de Distribución Acumulada (Prueba KS)",
xlab = "Residuos estandarizados",
ylab = "Probabilidad acumulada",
col = "blue",
lwd = 2)
curve(pnorm(x),
from = -3,
to = 3,
add = TRUE,
col = "red",
lwd = 2,
lty = 2)
legend("bottomright",
legend = c("Distribución empírica", "Distribución normal teórica"),
col = c("blue", "red"),
lwd = c(2, 2),
lty = c(1, 2))

# ================================
# 2c. PRUEBA SHAPIRO - WILK (SW)
# ================================
sw <- shapiro.test(tabla$res)
# Mostrar resultado SW
cat("\n=== PRUEBA SHAPIRO-WILK ===\n")
##
## === PRUEBA SHAPIRO-WILK ===
print(sw)
##
## Shapiro-Wilk normality test
##
## data: tabla$res
## W = 0.94132, p-value = 0.0005937
# Tabla de resultados SW
resultados_sw <- data.frame(
Prueba = "Shapiro-Wilk",
Estadistico = round(sw$statistic, 4),
Valor_p = round(sw$p.value, 4)
)
print(resultados_sw)
## Prueba Estadistico Valor_p
## W Shapiro-Wilk 0.9413 6e-04
# Gráfica normalidad SW (QQ Plot)
qqnorm(tabla$res,
main = "QQ Plot - Normalidad (Shapiro-Wilk)",
col = "blue",
pch = 19)
qqline(tabla$res,
col = "red",
lwd = 2)

# ================================
# TABLA RESUMEN DE LAS 3 PRUEBAS
# ================================
cat("\n=== TABLA RESUMEN DE PRUEBAS DE NORMALIDAD ===\n")
##
## === TABLA RESUMEN DE PRUEBAS DE NORMALIDAD ===
tabla_resumen <- rbind(resultados_jb, resultados_ks, resultados_sw)
print(tabla_resumen)
## Prueba Estadistico Valor_p
## X-squared Jarque-Bera 32.2779 0.0000
## D Kolmogorov-Smirnov 0.0754 0.6700
## W Shapiro-Wilk 0.9413 0.0006
# ================================
# INTERPRETACIÓN FINAL
# ================================
cat("\n=== INTERPRETACIÓN FINAL ===\n")
##
## === INTERPRETACIÓN FINAL ===
cat("Si el valor p > 0.05 → No se rechaza H0 → Los residuos son normales\n")
## Si el valor p > 0.05 → No se rechaza H0 → Los residuos son normales
cat("Si el valor p < 0.05 → Se rechaza H0 → Los residuos NO son normales\n\n")
## Si el valor p < 0.05 → Se rechaza H0 → Los residuos NO son normales
cat("Resultados:\n")
## Resultados:
cat(paste("- Jarque-Bera: p =", round(jb$p.value, 4),
if(jb$p.value > 0.05) "→ NORMAL" else "→ NO NORMAL", "\n"))
## - Jarque-Bera: p = 0 → NO NORMAL
cat(paste("- Kolmogorov-Smirnov: p =", round(ks$p.value, 4),
if(ks$p.value > 0.05) "→ NORMAL" else "→ NO NORMAL", "\n"))
## - Kolmogorov-Smirnov: p = 0.67 → NORMAL
cat(paste("- Shapiro-Wilk: p =", round(sw$p.value, 4),
if(sw$p.value > 0.05) "→ NORMAL" else "→ NO NORMAL", "\n"))
## - Shapiro-Wilk: p = 6e-04 → NO NORMAL