El presente analisis se realizo con la base de datos prevista con un total de registros de 8330 enfocado a analizar el mercado inmobiliario de la ciudad de Cali en el año 2022, con un enfoque en la venta de apartamentos y casas. explorare patrones y tendencias clave en los precios y características de las propiedades. Al proporcionar información actualizada sobre el mercado, este estudio ofrece una visión sólida para inversores, agentes inmobiliarios y otros actores interesados en el sector inmobiliario de Cali. A lo largo de este análisis, se espera identificar factores influyentes en los precios y brindar insights que respalden decisiones estratégicas en este sector.
A lo largo del analisis a realizar se dara claridad a respecto a los siguientes puntos:
Para el analisis se realizara primero una limpieza y preparación de datos, que puede implicar eliminar duplicados, manejar valores faltantes, normalizar formatos, luego se realizaran los respectivos calculos necesarios para dar respuesta a los interrogantes tipificados en el punto anterior.
#if (!require("learnr")) install.packages("learnr",repos = "http://cran.us.r-project.org")
if (!require("devtools")) install.packages("devtools",repos = "http://cran.us.r-project.org")
## Loading required package: devtools
## Loading required package: usethis
if (!require("dplyr")) install.packages("dplyr",repos = "http://cran.us.r-project.org")
## Loading required package: dplyr
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
if (!require("rmarkdown")) install.packages("rmarkdown")
## Loading required package: rmarkdown
if (!require("ggplot2")) install.packages("ggplot2")
## Loading required package: ggplot2
if (!require("psych")) install.packages("psych")
## Loading required package: psych
##
## Attaching package: 'psych'
## The following objects are masked from 'package:ggplot2':
##
## %+%, alpha
devtools::install_github("dgonxalex80/paqueteMET", force = TRUE)
## Downloading GitHub repo dgonxalex80/paqueteMET@HEAD
##
## ── R CMD build ─────────────────────────────────────────────────────────────────
##
checking for file ‘/private/var/folders/vh/c65wsrm94x92d8rfk33vvpwr0000gn/T/RtmpBHrrxX/remotesf4373b3ccbf/dgonxalex80-paqueteMET-624823e/DESCRIPTION’ ...
✔ checking for file ‘/private/var/folders/vh/c65wsrm94x92d8rfk33vvpwr0000gn/T/RtmpBHrrxX/remotesf4373b3ccbf/dgonxalex80-paqueteMET-624823e/DESCRIPTION’
##
─ preparing ‘paqueteMET’:
##
checking DESCRIPTION meta-information ...
✔ checking DESCRIPTION meta-information
##
─ checking for LF line-endings in source and make files and shell scripts
##
─ checking for empty or unneeded directories
##
─ building ‘paqueteMET_0.0.0.1.tar.gz’
##
##
library(paqueteMET)
data(vivienda_faltantes)
vf<-vivienda_faltantes
¿Cuantos elementos existen por tipo, zona o barrio con los datos originales?
vf<-vivienda_faltantes
tipos_counter <- table(vf$tipo)
tipos_df <- data.frame(tipos_counter)
paged_table(tipos_df, options = NULL)
barrio_counter <- table(vf$barrio)
barrio_df <- data.frame(barrio_counter)
paged_table(barrio_df, options = NULL)
zona_counter <- table(vf$zona)
zona_df <- data.frame(zona_counter)
paged_table(zona_df, options = NULL)
Paso a normalizar los datos para evitar cosas como apto<>Apartamento en todos los datos
# Aplicar transformaciones a las columnas de tipo string
convertTableAccents <- data.frame(
original = c("á", "é", "í", "ó", "ú", "apto", "agua blanca", "valle de lili", "juanamb√∫", "mel√©ndez", "alf√©rez real", "cali canto", "cali bella", " los ", "barrio", "paso ancho", "ingenio 3", "pampa linda"),
replace = c("a", "e", "i", "o", "u", "apartamento", "aguablanca", "valle del lili", "juanambu", "melendez", "alferez real", "calicanto", "calibella", "", "", "pasoancho", "ingenio iii", "pampalinda"),
stringsAsFactors = FALSE
)
# aplicar reemplazos
removeAccents <- function(x) {
for (i in seq_len(nrow(convertTableAccents))) {
x <- gsub(convertTableAccents$original[i], convertTableAccents$replace[i], x)
}
return(x)
}
removePrefix <- function(x) {
x <- gsub("^(el|la|las|los)\\s+", "", x, ignore.case = TRUE)
return(x)
}
# Aplicar transformaciones a todas las de tipo string
vf <- vf %>%
mutate_if(is.character, tolower) %>%
mutate_if(is.character, removeAccents) %>%
mutate_if(is.character, removePrefix)
vuelvo a contar la frecuencia por tipo, barrio o zona con los datos ya ajustado
tipos_counter <- table(vf$tipo)
tipos_df <- data.frame(tipos_counter)
paged_table(tipos_df, options = NULL)
barrio_counter <- table(vf$barrio)
barrio_df <- data.frame(barrio_counter)
paged_table(barrio_df, options = NULL)
zona_counter <- table(vf$zona)
zona_df <- data.frame(zona_counter)
paged_table(zona_df, options = NULL)
Haciendo un analisis de observacion en los datos encontramos que existen 3 registros que no tienen informacion, es decir con las columnas mas relevantes de este analisis en NA, por lo cual se decide eliminarlas puesto que no generan valor a este ejercicio, como resumen hasta aqui obtengo 8327 registros
# Contar el número de registros con información faltante en las columnas especificadas
missing_counts <- vf %>%
filter(is.na(preciom) | is.na(tipo) | is.na(areaconst) | is.na(estrato)) %>%
nrow()
sprintf("El numero de registros in informacion relevente %d", missing_counts)
## [1] "El numero de registros in informacion relevente 3"
vf <- vf %>%
filter(!is.na(preciom) & !is.na(tipo) & !is.na(areaconst) & !is.na(estrato))
# Mostrar el nuevo dataframe sin las filas con información faltante
paged_table(vf, options = NULL)
reviso los registros duplicados encontrados:
duplicados <- vf[duplicated(vf), ]
# Imprimir los registros duplicados
paged_table(duplicados, options = NULL)
Finalmente se decide no hacer nada con los registros duplicados puesto que como se observan la mayoria son apartamentos que suelen tener todos los datos iguales y tambien ubicados en las mismas coordenadas
saco el % de datos faltantes por columna
porcentaje_faltantes <- colMeans(is.na(vf)) * 100
# Crear un dataframe para mostrar los resultados
resultado <- data.frame(Columna = names(vf), PorcentajeFaltantes = porcentaje_faltantes)
# Ordenar el dataframe por el porcentaje de faltantes de mayor a menor
resultado <- resultado[order(-resultado$PorcentajeFaltantes), ]
# Redondear los porcentajes a 3 decimales y agregar el signo "%"
resultado$PorcentajeFaltantes <- sprintf("%.3f%%", resultado$PorcentajeFaltantes)
# Imprimir el dataframe con los porcentajes de faltantes
paged_table(resultado, options = NULL)
Distribucion de variables numericas
library("psych")
# Filtrar solo las columnas numéricas
vf_numeric <- vivienda_faltantes %>%
select_if(is.numeric)
vf_numeric <- subset(vf_numeric, select = -c(id ,longitud, latitud))
# Calcular las estadísticas por columna
describe(vf_numeric)
## vars n mean sd median trimmed mad min max range skew
## piso 1 5689 3.77 2.62 3 3.37 1.48 1 12 11 1.28
## estrato 2 8327 4.63 1.03 5 4.67 1.48 3 6 3 -0.18
## preciom 3 8328 434.24 329.02 330 374.72 209.05 58 1999 1941 1.85
## areaconst 4 8327 174.99 142.95 123 149.22 84.51 30 1745 1715 2.69
## parquea 5 6724 1.84 1.13 2 1.62 1.48 1 10 9 2.32
## banios 6 8327 3.11 1.43 3 2.99 1.48 0 10 10 0.92
## habitac 7 8327 3.61 1.46 3 3.41 1.48 0 10 10 1.64
## kurtosis se
## piso 1.05 0.03
## estrato -1.11 0.01
## preciom 3.66 3.61
## areaconst 12.90 1.57
## parquea 8.29 0.01
## banios 1.12 0.02
## habitac 3.99 0.02
###Caso Parquederos
Teniendo en cuenta que el parqueadero es una caracteristica determinante para el costo o intencion de compra/venta de un predio procedemos a su analisis:
# Filtrar los registros de tipo "apartamento" con valores NA en "parquea"
na_apartamento_count <- vf %>%
filter(tipo == "apartamento" & is.na(parquea)) %>%
nrow()
sprintf("El numero de apartamentos sin el dato de parqueadero es %d", na_apartamento_count)
## [1] "El numero de apartamentos sin el dato de parqueadero es 869"
na_casa_count <- vf %>%
filter(tipo == "casa" & is.na(parquea)) %>%
nrow()
sprintf("El numero de casas sin el dato de parqueadero es %d", na_casa_count)
## [1] "El numero de casas sin el dato de parqueadero es 734"
Mediante observacion se puede afirmar que la base de datos no presenta bienes inmuebles sin parquederos, lo cual es falso, puesto que esto no representa la realidad.
Teniendo en cuenta el analisis numerico no es correcto afirmar que todos los apartamentos estrato 3 tienen 2 parqueaderos o que minimo tienen 1, vamos a hacer un analisis a los parqueaderos a fin de determinar la mejor estrategia para esta caracteristica:
library(dplyr)
summary_by_type_estrato <- vf %>%
group_by(tipo, estrato) %>%
#group_by(tipo, barrio) %>%
summarise(mean_parqueadero = mean(parquea, na.rm = TRUE),
median_parqueadero = median(parquea, na.rm = TRUE),
max_parqueadero = max(parquea, na.rm = TRUE),
#mode_parqueadero = stat_mode(parquea, na.rm = TRUE),
median_areaconst = median(areaconst, na.rm = TRUE),
#median_estrato = median(estrato, na.rm = TRUE),
count_na = sum(is.na(parquea)),
count_not_na = sum(!is.na(parquea)))
## `summarise()` has grouped output by 'tipo'. You can override using the
## `.groups` argument.
# Mostrar el resumen
print(summary_by_type_estrato)
## # A tibble: 8 × 8
## # Groups: tipo [2]
## tipo estrato mean_parqueadero median_parqueadero max_parqueadero
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 apartamento 3 1.06 1 3
## 2 apartamento 4 1.13 1 10
## 3 apartamento 5 1.46 1 10
## 4 apartamento 6 2.21 2 6
## 5 casa 3 1.44 1 10
## 6 casa 4 1.71 1 10
## 7 casa 5 2.25 2 9
## 8 casa 6 3.40 3 10
## # ℹ 3 more variables: median_areaconst <dbl>, count_na <int>,
## # count_not_na <int>
Teniendo como referente el POT de Cali del año 2000 el Acuerdo 193-06 de 2006 [1] segun lo expuesto en la pagina 11 indica que segun el estrato y area del bien, el numero o proporcion de parquederos, y por otra parte se observa que en las caracteristicas de los inmuebles analizados no se encuentra la antiguedad para determinar asi su valor mas exacto, se procede asi:
Estrato 3:
Estrato 4:
Estrato 5:
Estrato 6:
vf$parquea <- ifelse(vf$estrato == 3 & is.na(vf$parquea), 0, vf$parquea)
vf$parquea <- ifelse(vf$estrato == 4 & is.na(vf$parquea) & vf$tipo=="apartamento", 1, vf$parquea)
vf$parquea <- ifelse(vf$estrato == 5 & is.na(vf$parquea) & vf$tipo=="apartamento", 1, vf$parquea)
vf$parquea <- ifelse(vf$estrato == 6 & is.na(vf$parquea) & vf$tipo=="apartamento", 2, vf$parquea)
vf$parquea <- ifelse(vf$estrato == 4 & is.na(vf$parquea) & vf$tipo=="casa", 1, vf$parquea)
vf$parquea <- ifelse(vf$estrato == 5 & is.na(vf$parquea) & vf$tipo=="casa", 2, vf$parquea)
vf$parquea <- ifelse(vf$estrato == 6 & is.na(vf$parquea) & vf$tipo=="casa", 3, vf$parquea)
df_summary <- vf %>%
group_by(tipo) %>%
summarise(
count = n(),
percentage = n() / nrow(vf) * 100
)
# Mostrar los resultados
print(df_summary)
## # A tibble: 2 × 3
## tipo count percentage
## <chr> <int> <dbl>
## 1 apartamento 5106 61.3
## 2 casa 3221 38.7
plot_piso <- ggplot(data = vf, aes(x = factor(piso))) +
geom_bar(fill = "blue") +
labs(title = "Distribution of 'piso' Column",
x = "Piso",
y = "Count")
# Print the count plot
print(plot_piso)
plot_estrato <- ggplot(data = vf, aes(x = factor(estrato))) +
geom_bar(fill = "green") +
labs(title = "Distribution of 'estrato' Column",
x = "Estrato",
y = "Count")
# Print the count plot
print(plot_estrato)
plot_preciom <- ggplot(data = vf, aes(x = preciom)) +
geom_histogram(fill = "purple", bins = 20) +
labs(title = "Histogram of 'preciom' Column",
x = "Precio (millions)",
y = "Frequency")
# Print the histogram
print(plot_preciom)
plot_areaconst <- ggplot(data = vf, aes(x = areaconst)) +
geom_histogram(fill = "orange", bins = 20) +
labs(title = "Histogram of 'areaconst' Column",
x = "Area Construida",
y = "Frequency")
# Print the histogram
print(plot_areaconst)
plot_parquea <- ggplot(data = vf, aes(x = factor(parquea))) +
geom_bar(fill = "red") +
labs(title = "Distribution of 'parquea' Column",
x = "Parqueadero",
y = "Count")
# Print the count plot
print(plot_parquea)
plot_banios <- ggplot(data = vf, aes(x = factor(banios))) +
geom_bar(fill = "blue") +
labs(title = "Distribution of 'banios' Column",
x = "Baños",
y = "Count")
# Print the count plot
print(plot_banios)
plot_habitac <- ggplot(data = vf, aes(x = factor(habitac))) +
geom_bar(fill = "green") +
labs(title = "Distribution of 'habitac' Column",
x = "Habitaciones",
y = "Count")
# Print the count plot
print(plot_habitac)
library(ggplot2)
# Gráfico de Distribución de 'piso' (Count Plot)
plot_piso <- ggplot(data = vf, aes(x = factor(piso))) +
geom_bar(fill = "blue") +
labs(title = "Distribución de Pisos",
x = "Piso",
y = "Cantidad") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
print(plot_piso)
# Gráfico de Distribución de 'estrato' (Count Plot)
plot_estrato <- ggplot(data = vf, aes(x = factor(estrato))) +
geom_bar(fill = "green") +
labs(title = "Distribución de Estratos",
x = "Estrato",
y = "Cantidad") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
print(plot_estrato)
# Histograma de 'preciom' (Histogram Plot)
plot_preciom <- ggplot(data = vf, aes(x = preciom)) +
geom_histogram(fill = "purple", bins = 20) +
labs(title = "Distribución de Precios",
x = "Precio (millones)",
y = "Frecuencia")
print(plot_preciom)
# Histograma de 'areaconst' (Histogram Plot)
plot_areaconst <- ggplot(data = vf, aes(x = areaconst)) +
geom_histogram(fill = "orange", bins = 20) +
labs(title = "Distribución de Área Construida",
x = "Área Construida",
y = "Frecuencia")
print(plot_areaconst)
# Gráfico de Distribución de 'parquea' (Count Plot)
plot_parquea <- ggplot(data = vf, aes(x = factor(parquea))) +
geom_bar(fill = "red") +
labs(title = "Distribución de Parqueaderos",
x = "Parqueadero",
y = "Cantidad") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
print(plot_parquea)
# Gráfico de Distribución de 'banios' (Count Plot)
plot_banios <- ggplot(data = vf, aes(x = factor(banios))) +
geom_bar(fill = "blue") +
labs(title = "Distribución de Baños",
x = "Baños",
y = "Cantidad") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
print(plot_banios)
# Gráfico de Distribución de 'habitac' (Count Plot)
plot_habitac <- ggplot(data = vf, aes(x = factor(habitac))) +
geom_bar(fill = "green") +
labs(title = "Distribución de Habitaciones",
x = "Habitaciones",
y = "Cantidad") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
print(plot_habitac)
# Crear un gráfico de dispersión para 'areaconst' vs 'preciom'
plot_area_precio <- ggplot(data = vf, aes(x = areaconst, y = preciom)) +
geom_point(color = "blue", alpha = 0.6) +
labs(title = "Relación entre Área Construida y Precio",
x = "Área Construida",
y = "Precio (millones)") +
theme_minimal()
print(plot_area_precio)
# Crear un gráfico de dispersión para 'areaconst' vs 'preciom' por tipo
plot_area_precio_tipo <- ggplot(data = vf, aes(x = areaconst, y = preciom, color = tipo)) +
geom_point(alpha = 0.6) +
labs(title = "Relación entre Área Construida y Precio por Tipo",
x = "Área Construida",
y = "Precio (millones)") +
theme_minimal() +
scale_color_discrete(name = "Tipo")
print(plot_area_precio_tipo)
library(ggplot2)
# Gráfico de Distribución de 'piso' por tipo (Count Plot)
plot_piso_tipo <- ggplot(data = vf, aes(x = factor(piso), fill = tipo)) +
geom_bar(position = "dodge") +
labs(title = "Distribución de Pisos por Tipo",
x = "Piso",
y = "Cantidad") +
theme_minimal() +
scale_fill_discrete(name = "Tipo")
print(plot_piso_tipo)
# Gráfico de Distribución de 'estrato' por tipo (Count Plot)
plot_estrato_tipo <- ggplot(data = vf, aes(x = factor(estrato), fill = tipo)) +
geom_bar(position = "dodge") +
labs(title = "Distribución de Estratos por Tipo",
x = "Estrato",
y = "Cantidad") +
theme_minimal() +
scale_fill_discrete(name = "Tipo")
print(plot_estrato_tipo)
# Histograma de 'preciom' por tipo (Histogram Plot)
plot_preciom_tipo <- ggplot(data = vf, aes(x = preciom, fill = tipo)) +
geom_histogram(position = "dodge", bins = 20) +
labs(title = "Distribución de Precios por Tipo",
x = "Precio (millones)",
y = "Frecuencia") +
theme_minimal() +
scale_fill_discrete(name = "Tipo")
print(plot_preciom_tipo)
# Histograma de 'areaconst' por tipo (Histogram Plot)
plot_areaconst_tipo <- ggplot(data = vf, aes(x = areaconst, fill = tipo)) +
geom_histogram(position = "dodge", bins = 20) +
labs(title = "Distribución de Área Construida por Tipo",
x = "Área Construida",
y = "Frecuencia") +
theme_minimal() +
scale_fill_discrete(name = "Tipo")
print(plot_areaconst_tipo)
# Gráfico de Distribución de 'parquea' por tipo (Count Plot)
plot_parquea_tipo <- ggplot(data = vf, aes(x = factor(parquea), fill = tipo)) +
geom_bar(position = "dodge") +
labs(title = "Distribución de Parqueaderos por Tipo",
x = "Parqueadero",
y = "Cantidad") +
theme_minimal() +
scale_fill_discrete(name = "Tipo")
print(plot_parquea_tipo)
# Gráfico de Distribución de 'banios' por tipo (Count Plot)
plot_banios_tipo <- ggplot(data = vf, aes(x = factor(banios), fill = tipo)) +
geom_bar(position = "dodge") +
labs(title = "Distribución de Baños por Tipo",
x = "Baños",
y = "Cantidad") +
theme_minimal() +
scale_fill_discrete(name = "Tipo")
print(plot_banios_tipo)
# Gráfico de Distribución de 'habitac' por tipo (Count Plot)
plot_habitac_tipo <- ggplot(data = vf, aes(x = factor(habitac), fill = tipo)) +
geom_bar(position = "dodge") +
labs(title = "Distribución de Habitaciones por Tipo",
x = "Habitaciones",
y = "Cantidad") +
theme_minimal() +
scale_fill_discrete(name = "Tipo")
print(plot_habitac_tipo)
# Gráfico de Dispersión de 'areaconst' vs 'preciom' por tipo
plot_area_precio_tipo <- ggplot(data = vf, aes(x = areaconst, y = preciom, color = tipo)) +
geom_point(alpha = 0.6) +
labs(title = "Relación entre Área Construida y Precio por Tipo",
x = "Área Construida",
y = "Precio (millones)") +
theme_minimal() +
scale_color_discrete(name = "Tipo")
print(plot_area_precio_tipo)
# Gráfico de Cajas de Precios por Tipo
plot_box_precio_tipo <- ggplot(data = vf, aes(x = tipo, y = preciom, fill = tipo)) +
geom_boxplot() +
labs(title = "Distribución de Precios por Tipo de Propiedad",
x = "Tipo de Propiedad",
y = "Precio (millones)") +
theme_minimal() +
scale_fill_discrete(name = "Tipo de Propiedad")
print(plot_box_precio_tipo)
plot_box_area_tipo <- ggplot(data = vf, aes(x = tipo, y = areaconst, fill = tipo)) +
geom_boxplot() +
labs(title = "Distribución de Área Construida por Tipo de Propiedad",
x = "Tipo de Propiedad",
y = "Área Construida") +
theme_minimal() +
scale_fill_discrete(name = "Tipo de Propiedad")
print(plot_box_area_tipo)
tipo_zona <- table(vf$tipo,vf$zona)
tipo_zona_df <- as.data.frame(tipo_zona)
paged_table(tipo_zona_df, options = NULL)
tipo_barrio <- table(vf$tipo,vf$barrio)
tipo_barrio_df <- as.data.frame(tipo_barrio)
paged_table(tipo_barrio_df, options = NULL)
# Definir función para calcular la moda
mode <- function(x) {
uniqx <- unique(x)
uniqx[which.max(tabulate(match(x, uniqx)))]
}
# Agrupar por vecindario y calcular estadísticas
grouped_by_neighborhood <- vf %>%
group_by(barrio) %>%
summarize(
price = median(preciom),
garage_places = mode(parquea),
rooms = mode(habitac),
square_foot = median(areaconst)
)
# Ordenar los datos por columnas
cols <- c("price", "square_foot", "rooms", "garage_places")
#cols <- c("price", "square_foot")
grouped_by_neighborhood <- grouped_by_neighborhood %>%
arrange(
desc(price),
desc(square_foot),
desc(rooms),
desc(garage_places)
)
# Crear gráfico
top10 <- head(grouped_by_neighborhood, 10)
p <- ggplot(top10, aes(x = barrio)) +
geom_bar(aes(y = price), stat = "identity") +
geom_bar(aes(y = square_foot), stat = "identity") +
geom_bar(aes(y = rooms), stat = "identity") +
geom_bar(aes(y = garage_places), stat = "identity") +
coord_flip() +
theme_minimal() +
labs(title = "Características por Vecindario - 10 Mas Costosos", y = NULL)
print(p)
tail10 <- tail(grouped_by_neighborhood, 10)
p <- ggplot(tail10, aes(x = barrio)) +
geom_bar(aes(y = price), stat = "identity") +
geom_bar(aes(y = square_foot), stat = "identity") +
geom_bar(aes(y = rooms), stat = "identity") +
geom_bar(aes(y = garage_places), stat = "identity") +
coord_flip() +
theme_minimal() +
labs(title = "Características por Vecindario - 10 menos Costosos", y = NULL)
print(p)
El analisis revela que la mayor parte de apartamentos en venta se encuentra al sur de la ciudad
El analisis no revela una amplia dispersión en los precios de las propiedades en Cali. en area y precio, lo que se puede atribuir a que gran parte de los predios en venta se encuentren en un mismo sector y pertenezcan al tipo apartamento
Al Oeste se puede evidenciar algunos barrios con precios que superan la media del total de los datos
[1] POT Cali año 2000 Acuerdo 193-06 de 2006, Regulacion parquederos- pagina 11 https://idesc.cali.gov.co/download/pot_2000/fichas_normativas/acuerdo_193_2006_pieza_urbano_regional.pdf
#install.packages("leaflet")
#install.packages("dplyr")
vf$latitud <- as.numeric(vf$latitud)
vf$longitud <- as.numeric(vf$longitud)
corregir_long <- function(longitud) {
if (abs(longitud) > 77) {
return(sprintf("%.3f", longitud / 1000))
} else {
return(longitud)
}
}
vf$longitud <- sapply(vf$longitud, corregir_long)
#
#
corregir_lat <- function(latitud) {
if (abs(latitud) > 4) {
return(sprintf("%.3f", latitud / 1000))
} else {
return(latitud)
}
}
vf$latitud <- sapply(vf$latitud, corregir_lat)
vf$latitud <- as.double(vf$latitud)
vf$longitud <- as.double(vf$longitud)
vf_avg_price_by_barrio <- vf %>%
group_by(barrio) %>%
summarize(
avg_price = mean(preciom, na.rm = TRUE),
latitud = median(latitud),
longitud = median(longitud),
frecuencia = n()
)
library(leaflet)
library(dplyr)
# Crear un mapa
ap_map <- leaflet() %>%
setView(lng = -76.5225, lat = 3.43722, zoom = 12) %>% addTiles()
# Agregar marcadores al mapa
for (i in 1:nrow(vf_avg_price_by_barrio)) {
row <- vf_avg_price_by_barrio[i,]
ap_map <- addCircles(ap_map,
lng = row$longitud,
lat = row$latitud,
weight = 1,
radius = sqrt(row$frecuencia) * 30,
popup = paste("<strong>Barrio: </strong>", row$barrio, "<br>",
"<strong>AVG precio: $</strong> ",round(row$avg_price), "' <br>",
"<strong>Q Predios: </strong>", row$frecuencia))
}
# Mostrar el mapa
print(ap_map)
ap_map