Librerías

Para la instalación de librerias necesarias, se crea una función para facilitar el proceso y se instalan todas la librerías necesarias para evitar redundancia en el documento.

cargar_libreria <- function(paquete) {
  # Función para cargar una librería de R
  if (!requireNamespace(paquete, quietly = TRUE)) {
    # Verifica si el paquete no está cargado y lo instala si es necesario
    install.packages(paquete)
  } else {
    # Si el paquete ya está instalado, muestra un mensaje indicándolo
    message(paste("La librería", paquete, "ya está instalada."))
  }
}

suppressMessages({
  suppressWarnings({
      # Cargar librerías con supresión de mensajes y advertencias
      cargar_libreria("readxl")  
      cargar_libreria("sf")      
      cargar_libreria("ggplot2") 
      cargar_libreria("ggtext")  
      cargar_libreria("dplyr")   
      cargar_libreria("plotly")  
      cargar_libreria("patchwork") 
      library(patchwork)
      require(plotly)            
      library(plotly)           
      library(dplyr)            
      library(readxl)           
      library(sf)                
      library(ggplot2)           
      library(ggtext)            
  })
})

Cargue de insumos

Los dos insumos a utilizar son:

ruta_zip <- "mc_comunas.zip"  # Ruta del archivo ZIP que contiene los datos del shapefile
unzip(ruta_zip, exdir = "shape_comunas")  # Descomprimir el archivo ZIP en el directorio "shape_comunas"

datos_shape <- st_read("shape_comunas/mc_comunas.shp")  # Leer el archivo shapefile (.shp) y cargar los datos
## Reading layer `mc_comunas' from data source 
##   `C:\Users\jmont\OneDrive\Escritorio\3. ESTUDIOS\Analisis de información Geográfica y Espaciales\M1_Unidad 1 Introducción a la estadistica espacial\Desarrollo\shape_comunas\mc_comunas.shp' 
##   using driver `ESRI Shapefile'
## Simple feature collection with 22 features and 4 fields
## Geometry type: POLYGON
## Dimension:     XY
## Bounding box:  xmin: 1054098 ymin: 860192.1 xmax: 1068492 ymax: 879441.5
## Projected CRS: MAGNA-SIRGAS / Cali urban grid
suppressMessages({
  suppressWarnings({
    # Leer el archivo de Excel "EncuestaOrigenDestino.xlsx" sin mostrar mensajes ni advertencias
    Encuesta <- read_excel("EncuestaOrigenDestino.xlsx")
  })
})

Preparación de los datos

Para realizar el ejercicio se requiere:

Información espacial de las comunas: Archivo ShapeFile llamado “datos_shape”

Información alfanumérica de la encuesta: Atributos relacionados a trayectos únicamente de la ciudad de Cali.

Comuna Origen
Comuna Destino
Tipo de Vehículo
# Definir las columnas de interés para la Encuesta
columnas_de_interes <- c("ID ESTACIÓN", "TIPO DE VEHÍCULO", "comuna origen", "comuna destino")

# Crear un nuevo dataframe con las columnas de interés de la Encuesta
Encuesta_filtrada <- Encuesta[columnas_de_interes]

# Filtrar las filas donde la comuna de origen no sea "Fuera de Cali"
Encuesta_filtrada <- subset(Encuesta_filtrada, Encuesta_filtrada$`comuna origen` != "Fuera de Cali")

# Filtrar las filas donde la comuna de destino no sea "Fuera de Cali"
Encuesta_filtrada <- subset(Encuesta_filtrada, Encuesta_filtrada$`comuna destino` != "Fuera de Cali")

# Convertir las columnas de comuna de origen y destino a tipo entero
Encuesta_filtrada$`comuna origen` <- as.integer(Encuesta_filtrada$`comuna origen`)
Encuesta_filtrada$`comuna destino` <- as.integer(Encuesta_filtrada$`comuna destino`)

# Imprimir el dataframe filtrado
print(Encuesta_filtrada)
## # A tibble: 23,372 × 4
##    `ID ESTACIÓN` `TIPO DE VEHÍCULO` `comuna origen` `comuna destino`
##            <dbl>              <dbl>           <int>            <int>
##  1             1                  2               2               22
##  2             1                  2               6                2
##  3             1                  3               6                4
##  4             1                  3               3                2
##  5             1                  3               4                2
##  6             1                  3               6                2
##  7             1                  2               4                2
##  8             1                  2               2                3
##  9             1                  2              13                2
## 10             1                  3               6               19
## # ℹ 23,362 more rows

Mapa general

Se genera un mapa general mostrando las comunas de la ciudad de Cali.

# Crear un gráfico de ggplot utilizando los datos del shapefile y añadir un título
m1_comunas_gral <- ggplot(datos_shape) + 
  geom_sf(aes(fill = nombre), color = "grey") +  # Añadir polígonos de las comunas con el nombre de cada comuna
  geom_sf_text(aes(label = comuna), size = 3, color = "black", check_overlap = TRUE) +  # Añadir etiquetas de texto para las comunas
  theme_minimal() +  # Utilizar un tema minimalista para el gráfico
  theme(
    axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),  # Rotar etiquetas del eje x
    axis.title.x = element_blank(),  # Eliminar título del eje x
    axis.title.y = element_blank(),  # Eliminar título del eje y
    plot.title = element_text(hjust = 0.5)  # Ajustar la posición horizontal del título
  ) +
  labs(title = "Mapa de Comunas")  # Añadir un título al gráfico usando labs()

# Convertir el gráfico de ggplot a un objeto interactivo de Plotly
ggplotly(m1_comunas_gral)

A continuación se realizan algunas consultas con el objetivo de general los mapas de salidas y llegadas.

# Contar la cantidad de salidas desde cada comuna de origen y almacenar los resultados en un dataframe
conteo_origen <- as.data.frame(table(Encuesta_filtrada$`comuna origen`))

# Renombrar las columnas del dataframe de conteo de origen
names(conteo_origen) <- c("c_origen", "cantidad_salidas")

# Contar la cantidad de llegadas a cada comuna de destino y almacenar los resultados en un dataframe
conteo_destino <- as.data.frame(table(Encuesta_filtrada$`comuna destino`))

# Renombrar las columnas del dataframe de conteo de destino
names(conteo_destino) <- c("c_destino", "cantidad_llegadas")

# Fusionar los datos de conteo de origen con los datos del shapefile por la columna "comuna"
datos_shape <- merge(datos_shape, conteo_origen, by.x = "comuna", by.y = "c_origen", all = TRUE)

# Fusionar los datos de conteo de destino con los datos del shapefile por la columna "comuna"
datos_shape <- merge(datos_shape, conteo_destino, by.x = "comuna", by.y = "c_destino", all = TRUE)

# Filtrar las filas donde la comuna no sea "0"
datos_shape <- subset(datos_shape, comuna != "0")

Mapa general de Salidas y Llegadas

Se cambian parámetros de color, los atributos a mostrar en leyenda y ajuste de los títulos para generar las mapas con ggplot.

# Crear un gráfico de ggplot utilizando los datos fusionados
m1_comunas_gral2 <- ggplot(datos_shape) + 
  geom_sf(aes(fill = cantidad_salidas), color = "grey") +  # Añadir polígonos de las comunas con el número de salidas como variable de color
  geom_sf_text(aes(label = comuna), size = 3, color = "black", check_overlap = TRUE) +  # Añadir etiquetas de texto para las comunas
  scale_fill_gradient(low = "white", high = "skyblue") +  # Ajustar la paleta de colores para el relleno
  theme_minimal() +  # Utilizar un tema minimalista para el gráfico
  theme(
    axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),  # Rotar etiquetas del eje x
    axis.title.x = element_blank(),  # Eliminar título del eje x
    axis.title.y = element_blank(),  # Eliminar título del eje y
    plot.title = element_text(hjust = 0.5)  # Ajustar la posición horizontal del título
  ) +
  labs(title = "Mapa de salidas")  # Añadir un título al gráfico


# Crear un gráfico de ggplot utilizando los datos fusionados y añadir un título
m1_comunas_gral3 <- ggplot(datos_shape) + 
  geom_sf(aes(fill = cantidad_llegadas), color = "grey") +  # Añadir polígonos de las comunas con el número de llegadas como variable de color
  geom_sf_text(aes(label = comuna), size = 3, color = "black", check_overlap = TRUE) +  # Añadir etiquetas de texto para las comunas
  scale_fill_gradient(low = "white", high = "brown") +  # Ajustar la paleta de colores para el relleno
  theme_minimal() +  # Utilizar un tema minimalista para el gráfico
  theme(
    axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),  # Rotar etiquetas del eje x
    axis.title.x = element_blank(),  # Eliminar título del eje x
    axis.title.y = element_blank(),  # Eliminar título del eje y
    plot.title = element_text(hjust = 0.5)  # Ajustar la posición horizontal del título
  ) +
  labs(title = "Mapa de llegadas")  # Añadir un título al gráfico

Se combinan los mapas de ggplot con ggplotly para una visualización más agradable e interactiva.

# Convertir el gráfico de ggplot a un objeto interactivo de Plotly
ggplotly(m1_comunas_gral2)
# Convertir el gráfico de ggplot a un objeto interactivo de Plotly
ggplotly(m1_comunas_gral3)

Preparación de los datos

Se realizan transformaciones, agrupaciones por tipo de vehículo y se extraen sub conjuntos del datraframe Encuestas, especificamente para las comunas de origen, con el objetivo de unir dicha información con el archivo shapefile de comunas y lograr visualizaciones basadas en la frecuencia de viajes según el tipo de vehículo para cada comuna de la ciudad de Cali.

# Convertir la columna "TIPO DE VEHÍCULO" a tipo entero en el dataframe Encuesta_filtrada
Encuesta_filtrada$`TIPO DE VEHÍCULO` <- as.integer(Encuesta_filtrada$`TIPO DE VEHÍCULO`)

# Realizar el conteo de salidas por comuna de origen y tipo de vehículo
conteo_org <- Encuesta_filtrada %>%
  group_by(`comuna origen`, `TIPO DE VEHÍCULO`) %>%
  summarise(contador = n())
## `summarise()` has grouped output by 'comuna origen'. You can override using the
## `.groups` argument.
# Renombrar las columnas del dataframe de conteo de origen
nombres_nuevos <- c("comuna_org", "vehiculo", "cantidad_salidas")
colnames(conteo_org) <- nombres_nuevos

# Filtrar las filas correspondientes a bicicletas
conteo_org_bici <- subset(conteo_org, vehiculo == 1)

# Renombrar la columna de cantidad de salidas para bicicletas
conteo_org_bici <- conteo_org_bici %>%
  rename(cantidad_salidas_bici = cantidad_salidas) 

# Filtrar las filas correspondientes a motos
conteo_org_moto <- subset(conteo_org, vehiculo == 2)

# Renombrar la columna de cantidad de salidas para motos
conteo_org_moto <- conteo_org_moto %>%
  rename(cantidad_salidas_moto = cantidad_salidas)

# Filtrar las filas correspondientes a autos
conteo_org_auto <- subset(conteo_org, vehiculo == 3)

# Renombrar la columna de cantidad de salidas para autos
conteo_org_auto <- conteo_org_auto %>%
  rename(cantidad_salidas_auto = cantidad_salidas)

# Fusionar los datos de bicicletas con los datos del shapefile por la columna "comuna"
datos_shape <- merge(datos_shape, conteo_org_bici, by.x = "comuna", by.y = "comuna_org", all = TRUE)

# Fusionar los datos de motos con los datos del shapefile por la columna "comuna"
datos_shape <- merge(datos_shape, conteo_org_moto, by.x = "comuna", by.y = "comuna_org", all = TRUE)

# Fusionar los datos de autos con los datos del shapefile por la columna "comuna"
datos_shape <- merge(datos_shape, conteo_org_auto, by.x = "comuna", by.y = "comuna_org", all = TRUE)

# Eliminar las filas donde la comuna es "0"
datos_shape <- subset(datos_shape, comuna != "0")

Se cambian parámetros de color, los atributos a mostrar en leyenda y ajuste de los títulos para generar las mapas temáticos de salidas por tipo de vehículo con con ggplot.

# Crear un gráfico de ggplot para las salidas en bicicleta y añadir un título
m1_comunas_org_bici <- ggplot(datos_shape) + 
  geom_sf(aes(fill = cantidad_salidas_bici), color = "grey") +  # Añadir polígonos de las comunas con el número de salidas en bicicleta como variable de color
  geom_sf_text(aes(label = comuna), size = 3, color = "black", check_overlap = TRUE) +  # Añadir etiquetas de texto para las comunas
  scale_fill_gradient(low = "white", high = "red") +  # Ajustar la paleta de colores para el relleno
  theme_minimal() +  # Utilizar un tema minimalista para el gráfico
  theme(
    axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),  # Rotar etiquetas del eje x
    axis.title.x = element_blank(),  # Eliminar título del eje x
    axis.title.y = element_blank(),  # Eliminar título del eje y
    plot.title = element_text(hjust = 0.5)  # Ajustar la posición horizontal del título
  ) +
  labs(title = "Mapa de salidas en bicicleta")  # Añadir un título al gráfico

# Crear un gráfico de ggplot para las salidas en motocicleta y añadir un título
m1_comunas_org_moto <- ggplot(datos_shape) + 
  geom_sf(aes(fill = cantidad_salidas_moto), color = "grey") +  # Añadir polígonos de las comunas con el número de salidas en motocicleta como variable de color
  geom_sf_text(aes(label = comuna), size = 3, color = "black", check_overlap = TRUE) +  # Añadir etiquetas de texto para las comunas
  scale_fill_gradient(low = "white", high = "purple") +  # Ajustar la paleta de colores para el relleno
  theme_minimal() +  # Utilizar un tema minimalista para el gráfico
  theme(
    axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),  # Rotar etiquetas del eje x
    axis.title.x = element_blank(),  # Eliminar título del eje x
    axis.title.y = element_blank(),  # Eliminar título del eje y
    plot.title = element_text(hjust = 0.5)  # Ajustar la posición horizontal del título
  ) +
  labs(title = "Mapa de salidas en motocicleta")  # Añadir un título al gráfico

# Crear un gráfico de ggplot para las salidas en automóvil y añadir un título
m1_comunas_org_auto <- ggplot(datos_shape) + 
  geom_sf(aes(fill = cantidad_salidas_auto), color = "grey") +  # Añadir polígonos de las comunas con el número de salidas en automóvil como variable de color
  geom_sf_text(aes(label = comuna), size = 3, color = "black", check_overlap = TRUE) +  # Añadir etiquetas de texto para las comunas
  scale_fill_gradient(low = "white", high = "turquoise") +  # Ajustar la paleta de colores para el relleno
  theme_minimal() +  # Utilizar un tema minimalista para el gráfico
  theme(
    axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),  # Rotar etiquetas del eje x
    axis.title.x = element_blank(),  # Eliminar título del eje x
    axis.title.y = element_blank(),  # Eliminar título del eje y
    plot.title = element_text(hjust = 0.5)  # Ajustar la posición horizontal del título
  ) +
  labs(title = "Mapa de salidas en automóvil")  # Añadir un título al gráfico

Se realizan transformaciones, agrupaciones por tipo de vehículo y se extraen sub conjuntos del datraframe Encuestas, especificamente para las comunas de destino, con el objetivo de unir dicha información con el archivo shapefile de comunas y lograr visualizaciones basadas en la frecuencia de viajes según el tipo de vehículo para cada comuna de la ciudad de Cali.

# Realizar el conteo de llegadas por comuna de destino y tipo de vehículo
conteo_des <- Encuesta_filtrada %>%
  group_by(`comuna destino`, `TIPO DE VEHÍCULO`) %>%
  summarise(contador = n())
## `summarise()` has grouped output by 'comuna destino'. You can override using
## the `.groups` argument.
# Renombrar las columnas del dataframe de conteo de destino
nombres_nuevos <- c("comuna_dest", "vehiculo", "cantidad_llegadas") 
colnames(conteo_des) <- nombres_nuevos

# Filtrar las filas correspondientes a bicicletas
conteo_des_bici <- subset(conteo_des, vehiculo == 1)

# Renombrar la columna de cantidad de llegadas para bicicletas
conteo_des_bici <- conteo_des_bici %>%
  rename(cantidad_llegadas_bici = cantidad_llegadas ) 

# Filtrar las filas correspondientes a motos
conteo_des_moto <- subset(conteo_des, vehiculo == 2)

# Renombrar la columna de cantidad de llegadas para motos
conteo_des_moto <- conteo_des_moto %>%
  rename(cantidad_llegadas_moto = cantidad_llegadas)

# Filtrar las filas correspondientes a autos
conteo_des_auto <- subset(conteo_des, vehiculo == 3)

# Renombrar la columna de cantidad de llegadas para autos
conteo_des_auto <- conteo_des_auto %>%
  rename(cantidad_llegadas_auto = cantidad_llegadas)

# Fusionar los datos de bicicletas con los datos del shapefile por la columna "comuna"
datos_shape <- merge(datos_shape, conteo_des_bici, by.x = "comuna", by.y = "comuna_dest", all = TRUE)
## Warning in merge.data.frame(datos_shape, conteo_des_bici, by.x = "comuna", :
## column names 'vehiculo.x', 'vehiculo.y' are duplicated in the result
# Fusionar los datos de motos con los datos del shapefile por la columna "comuna"
datos_shape <- merge(datos_shape, conteo_des_moto, by.x = "comuna", by.y = "comuna_dest", all = TRUE)

# Fusionar los datos de autos con los datos del shapefile por la columna "comuna"
datos_shape <- merge(datos_shape, conteo_des_auto, by.x = "comuna", by.y = "comuna_dest", all = TRUE)
## Warning in merge.data.frame(datos_shape, conteo_des_auto, by.x = "comuna", :
## column names 'vehiculo.x', 'vehiculo.y' are duplicated in the result
# Eliminar las filas donde la comuna es "0"
datos_shape <- subset(datos_shape, comuna != "0")

Se cambian parámetros de color, los atributos a mostrar en leyenda y ajuste de los títulos para generar las mapas temáticos de llegadas por tipo de vehículo con con ggplot.

# Crear un gráfico de ggplot para las llegadas en bicicleta y añadir un título
m1_comunas_lleg_bici <- ggplot(datos_shape) + 
  geom_sf(aes(fill = cantidad_llegadas_bici), color = "grey") +  # Añadir polígonos de las comunas con el número de llegadas en bicicleta como variable de color
  geom_sf_text(aes(label = comuna), size = 3, color = "black", check_overlap = TRUE) +  # Añadir etiquetas de texto para las comunas
  scale_fill_gradient(low = "white", high = "red") +  # Ajustar la paleta de colores para el relleno
  theme_minimal() +  # Utilizar un tema minimalista para el gráfico
  theme(
    axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),  # Rotar etiquetas del eje x
    axis.title.x = element_blank(),  # Eliminar título del eje x
    axis.title.y = element_blank(),  # Eliminar título del eje y
    plot.title = element_text(hjust = 0.5)  # Ajustar la posición horizontal del título
  ) +
  labs(title = "Mapa de llegadas en bicicleta")  # Añadir un título al gráfico

# Crear un gráfico de ggplot para las llegadas en motocicleta y añadir un título
m1_comunas_lleg_moto <- ggplot(datos_shape) + 
  geom_sf(aes(fill = cantidad_llegadas_moto), color = "grey") +  # Añadir polígonos de las comunas con el número de llegadas en motocicleta como variable de color
  geom_sf_text(aes(label = comuna), size = 3, color = "black", check_overlap = TRUE) +  # Añadir etiquetas de texto para las comunas
  scale_fill_gradient(low = "white", high = "purple") +  # Ajustar la paleta de colores para el relleno
  theme_minimal() +  # Utilizar un tema minimalista para el gráfico
  theme(
    axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),  # Rotar etiquetas del eje x
    axis.title.x = element_blank(),  # Eliminar título del eje x
    axis.title.y = element_blank(),  # Eliminar título del eje y
    plot.title = element_text(hjust = 0.5)  # Ajustar la posición horizontal del título
  ) +
  labs(title = "Mapa de llegadas en motocicleta")  # Añadir un título al gráfico

# Crear un gráfico de ggplot para las llegadas en automóvil y añadir un título
m1_comunas_lleg_auto <- ggplot(datos_shape) + 
  geom_sf(aes(fill = cantidad_llegadas_auto), color = "grey") +  # Añadir polígonos de las comunas con el número de llegadas en automóvil como variable de color
  geom_sf_text(aes(label = comuna), size = 3, color = "black", check_overlap = TRUE) +  # Añadir etiquetas de texto para las comunas
  scale_fill_gradient(low = "white", high = "turquoise") +  # Ajustar la paleta de colores para el relleno
  theme_minimal() +  # Utilizar un tema minimalista para el gráfico
  theme(
    axis.text.x = element_text(angle = 90, vjust = 0.5, hjust=1),  # Rotar etiquetas del eje x
    axis.title.x = element_blank(),  # Eliminar título del eje x
    axis.title.y = element_blank(),  # Eliminar título del eje y
    plot.title = element_text(hjust = 0.5)  # Ajustar la posición horizontal del título
  ) +
  labs(title = "Mapa de llegadas en automovil")  # Añadir un título al gráfico

Se combinan los mapas de ggplot con ggplotly para una visualización más agradable e interactiva.

require(plotly)            
library(plotly)

ggplotly(m1_comunas_org_bici)
ggplotly(m1_comunas_lleg_bici)
ggplotly(m1_comunas_org_moto)
ggplotly(m1_comunas_lleg_moto)
ggplotly(m1_comunas_org_auto)
ggplotly(m1_comunas_lleg_auto)

Conclusiones