# Importación de datos
#install.packages(devtools) # solo una vez
#devtools::install_github("dgonxalex80/paqueteMETODOS")
library(paqueteMETODOS)
## Loading required package: cubature
## Loading required package: GGally
## Loading required package: ggplot2
## Registered S3 method overwritten by 'GGally':
## method from
## +.gg ggplot2
## Loading required package: MASS
## Loading required package: summarytools
## Loading required package: psych
##
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
##
## %+%, alpha
## Loading required package: tidyverse
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr 1.1.2 ✔ readr 2.1.4
## ✔ forcats 1.0.0 ✔ stringr 1.5.0
## ✔ lubridate 1.9.2 ✔ tibble 3.2.1
## ✔ purrr 1.0.1 ✔ tidyr 1.3.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ psych::%+%() masks ggplot2::%+%()
## ✖ psych::alpha() masks ggplot2::alpha()
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag() masks stats::lag()
## ✖ dplyr::select() masks MASS::select()
## ✖ tibble::view() masks summarytools::view()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
data(vivienda4)
#write.csv(vivienda4, "vivienda4.csv", row.names = FALSE)
#Cargamos los datos y paquetes adicionales necesarios
#install.packages("tidyverse")
#install.packages("corrplot")
#install.packages("leaflet")
#install.packages("mapview")
#install.packages("table1")
library(tidyverse)
library(corrplot)
## corrplot 0.92 loaded
library(leaflet)
library(leaflet.extras)
#Verificamos la cantidad de filas y columnas que tiene el dataset
str(vivienda4)
## spc_tbl_ [1,706 × 5] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ zona : Factor w/ 5 levels "Zona Centro",..: 2 2 2 5 2 2 2 2 2 2 ...
## $ estrato : Factor w/ 4 levels "3","4","5","6": 2 2 2 2 2 2 2 2 2 2 ...
## $ preciom : num [1:1706] 220 600 320 290 220 305 220 162 225 370 ...
## $ areaconst: num [1:1706] 52 160 108 96 82 117 75 60 84 117 ...
## $ tipo : Factor w/ 2 levels "Apartamento",..: 1 2 1 1 1 2 1 1 1 1 ...
head(vivienda4)
## # A tibble: 6 × 5
## zona estrato preciom areaconst tipo
## <fct> <fct> <dbl> <dbl> <fct>
## 1 Zona Norte 4 220 52 Apartamento
## 2 Zona Norte 4 600 160 Casa
## 3 Zona Norte 4 320 108 Apartamento
## 4 Zona Sur 4 290 96 Apartamento
## 5 Zona Norte 4 220 82 Apartamento
## 6 Zona Norte 4 305 117 Casa
# Realizamos el filtro del dataset de acuerdo a la solicitud.
# Filtrar el dataset
data_filtrado <- subset(
vivienda4,
tipo == "Apartamento" & estrato == 4 & areaconst < 200
)
# Mostrar el dataset filtrado
print(data_filtrado)
## # A tibble: 1,360 × 5
## zona estrato preciom areaconst tipo
## <fct> <fct> <dbl> <dbl> <fct>
## 1 Zona Norte 4 220 52 Apartamento
## 2 Zona Norte 4 320 108 Apartamento
## 3 Zona Sur 4 290 96 Apartamento
## 4 Zona Norte 4 220 82 Apartamento
## 5 Zona Norte 4 220 75 Apartamento
## 6 Zona Norte 4 162 60 Apartamento
## 7 Zona Norte 4 225 84 Apartamento
## 8 Zona Norte 4 370 117 Apartamento
## 9 Zona Norte 4 155 60 Apartamento
## 10 Zona Norte 4 240 75 Apartamento
## # ℹ 1,350 more rows
#Verificamos la cantidad de filas y columnas que tiene el dataset
str(data_filtrado)
## tibble [1,360 × 5] (S3: tbl_df/tbl/data.frame)
## $ zona : Factor w/ 5 levels "Zona Centro",..: 2 2 5 2 2 2 2 2 2 2 ...
## $ estrato : Factor w/ 4 levels "3","4","5","6": 2 2 2 2 2 2 2 2 2 2 ...
## $ preciom : num [1:1360] 220 320 290 220 220 162 225 370 155 240 ...
## $ areaconst: num [1:1360] 52 108 96 82 75 60 84 117 60 75 ...
## $ tipo : Factor w/ 2 levels "Apartamento",..: 1 1 1 1 1 1 1 1 1 1 ...
head(data_filtrado)
## # A tibble: 6 × 5
## zona estrato preciom areaconst tipo
## <fct> <fct> <dbl> <dbl> <fct>
## 1 Zona Norte 4 220 52 Apartamento
## 2 Zona Norte 4 320 108 Apartamento
## 3 Zona Sur 4 290 96 Apartamento
## 4 Zona Norte 4 220 82 Apartamento
## 5 Zona Norte 4 220 75 Apartamento
## 6 Zona Norte 4 162 60 Apartamento
# Análisis descriptivo de las variables precio y area construida
summary(data_filtrado$preciom)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 78 153 185 202 240 645
summary(data_filtrado$areaconst)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 40.0 60.0 70.0 75.2 83.0 198.0
# Visualización de los datos
# Gráfico de densidad para el precio de vivienda
ggplot(data_filtrado, aes(x = preciom)) +
geom_density() +
labs(x = "Precio de Vivienda (millones de pesos COP)", y = "Densidad")
# Gráfico de dispersión para precio de vivienda vs. área construida
ggplot(data_filtrado, aes(x = areaconst, y = preciom)) +
geom_point() +
labs(x = "Área Construida (metros cuadrados)", y = "Precio de Vivienda (millones de pesos COP)")
# Histograma Precio Viviendas
ggplot(data_filtrado, aes(x = preciom)) + geom_histogram(bins = 30)
##### El histograma del precio de la vivienda muestra que la mayoría de
las viviendas tienen un precio entre 100 y 270 millones de pesos
aproximadamente.
# Histograma área construida
ggplot(data_filtrado, aes(x = areaconst)) + geom_histogram(bins = 30)
# Correlación entre preciom y areaconst
cor(data_filtrado$preciom, data_filtrado$areaconst)
## [1] 0.7431338
# Gráfico de dispersión con línea de regresión
ggplot(data_filtrado, aes(x = areaconst, y = preciom)) +
geom_point() +
geom_smooth(method = "lm", se = FALSE, color = "blue") +
labs(x = "Área Construida (metros cuadrados)", y = "Precio de Vivienda (millones de pesos COP)")
## `geom_smooth()` using formula = 'y ~ x'
# Calcular la correlación entre precio y área construida
correlation <- cor(data_filtrado$preciom, data_filtrado$areaconst)
correlation
## [1] 0.7431338
# Estimar el modelo de regresión lineal
modelo_regresion <- lm(preciom ~ areaconst, data = data_filtrado)
# Resumen del modelo
summary(modelo_regresion)
##
## Call:
## lm(formula = preciom ~ areaconst, data = data_filtrado)
##
## Residuals:
## Min 1Q Median 3Q Max
## -228.412 -23.589 -4.653 25.674 207.336
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 36.62292 4.20667 8.706 <2e-16 ***
## areaconst 2.19868 0.05372 40.926 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 43.21 on 1358 degrees of freedom
## Multiple R-squared: 0.5522, Adjusted R-squared: 0.5519
## F-statistic: 1675 on 1 and 1358 DF, p-value: < 2.2e-16
# Intervalo de confianza para el coeficiente de área construida
confint(modelo_regresion, parm = "areaconst", level = 0.95)
## 2.5 % 97.5 %
## areaconst 2.093294 2.304074
# Prueba de hipótesis t para el coeficiente de área construida
summary(modelo_regresion)$coefficients
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 36.622924 4.20667014 8.705918 8.972924e-18
## areaconst 2.198684 0.05372357 40.925877 3.301551e-239
# Obtener el R2 del modelo
r2 <- summary(modelo_regresion)$r.squared
r2
## [1] 0.5522478
# Área de apartamento para la predicción
area_apartamento <- 110
# Calcular el precio estimado para un apartamento de 110 metros cuadrados
precio_estimado <- coef(modelo_regresion)[1] + coef(modelo_regresion)[2] * area_apartamento
precio_estimado
## (Intercept)
## 278.4782
# Obtener los residuos del modelo
residuos <- residuals(modelo_regresion)
# Gráficos para validar supuestos
par(mfrow=c(2,2))
# Gráfico de dispersión entre residuos y predicciones
plot(modelo_regresion$fitted.values, residuos,
xlab = "Predicciones", ylab = "Residuos",
main = "Residuos vs. Predicciones")
##### El gráfico muestra que los residuos estandarizados se distribuyen
aleatoriamente alrededor de la línea cero. Esto sugiere que el supuesto
de linealidad se cumple.
# Gráfico de residuos estandarizados vs. predicciones
plot(modelo_regresion$fitted.values, rstandard(modelo_regresion),
xlab = "Predicciones", ylab = "Residuos Estandarizados",
main = "Residuos Estandarizados vs. Predicciones")
# Gráfico de densidad de los residuos
plot(density(residuos),
xlab = "Residuos", main = "Densidad de Residuos")
# Gráfico cuantil-cuantil de los residuos
qqnorm(residuos, main = "Q-Q Plot de Residuos")
qqline(residuos)
# Calcular los residuos estandarizados del modelo
rstudent <- rstudent(modelo_regresion)
# Calcular el rezago de los residuos estandarizados
rstudent_lag <- lag(rstudent)
# Generar el gráfico de autocorrelación de los residuos
ggplot(modelo_regresion, aes(x = rstudent_lag, y = rstudent)) + geom_point()
## Warning: Removed 1 rows containing missing values (`geom_point()`).
# Estimar el modelo cuadrático
modelo_cuadratico <- lm(preciom ~ areaconst + I(areaconst^2), data = data_filtrado)
# Resumen del modelo cuadrático
summary(modelo_cuadratico)
##
## Call:
## lm(formula = preciom ~ areaconst + I(areaconst^2), data = data_filtrado)
##
## Residuals:
## Min 1Q Median 3Q Max
## -195.104 -21.232 -1.621 22.713 275.774
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -52.336399 11.206354 -4.67 3.31e-06 ***
## areaconst 4.249215 0.246038 17.27 < 2e-16 ***
## I(areaconst^2) -0.010642 0.001248 -8.53 < 2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 42.11 on 1357 degrees of freedom
## Multiple R-squared: 0.575, Adjusted R-squared: 0.5744
## F-statistic: 918.1 on 2 and 1357 DF, p-value: < 2.2e-16
# Estimar el modelo logarítmico
modelo_logaritmico <- lm(log(preciom) ~ log(areaconst), data = data_filtrado)
# Resumen del modelo logarítmico
summary(modelo_logaritmico)
##
## Call:
## lm(formula = log(preciom) ~ log(areaconst), data = data_filtrado)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.89099 -0.11086 0.00225 0.13390 0.75535
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 1.46270 0.08850 16.53 <2e-16 ***
## log(areaconst) 0.88673 0.02061 43.02 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1913 on 1358 degrees of freedom
## Multiple R-squared: 0.5767, Adjusted R-squared: 0.5764
## F-statistic: 1850 on 1 and 1358 DF, p-value: < 2.2e-16
# Comparación de modelos
modelos <- list(modelo_regresion, modelo_cuadratico, modelo_logaritmico)
nombres_modelos <- c("Modelo Lineal", "Modelo Cuadrático", "Modelo Logarítmico")
# R2
r2_1 <- summary(modelo_regresion)$r.squared
r2_2 <- summary(modelo_cuadratico)$r.squared
r2_3 <- summary(modelo_logaritmico)$r.squared
# Homocedasticidad
homocedasticidad_1 <- plot(modelo_regresion, which = 1)
homocedasticidad_2 <- plot(modelo_cuadratico, which = 1)
homocedasticidad_3 <- plot(modelo_logaritmico, which = 1)
# Normalidad
normalidad_1 <- shapiro.test(modelo_regresion$residuals)
normalidad_2 <- shapiro.test(modelo_cuadratico$residuals)
normalidad_3 <- shapiro.test(modelo_logaritmico$residuals)
# Independencia
independencia_1 <- plot(modelo_regresion, which = 2)
independencia_2 <- plot(modelo_cuadratico, which = 2)
independencia_3 <- plot(modelo_logaritmico, which = 2)
# Resultados R2
print(paste("R2 para el modelo de regresión lineal:", r2_1))
## [1] "R2 para el modelo de regresión lineal: 0.552247776205436"
print(paste("R2 para el modelo de regresión cuadrática:", r2_2))
## [1] "R2 para el modelo de regresión cuadrática: 0.575031920788014"
print(paste("R2 para el modelo de regresión logarítmica:", r2_3))
## [1] "R2 para el modelo de regresión logarítmica: 0.576726320143471"
print(normalidad_1)
##
## Shapiro-Wilk normality test
##
## data: modelo_regresion$residuals
## W = 0.96464, p-value < 2.2e-16
print(normalidad_2)
##
## Shapiro-Wilk normality test
##
## data: modelo_cuadratico$residuals
## W = 0.95597, p-value < 2.2e-16
print(normalidad_3)
##
## Shapiro-Wilk normality test
##
## data: modelo_logaritmico$residuals
## W = 0.98913, p-value = 1.604e-08