library(readxl)
library(dplyr)
library(ggplot2)
library(janitor)
library(qqplotr)
library(car)
library(sf)
library(digest)
library(viridisLite)
library(viridis)
library(rgeoda)
library(viridisLite)
library(viridis)
library(gridExtra)
library(dlookr)
library(spdep)
library(sp)
library(tidyverse)
library(sf)
library(corrplot)file_path<- "/Users/marianaaleal/Desktop/TEC 2025/_Planeación estratégica basada en analítica prescriptiva /M1/tourism_state_data.xlsx"
df <- read_excel("/Users/marianaaleal/Desktop/TEC 2025/_Planeación estratégica basada en analítica prescriptiva /M1/tourism_state_data.xlsx")
mxstates <- sf::read_sf("/Users/marianaaleal/Desktop/TEC 2025/_Planeación estratégica basada en analítica prescriptiva /M1/mx_shapefiles/states/mexlatlong.shp")ESDA son las siglas de Exploratory Spatial Data Analysis (Análisis Espacial Exploratorio de Datos, en español). Es una técnica de análisis de datos, que se utiliza principalemnte para explorar y analizar la estructura espacial de los datos, es decir, cómo se distribuyen los datos en el espacio. El propósito principal del ESDA es ayudar a identificar patrones espaciales y tendencias en los datos, lo que puede ser útil para entender mejor las relaciones espaciales entre las variables y para tomar decisiones informadas basadas en la ubicación geográfica.
La autocorrelación espacial es la relación que existe entre los valores de una variable en ubicaciones geográficas cercanas. Es decir, si los valores similares (altos o bajos) de una variable tienden a agruparse en el espacio, habrá autocorrelación espacial positiva; si, por el contrario, valores altos están rodeados de bajos y viceversa, será negativa.
Ejemplos: - Contaminación del aire: Si en una ciudad las zonas industriales tienen altos niveles de contaminación y estas están agrupadas en una misma área, mientras que las zonas residenciales lejanas presentan valores bajos, existe autocorrelación espacial positiva.
gráfico de barras, etc.).
## state year state_id tourism_gdp
## Length:544 Min. :2006 Min. : 888 Min. : 6240
## Class :character 1st Qu.:2010 1st Qu.:1047 1st Qu.: 22685
## Mode :character Median :2014 Median :1081 Median : 32482
## Mean :2014 Mean :1219 Mean : 56520
## 3rd Qu.:2018 3rd Qu.:1118 3rd Qu.: 59014
## Max. :2022 Max. :2357 Max. :472642
## crime_rate college_education unemployment employment
## Min. : 1.710 Min. :0.08751 Min. :0.01000 Min. :0.8900
## 1st Qu.: 8.107 1st Qu.:0.16703 1st Qu.:0.03000 1st Qu.:0.9500
## Median : 13.880 Median :0.20304 Median :0.04000 Median :0.9700
## Mean : 22.163 Mean :0.21106 Mean :0.04251 Mean :0.9639
## 3rd Qu.: 26.314 3rd Qu.:0.25085 3rd Qu.:0.05000 3rd Qu.:0.9754
## Max. :181.510 Max. :0.43761 Max. :0.10000 Max. :0.9928
## business_activity real_wage pop_density good_governance
## Min. :-2.980 Min. :239.3 Min. : 7.74 Min. : 0.000
## 1st Qu.:-2.260 1st Qu.:282.5 1st Qu.: 39.56 1st Qu.: 0.180
## Median :-2.070 Median :306.2 Median : 61.77 Median : 0.500
## Mean :-1.757 Mean :314.9 Mean : 299.46 Mean : 2.362
## 3rd Qu.:-1.768 3rd Qu.:335.4 3rd Qu.: 150.46 3rd Qu.: 1.350
## Max. : 2.470 Max. :481.7 Max. :6211.45 Max. :200.020
## ratio_public_investment exchange_rate inpc border_distance
## Min. :0.000000 Min. :10.85 Min. : 62.69 Min. : 8.83
## 1st Qu.:0.000000 1st Qu.:12.87 1st Qu.: 74.93 1st Qu.: 613.26
## Median :0.000000 Median :14.51 Median : 87.19 Median : 751.64
## Mean :0.005736 Mean :15.91 Mean : 89.08 Mean : 704.92
## 3rd Qu.:0.010000 3rd Qu.:19.47 3rd Qu.:103.02 3rd Qu.: 875.76
## Max. :0.067644 Max. :20.52 Max. :126.48 Max. :1252.66
## region...17 region...18
## Length:544 Min. :1.000
## Class :character 1st Qu.:2.000
## Mode :character Median :3.000
## Mean :3.188
## 3rd Qu.:4.250
## Max. :5.000
# Estadísticos Descriptivos por Región
df%>%
group_by(state) %>%
summarise(across(
.cols = c(tourism_gdp, crime_rate, college_education),
.fns = list(media = mean, mediana = median, min = min, max = max),
.names = "{.col}_{.fn}"
))## # A tibble: 32 × 13
## state tourism_gdp_media tourism_gdp_mediana tourism_gdp_min tourism_gdp_max
## <chr> <dbl> <dbl> <dbl> <dbl>
## 1 Aguasc… 14123. 14181. 11653. 17031.
## 2 Baja C… 54418. 53844. 45555. 69966.
## 3 Baja C… 28144. 28776. 22508. 33404.
## 4 Campec… 13426. 13444. 10338. 14840.
## 5 Chiapas 31402. 31250. 22730. 41871.
## 6 Chihua… 33688. 33296. 26120. 48140.
## 7 Ciudad… 392386. 390808. 262272. 472642.
## 8 Coahui… 28284. 27807. 22933. 31420.
## 9 Colima 8448. 8631. 6240. 9167.
## 10 Durango 11045. 11115. 8618. 13404.
## # ℹ 22 more rows
## # ℹ 8 more variables: crime_rate_media <dbl>, crime_rate_mediana <dbl>,
## # crime_rate_min <dbl>, crime_rate_max <dbl>, college_education_media <dbl>,
## # college_education_mediana <dbl>, college_education_min <dbl>,
## # college_education_max <dbl>
# Histograma Global – PIB Turístico
ggplot(df, aes(x = tourism_gdp)) +
geom_histogram(fill = "skyblue", color = "black") +
labs(title = "Distribución del PIB Turístico", x = "PIB Turístico", y = "Frecuencia") # Gráfico de Barras – PIB Promedio por Región
ggplot(df, aes(x = state, y = tourism_gdp)) +
stat_summary(fun = "mean", geom = "bar", fill = "pink", color = "black") +
labs(title = "PIB Turístico Promedio por Región", x = "Región", y = "PIB Promedio") +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Gráfico de Barrasstate# Gráfico de Barras – Tasa de Crimen por Región
ggplot(df, aes(x = state, y = crime_rate)) +
stat_summary(fun = "mean", geom = "bar", fill = "purple", color = "black") +
labs(title = "Tasa de Crimen Promedio por Región", x = "Región", y = "Tasa de Crimen")
#### b.Estadísticos de Dispersión (Global y Regional). Incluir elementos
gráficos (box plots, qq -plots, etc.).
# Estadísticos de dispersión globales
dispersion_global <- df%>%
summarise(across(where(is.numeric), list(
media = mean,
mediana = median,
sd = sd,
var = var,
iqr = IQR
), .names = "{.col}_{.fn}"))
print("Estadísticos de dispersión globales:")## [1] "Estadísticos de dispersión globales:"
## # A tibble: 1 × 80
## year_media year_mediana year_sd year_var year_iqr state_id_media
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2014 2014 4.90 24.0 8 1219.
## # ℹ 74 more variables: state_id_mediana <dbl>, state_id_sd <dbl>,
## # state_id_var <dbl>, state_id_iqr <dbl>, tourism_gdp_media <dbl>,
## # tourism_gdp_mediana <dbl>, tourism_gdp_sd <dbl>, tourism_gdp_var <dbl>,
## # tourism_gdp_iqr <dbl>, crime_rate_media <dbl>, crime_rate_mediana <dbl>,
## # crime_rate_sd <dbl>, crime_rate_var <dbl>, crime_rate_iqr <dbl>,
## # college_education_media <dbl>, college_education_mediana <dbl>,
## # college_education_sd <dbl>, college_education_var <dbl>, …
#Estadísticos de dispersión por región
dispersion_regional <- df%>%
group_by(state) %>%
summarise(across(where(is.numeric), list(
media = mean,
mediana = median,
sd = sd,
var = var,
iqr = IQR
), .names = "{.col}_{.fn}"))
print("Estadísticos de dispersión por región:")## [1] "Estadísticos de dispersión por región:"
## # A tibble: 32 × 81
## state year_media year_mediana year_sd year_var year_iqr state_id_media
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Aguascalien… 2014 2014 5.05 25.5 8 1057
## 2 Baja Califo… 2014 2014 5.05 25.5 8 2304
## 3 Baja Califo… 2014 2014 5.05 25.5 8 2327
## 4 Campeche 2014 2014 5.05 25.5 8 1086
## 5 Chiapas 2014 2014 5.05 25.5 8 1182
## 6 Chihuahua 2014 2014 5.05 25.5 8 888
## 7 Ciudad de M… 2014 2014 5.05 25.5 8 1114
## 8 Coahuila 2014 2014 5.05 25.5 8 933
## 9 Colima 2014 2014 5.05 25.5 8 1111
## 10 Durango 2014 2014 5.05 25.5 8 1004
## # ℹ 22 more rows
## # ℹ 74 more variables: state_id_mediana <dbl>, state_id_sd <dbl>,
## # state_id_var <dbl>, state_id_iqr <dbl>, tourism_gdp_media <dbl>,
## # tourism_gdp_mediana <dbl>, tourism_gdp_sd <dbl>, tourism_gdp_var <dbl>,
## # tourism_gdp_iqr <dbl>, crime_rate_media <dbl>, crime_rate_mediana <dbl>,
## # crime_rate_sd <dbl>, crime_rate_var <dbl>, crime_rate_iqr <dbl>,
## # college_education_media <dbl>, college_education_mediana <dbl>, …
# Boxplots por región
ggplot(df, aes(x = state, y = tourism_gdp)) +
geom_boxplot(fill = "skyblue") +
theme_minimal() +
labs(title = "Boxplot del PIB turístico por región", y = "tourism_gdp")# QQ-Plot para real_wage
qqPlot(df$real_wage,
main = "QQ-Plot: real_wage",
ylab = "Cuantiles reales",
xlab = "Cuantiles teóricos")## [1] 519 487
# QQ-plots por región
df%>%
group_by(state) %>%
do({
region_data <- .
qqPlot(region_data$real_wage, main = paste("QQ-Plot:", unique(region_data$region)))
data.frame()
})## # A tibble: 0 × 1
## # Groups: state [0]
## # ℹ 1 variable: state <chr>
# 1. Cargar shapefile de México (previamente importado como objeto sf)
statesmx <- st_read("/Users/marianaaleal/Desktop/TEC 2025/_Planeación estratégica basada en analítica prescriptiva /M1/mx_shapefiles/states/mexlatlong.shp")## Reading layer `mexlatlong' from data source
## `/Users/marianaaleal/Desktop/TEC 2025/_Planeación estratégica basada en analítica prescriptiva /M1/mx_shapefiles/states/mexlatlong.shp'
## using driver `ESRI Shapefile'
## Simple feature collection with 32 features and 19 fields
## Geometry type: MULTIPOLYGON
## Dimension: XY
## Bounding box: xmin: -118.4042 ymin: 14.55055 xmax: -86.73862 ymax: 32.71846
## Geodetic CRS: WGS 84
names(df)[names(df) == "state_id"] <- "OBJECTID"
# Unir los datos con la geometría
data_sf <- merge(statesmx, df, by = "OBJECTID")
#GEOOOOO #fill cpn variable
# Mapa de una variable de interés
ggplot(data_sf) +
geom_sf(aes(fill = tourism_gdp)) +
scale_fill_viridis_c() +
theme_minimal() +
labs(title = "Distribución espacial de tourism_gdp", fill = "Valor")library(sf)
#df <- st_as_sf(df)
library(sp)
turismo.tr <- as(data_sf, "Spatial") # Conversión correcta
turismo_nb<-poly2nb(turismo.tr)
#Crear matriz de pesos espaciales (contigüidad Queen)
queen1 <- poly2nb(data_sf, queen = TRUE) ### queen approach
queen2 <- poly2nb(data_sf, queen = FALSE) ### rook approach
centroides<-coordinates(turismo.tr)
mapa.linkW<-nb2listw(turismo_nb, style="W") ###
plot(turismo.tr,border="blue",axes=FALSE,las=1, main="Matriz de Conectividad - Turismo MX")
plot(turismo.tr,col="grey",border=grey(0.9),axes=T,add=T)
plot(mapa.linkW,coords=centroides,pch=19,cex=0.1,col="red",add=T)queen1 <- poly2nb(turismo.tr, queen = TRUE) ### queen approach
queen2 <- poly2nb(turismo.tr, queen = FALSE) ### rook approach
queenr <- nb2listw(queen1, style = "W", zero.policy = TRUE)
rook <- nb2listw(queen2, style = "W", zero.policy = TRUE)
plot(turismo.tr,border="blue",axes=FALSE,las=1, main="Matriz Espacial de Conexión - Queen")
plot(turismo.tr,col="grey",border=grey(0.9),axes=T,add=T)
plot(queenr,centroides, add=TRUE, col='blue')plot(turismo.tr,border="blue",axes=FALSE,las=1, main="Matriz Espacial de Conexión - Rook")
plot(turismo.tr,col="grey",border=grey(0.9),axes=T,add=T)
plot(rook,centroides, add=TRUE, col='dark green')# Hicimos una matriz de correlación para identificar las variables más relevantes en nuestro df.
numericas <- data_sf %>%
st_drop_geometry() %>%
select(where(is.numeric))
cor_matrix <- cor(numericas, use = "complete.obs")
corrplot(cor_matrix, method = "color", type = "upper", tl.col = "black")La matriz de correlación revela relaciones significativas entre variables socioeconómicas clave. Destaca una correlación positiva entre el empleo, la educación universitaria y los salarios reales, lo que sugiere que las regiones con mayor nivel educativo tienden a tener mejores condiciones laborales y salariales. A su vez, el desempleo muestra correlaciones negativas con estas mismas variables, indicando que su aumento está asociado a contextos de menor desarrollo. También se observan asociaciones positivas entre la densidad poblacional, la actividad económica y el empleo, lo cual refuerza la idea de que las zonas más dinámicas y pobladas concentran mayores oportunidades laborales. En conjunto, estos patrones reflejan una estructura territorial donde el bienestar económico está fuertemente vinculado al acceso a la educación, el empleo y la calidad institucional.
# Instala los paquetes si no los tienes
#install.packages("spdep")
#install.packages("sf")
# Carga las librerías
library(sf)
library(spdep)
# 1. Crear matriz de vecinos espaciales
neighbors <- poly2nb(data_sf) # contigüidad de tipo "queen"
weights_list <- nb2listw(neighbors, style = "W") # matriz de pesos normalizada
# 2. Calcular el estadístico I de Moran para cada variable
# real_wage
moran_real_wage <- moran.test(data_sf$real_wage, listw = weights_list)
print(moran_real_wage)##
## Moran I test under randomisation
##
## data: data_sf$real_wage
## weights: weights_list
##
## Moran I statistic standard deviate = 36.399, p-value < 2.2e-16
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic Expectation Variance
## 2.259369e-01 -1.841621e-03 3.916019e-05
# college_education
moran_college <- moran.test(data_sf$college_education, listw = weights_list)
print(moran_college)##
## Moran I test under randomisation
##
## data: data_sf$college_education
## weights: weights_list
##
## Moran I statistic standard deviate = 34.318, p-value < 2.2e-16
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic Expectation Variance
## 2.130708e-01 -1.841621e-03 3.921783e-05
moran.plot(data_sf$college_education, listw = weights_list, main = "Moran's Scatterplot: College Education")# unemployment
moran_unemployment <- moran.test(data_sf$unemployment, listw = weights_list)
print(moran_unemployment)##
## Moran I test under randomisation
##
## data: data_sf$unemployment
## weights: weights_list
##
## Moran I statistic standard deviate = 8.5677, p-value < 2.2e-16
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic Expectation Variance
## 5.179144e-02 -1.841621e-03 3.918674e-05
Interpretación: Global MoranI: Es una medida de autocorrelación espacial, es decir, si los valores altos o bajos de una variable están agrupados en ciertas áreas o distribuidos aleatoriamente.
¿Qué indican estos resultados? Moran I Statistic: Un valor positivo significa que hay un patrón espacial, es decir, que las zonas con valores altos están cerca de otras zonas con valores altos y lo mismo con los valores bajos.
P-Values: Moran’s I mide autocorrelación espacial, por lo que el valor de una región se relaciona con los valores de las regiones vecinas.
Salarios reales (real_wage): La autocorrelación positiva significa que los lugares con salarios altos están rodeados de otros lugares con salarios altos, y los bajos con bajos.
Educación universitaria (college_education): Zonas con alto nivel educativo están cerca de otras con alto nivel educativo, y lo mismo para las de bajo nivel.
Desempleo (unemployment): Aunque el valor es menor, sigue indicando que las zonas con alto desempleo tienden a estar cerca unas de otras.
library(sf)
library(spdep)
library(ggplot2)
library(RColorBrewer)
# Variables a analizar
variables <- c("real_wage", "college_education", "unemployment")
# Crear una lista para guardar los gráficos
mapas <- list()
for (var in variables) {
# Cálculo de Moran Local (LISA)
lisa <- localmoran(data_sf[[var]], listw = weights_list)
# Ver nombres de columnas para evitar errores
print(colnames(lisa))
p_colname <- if ("Pr(z > 0)" %in% colnames(lisa)) "Pr(z > 0)" else "Pr(z != E(Ii))"
# Guardar valores en el dataframe
data_sf[[paste0(var, "_lisa_I")]] <- lisa[, "Ii"]
data_sf[[paste0(var, "_lisa_p")]] <- lisa[, p_colname]
# Clasificación de clusters
mean_var <- mean(data_sf[[var]], na.rm = TRUE)
data_sf[[paste0(var, "_cluster")]] <- "No Significativo"
data_sf[[paste0(var, "_cluster")]][data_sf[[paste0(var, "_lisa_p")]] < 0.05 &
data_sf[[var]] > mean_var &
data_sf[[paste0(var, "_lisa_I")]] > 0] <- "High-High"
data_sf[[paste0(var, "_cluster")]][data_sf[[paste0(var, "_lisa_p")]] < 0.05 &
data_sf[[var]] < mean_var &
data_sf[[paste0(var, "_lisa_I")]] > 0] <- "Low-Low"
data_sf[[paste0(var, "_cluster")]][data_sf[[paste0(var, "_lisa_p")]] < 0.05 &
data_sf[[var]] > mean_var &
data_sf[[paste0(var, "_lisa_I")]] < 0] <- "High-Low"
data_sf[[paste0(var, "_cluster")]][data_sf[[paste0(var, "_lisa_p")]] < 0.05 &
data_sf[[var]] < mean_var &
data_sf[[paste0(var, "_lisa_I")]] < 0] <- "Low-High"
# Convertir a factor
data_sf[[paste0(var, "_cluster")]] <- as.factor(data_sf[[paste0(var, "_cluster")]])
# Crear mapa
mapa <- ggplot(data_sf) +
geom_sf(aes(fill = !!sym(paste0(var, "_cluster"))), color = "white", size = 0.3) +
scale_fill_manual(
values = c("No Significativo" = "lightgrey",
"High-High" = "#D73027", # Rojo oscuro elegante
"Low-Low" = "#4575B4", # Azul sofisticado
"High-Low" = "#F46D43", # Naranja tierra
"Low-High" = "#74ADD1"), # Azul celeste suave
labels = c("No Significativo", "Alto-Alto", "Bajo-Bajo", "Alto-Bajo", "Bajo-Alto")
) +
labs(
title = paste("Mapa de Clusters LISA -", var),
fill = "Tipo de Clúster"
) +
theme_minimal(base_size = 14) +
theme(
plot.title = element_text(face = "bold", hjust = 0.5, size = 16),
legend.position = "right",
legend.title = element_text(face = "bold"),
legend.background = element_rect(fill = "white", color = NA)
)
# Guardar mapa en la lista
mapas[[var]] <- mapa
}## [1] "Ii" "E.Ii" "Var.Ii" "Z.Ii"
## [5] "Pr(z != E(Ii))"
## [1] "Ii" "E.Ii" "Var.Ii" "Z.Ii"
## [5] "Pr(z != E(Ii))"
## [1] "Ii" "E.Ii" "Var.Ii" "Z.Ii"
## [5] "Pr(z != E(Ii))"
## $real_wage
##
## $college_education
##
## $unemployment
🔴 High-High (Alto-Alto) Regiones con valores altos de la variable y rodeadas por regiones similares.
Estados con altos salarios reales, mayor educación universitaria o bajo desempleo.
Zonas con economías dinámicas y sectores industriales o de servicios bien desarrollados.
Alta concentración de talento y oportunidades laborales.
Infraestructura avanzada y acceso a servicios públicos de calidad.
🔵 Low-Low (Bajo-Bajo) - Regiones con valores bajos de la variable y rodeadas por regiones similares.
Áreas con bajos salarios reales, baja educación universitaria o alto desempleo.
Falta de inversión en infraestructura y educación.
Predominio de sectores económicos informales o de baja productividad.
Mayor vulnerabilidad a crisis económicas y dificultades para atraer inversión.
🟠 High-Low (Alto-Bajo) - Regiones con valores altos de la variable rodeadas por regiones con valores bajos.
Pueden ser centros urbanos o industriales rodeados por zonas rurales o menos desarrolladas.
Zonas con fuertes disparidades económicas entre municipios vecinos.
Atracción de migración interna por mejores oportunidades laborales y educativas.
Posibles efectos de gentrificación o desplazamiento de la población local.
🔵 Low-High (Bajo-Alto) - Regiones con valores bajos de la variable rodeadas por regiones con valores altos.
Municipios rezagados dentro de un entorno de alto desarrollo.
Puede indicar zonas que aún no han recibido inversiones o beneficios del crecimiento económico regional.
Oportunidad para estrategias de desarrollo dirigidas (infraestructura, educación, incentivos para inversión).
Posibles brechas en acceso a servicios públicos y conectividad con centros económicos cercanos.
El turismo y desarrollo económico son desiguales. Se requieren estrategias regionales para equilibrar crecimiento.
• Siabato, W., & Guzmán-Manrique, J. (2019). La autocorrelación espacial y el desarrollo de la geografía cuantitativa. Cuadernos De Geografía Revista Colombiana De Geografía, 28(1), 1–22. https://doi.org/10.15446/rcdg.v28n1.76919
• Dall’erba, S. (2009). Exploratory Spatial data analysis. In Elsevier eBooks (pp. 683–690). https://doi.org/10.1016/b978-008044910-4.00433-8