Los datos espaciales suelen ser más visibles en elementos poligonales con límites definidos. Los límites de estos los polígonos los definen los investigadores, sin embargo, en algunos campos de estudio pueden ser arbitrarios y en otros pueden ser límites administrativos creados para propósitos muy diferentes. Los datos observados a menudo se agrupan en límites, como por ejemplo la población. Las unidades territoriales pueden formar por sí mismas unidades de control, por ejemplo, examinando las acciones de las autoridades locales cuando se toman decisiones a nivel de unidad, como el establecimiento de tasas impositivas locales. Sin embargo, en general, las funciones de región son agregados, contenedores que se utilizan para calcular métricas como los resultados de encuestas. En la mayoría de los casos, un elemento de área es una subdivisión completa del área de estudio en la que cualquier parte del área total se asigna a una función. Desde luego, las características del área pueden constar de varios elementos geométricos, como islas que pertenecen a un solo condado; también, pueden cubrir completamente otras características del área y pueden contener agujeros como lagos.
Los límites de las áreas geográficas pueden ser establecidos con fines distintos a su utilización en el análisis de datos. Aunque las divisiones por códigos postales pueden resultar útiles en el análisis, fueron creadas originalmente para facilitar los envíos postales. Solo recientemente, las instituciones censales nacionales han reconocido que los cambios frecuentes e aparentemente justificados en los límites representan un problema importante para el análisis longitudinal. La naturaleza arbitraria de los límites de las unidades geográficas se convierte en un problema cuando su modificación puede dar lugar a resultados diferentes, como se ejemplifica en el caso del gerrymandering político, que nos sirve como un recordatorio revelador de cómo los cambios en la agrupación pueden alterar los resultados. Además, estos límites pueden dificultar el análisis si la escala espacial o la extensión de un proceso de generación de datos subyacente no se corresponden con los límites elegidos.
Si se diseña la recopilación de datos de manera que las entidades geográficas se alineen con los datos, se puede minimizar la influencia de la elección de los agregados. Un ejemplo de esto podría ser vincular los datos del mercado laboral con las áreas de mercado laboral local, que podrían definirse según los desplazamientos al trabajo. Sin embargo, cuando nos vemos obligados a utilizar límites arbitrarios, generalmente debido a la falta de otras fuentes de datos secundarios, debemos ser conscientes de las dificultades potenciales que esto conlleva. Estos desajustes son una de las razones por las cuales se encuentra autocorrelación espacial en el análisis de los agregados geográficos. Otras razones incluyen la influencia mutua entre las entidades debido a procesos espaciales contagiosos, como la adopción de políticas similares por parte de los vecinos, así como la especificación incorrecta del modelo, lo que puede dejar residuos con patrones espaciales. Identificar correctamente los procesos espaciales reales es una tarea interesante, ya que pueden ser causantes de la autocorrelación espacial observada.
Diversas disciplinas científicas han encontrado evidencia de autocorrelación espacial entre entidades geográficas, y este fenómeno se conoce como el “problema de Galton”, que ha sido abordado en varios contextos. Este problema se centra en determinar cuántas observaciones son verdaderamente independientes cuando se utilizan límites arbitrarios para dividir un área de estudio. En un intercambio de ideas con Tyler en 1889, Galton planteó la pregunta de si las observaciones de las leyes matrimoniales entre entidades geográficas constituían observaciones independientes, dado que podrían reflejar únicamente un patrón general de descendencia en todos los casos. Por lo tanto, la dependencia espacial positiva tiende a reducir la cantidad de información contenida en las observaciones, ya que las observaciones cercanas pueden ser utilizadas en parte para predecir unas a otras.
Se ha observado cómo las distancias en una superficie continua pueden ser utilizadas para establecer la autocorrelación espacial, como lo es el caso del variograma. En esta ocasión, nos centraremos en las entidades geográficas que se definen como vecinas. En una superficie continua, todos los puntos son vecinos entre sí, aunque algunos pueden tener un peso insignificante debido a su gran distancia. En una superficie discretizada, podemos elegir diferentes definiciones de vecindad que dividen el conjunto de todas las entidades (excluyendo la observación i) en miembros y no miembros del conjunto de vecinos de la observación i. Además, podemos decidir asignar a cada relación de vecindad un peso igual o variar los pesos en los arcos del grafo dirigido que describe la dependencia espacial.
En la siguiente sección, abordaremos la construcción de vecindarios y los pesos que se pueden aplicar a estas vecindades. Una vez que hayamos establecido este prerrequisito importante y a menudo exigente, procederemos a estudiar cómo medir la autocorrelación espacial. Si bien las pruebas se basan en modelos de procesos espaciales, primero examinaremos las pruebas y luego pasaremos a la modelización. También nos interesa explorar cómo podemos introducir la autocorrelación espacial en datos que inicialmente eran independientes, para así poder realizar simulaciones.
Es importante tener en cuenta que el patrón espacial que identifiquemos puede indicar que nuestro modelo actual de los datos no es adecuado. Esto puede deberse a unidades de área que no se ajustan al proceso de generación de datos, a variables faltantes, incluyendo aquellas con una forma funcional incorrecta, así como a las diferencias entre nuestras suposiciones sobre los datos y las distribuciones reales, las cuales a menudo se manifiestan como una dispersión excesiva en los datos de recuento.
Se empleará los datos de censo para 8 condados centrales de New York.
NY8 <- readOGR("data", "NY8_utm18")
## OGR data source with driver: ESRI Shapefile
## Source: "C:\Users\Usuario\Videos\trabajo3\data", layer: "NY8_utm18"
## with 281 features
## It has 17 fields
ny <- st_read("data/NY8_utm18.shp")
## Reading layer `NY8_utm18' from data source
## `C:\Users\Usuario\Videos\trabajo3\data\NY8_utm18.shp' using driver `ESRI Shapefile'
## Simple feature collection with 281 features and 17 fields
## Geometry type: POLYGON
## Dimension: XY
## Bounding box: xmin: 358241.9 ymin: 4649755 xmax: 480393.1 ymax: 4808545
## Projected CRS: WGS 84 / UTM zone 18N
plot(st_geometry(ny), axes = T)
La creación de pesos espaciales es un paso necesario en el análisis de datos en área. Para ello, primeramente se debe definir cuales relaciones entre las observaciones tendrán pesos no nulos, es decir, se debe escoger el criterio para que dos enlaces sean considerados como “vecinos”; el segundo paso es asignar los pesos a los enlaces identificados como “vecinos” en el paso anterior.
Este prceso no es facil y por ello existen varios métodos y funciones
en el paquete spdep que ayudan a facilitar este trabajo.
Además, el paquete ade4 tiene las funciones
nb2neig() y neig2nb(), las cuales ayudan a
transformar objetos entre las clases nb y
neig.
En el paquete spdep, las observaciones vinculadas o
vecinas se representan mediante objetos de clase nb. Estos
objetos se pueden visualizar como una lista de tamaño \(n\), donde cada elemento contiene un vector
con los índices de los vecinos correspondientes a esa observación. Si
alguna observación no tiene vecinos, la entrada correspondiente contiene
el valor cero (0). Además de estos índices de vecinos, los objetos nb
también pueden contener otros atributos, como un vector de caracteres
para identificar cada una de las regiones consideradas, y un vector
lógico (booleano) que indica si la relación entre observaciones es
simétrica o no (este aspecto se discute más adelante). La función
card() se utiliza para obtener el número de vecinos para
cada elemento de la lista (objeto nb). A continuación, se
presenta de manera concisa la estructura de estos objetos
espaciales.
NY_nb <- read.gal("data/NY_nb.gal", # read.gal carga el archivo de clase nb
region.id = as.numeric(row.names(ny)) - 1
) # Debe empezar en 0
summary(NY_nb)
## Neighbour list object:
## Number of regions: 281
## Number of nonzero links: 1522
## Percentage nonzero weights: 1.927534
## Average number of links: 5.41637
## Link number distribution:
##
## 1 2 3 4 5 6 7 8 9 10 11
## 6 11 28 45 59 49 45 23 10 3 2
## 6 least connected regions:
## 55 97 100 101 244 245 with 1 link
## 2 most connected regions:
## 34 82 with 11 links
plot(st_geometry(ny), border = "grey60", axes = T)
plot(NY_nb, st_geometry(ny), pch = 19, cex = 0.6, add = T)
Cabe resaltar, que un archivo gal es una matriz de pesos
o vecinos producida por el software GeoDa. Para esto, todas las regiones
contiguas son consideradas como “regiones vecinas”.
Una vez ilustrados los datos espaciales que van a ser utilizados, se
usará un subconjunto de ellos para mostrar el uso de las principales
funciones y métodos para los objetos nb, es decir, se usará
“Syracuse city”.
Syracuse <- filter(ny, AREANAME == "Syracuse city")
Sy0_nb <- subset(NY_nb, ny$AREANAME == "Syracuse city")
plot(st_geometry(Syracuse), border = "grey60", axes = T)
plot(Sy0_nb, st_geometry(Syracuse), pch = 19, cex = 0.6, add = T)
Se tiene que uno de los principales métodos de los objetos
nb son print(), summary() y
plot(), sin embargo, estos no son los únicos que existen;
tanto print como summary presentan el número
de regiones, enlaces no nulos, porcentaje de pesos no nulos y promedio
de enlaces entre regiones, sin embargo, summary presenta
adicionalmente la distribución del número de enlaces del objeto
nb, además, de las regiones con menor y mayor frecuencia de
enlaces dentro del objeto.
summary(Sy0_nb)
## Neighbour list object:
## Number of regions: 63
## Number of nonzero links: 346
## Percentage nonzero weights: 8.717561
## Average number of links: 5.492063
## Link number distribution:
##
## 1 2 3 4 5 6 7 8 9
## 1 1 5 9 14 17 9 6 1
## 1 least connected region:
## 164 with 1 link
## 1 most connected region:
## 136 with 9 links
El método summary también reporta la presencia o no de
asimetría en el objeto nb
La asimetria está presente cuando i es un vecino de j, pero j no es un vecino de i.
El método summary proporciona la siguiente
información:
Además, se muestra la distribución de las relaciones, lo que indica que el número máximo de vecinos encontrados fue 9, y esto ocurrió en relación con un polígono específico. Además, se observa que 17 de las 63 regiones presentes tienen 6 conexiones, y así sucesivamente.
La función card permite obtener rápidamente el número de
vecinos de cada región.
card(Sy0_nb)
## [1] 5 5 2 7 7 5 4 5 7 5 5 7 5 7 6 6 6 6 6 4 4 7 6 8 4 3 3 9 6 8 6 6 6 8 6 4 4 8
## [39] 6 6 7 5 7 6 4 5 3 5 6 4 6 7 4 8 5 1 5 8 5 5 6 3 3
En el documento, se generarán objetos de lista de vecinos para su uso posterior. Para ello, se utiliza la función knearneigh que nos permite obtener los índices de los puntos que son los \(k\) vecinos más cercanos. Esta función recibe como parámetros la lista de coordenadas de los puntos y el valor de \(k\), que indica el número de puntos vecinos cercanos que se desean obtener.
Una vez obtenido el resultado anterior, se pasa como entrada a la función knn2nb, que convierte el objeto resultante en una lista de vecinos de la clase nb. Esta transformación nos permite obtener un objeto nb que contiene la información sobre los vecinos de cada punto en forma de una lista.
coords <- st_point_on_surface(st_geometry(Syracuse))
ids <- row.names(Syracuse)
Sy8_nb <- knn2nb(knearneigh(coords, k = 1), row.names = ids)
Sy8_nb
## Neighbour list object:
## Number of regions: 63
## Number of nonzero links: 63
## Percentage nonzero weights: 1.587302
## Average number of links: 1
## Non-symmetric neighbours list
La función nbdists se utiliza para calcular las distancias entre los puntos de los objetos vecinos obtenidos en el paso anterior. Esta función es útil porque nos permite determinar la distancia mínima necesaria para garantizar que todas las áreas tengan al menos un vecino.
Después de calcular las distancias con nbdists, se emplea la función dnearneigh para obtener la lista de objetos vecinos (nb) que se encuentran a una distancia específica (d1, d2). Esto nos permite seleccionar los vecinos que se encuentran dentro de un rango determinado de distancias y obtener la lista correspondiente de vecinos para cada punto.
dsts <- unlist(nbdists(Sy8_nb, coords))
Sy11_nb <- dnearneigh(x = coords, d1 = 0, d2 = 0.75 * max(dsts))
Sy11_nb
## Neighbour list object:
## Number of regions: 63
## Number of nonzero links: 156
## Percentage nonzero weights: 3.930461
## Average number of links: 2.47619
## 8 regions with no links:
## 1 10 20 36 46 57 60 61
Como resultado, se observa que hay 8 regiones que no poseen vecinos (1, 10, 20…).
Resulta sorprendente que la literatura sobre pesos espaciales sea limitada, considerando la gran importancia que estos tienen al medir y modelar la dependencia espacial en datos de áreas. Los pesos espaciales desempeñan un papel fundamental en el análisis espacial al cuantificar la influencia de las observaciones vecinas en un determinado fenómeno. Estos pesos permiten capturar patrones de dependencia espacial y son utilizados en diversas técnicas, como la autocorrelación espacial, la regresión espacial y la interpolación espacial.
Aunque la importancia de los pesos espaciales es ampliamente reconocida en la comunidad científica, la disponibilidad de métodos y herramientas para su aplicación y la exploración de sus propiedades sigue siendo limitada. Es posible que esta falta de atención en la literatura se deba a la complejidad y la naturaleza multidimensional de los datos espaciales, así como a los desafíos metodológicos asociados con la selección y el cálculo de pesos espaciales adecuados.
A medida que el análisis espacial y el interés en comprender los patrones espaciales continúan creciendo en diferentes disciplinas, es necesario fomentar una mayor investigación y desarrollo en el campo de los pesos espaciales. Esto permitirá mejorar nuestra comprensión de la dependencia espacial y promover el uso adecuado de los pesos espaciales en el análisis y modelado de datos de áreas.
Los pesos espaciales pueden ser vistos como una lista de pesos indexada por una lista de vecinos. En este enfoque, el peso de la relación entre dos regiones, \(i\) y \(j\), se encuentra en el \(k\)-ésimo elemento del componente \(i\) de la lista de pesos.
Una vez que se ha definido la lista de vecinos espaciales, el siguiente paso consiste en asignar pesos a los enlaces entre las regiones. Si se cuenta con información relevante sobre el proceso espacial que se está analizando, esta información puede ser utilizada para asignar pesos a los enlaces. Sin embargo, si no se dispone de esta información, es recomendable evitar hacer suposiciones sobre los pesos para evitar problemas de mala especificación del modelo.
La función nb2listw se utiliza para convertir un objeto de lista de vecinos (nb) en un objeto de pesos. La conversión por defecto es un objeto de pesos denominado W, donde los pesos varían entre la unidad dividida por el número máximo y mínimo de vecinos, y la suma de los pesos para cada región es igual a la unidad. Esta conversión permite establecer una medida adecuada de la influencia espacial entre las regiones.
Sy0_lw_w <- nb2listw(neighbours = Sy0_nb)
Sy0_lw_w
## Characteristics of weights list object:
## Neighbour list object:
## Number of regions: 63
## Number of nonzero links: 346
## Percentage nonzero weights: 8.717561
## Average number of links: 5.492063
##
## Weights style: W
## Weights constants summary:
## n nn S0 S1 S2
## W 63 3969 63 24.78291 258.564
Existe otro tipo de conversión que se puede obtener al configurar el parámetro \(style = B\). En este caso, se asigna un peso de 1 a cada relación vecina y un peso de 0 para las relaciones que no son vecinas. Sin embargo, es importante tener en cuenta que en esta configuración, la suma de los pesos para cada área puede variar según el número de vecinos que tenga cada área.
Al establecer style = B, se crea un objeto de pesos que refleja únicamente la presencia o ausencia de una relación vecina entre las áreas. Cada relación vecina se representa con un peso de 1, lo que indica que existe una conexión directa entre las áreas correspondientes. Por otro lado, las relaciones que no son vecinas tienen asignado un peso de 0, indicando que no existe una conexión directa entre esas áreas.
Es recomendable utilizar pesos binarios cuando se tiene poco conocimiento acerca del proceso que se está estudiando.
El argumento glist proporciona la opción de asignar manualmente los pesos a cada enlace entre regiones en el objeto nb. Esta función resulta útil en situaciones en las que se dispone de información específica sobre las posibles relaciones entre dos regiones, lo cual puede contribuir a obtener resultados más precisos y adecuados a la situación particular. A continuación se presenta un ejemplo que ilustra el uso del argumento glist, suponiendo que los pesos siguen la regla IDW binaria (inverso de las distancias entre las regiones).
dsts <- nbdists(Sy0_nb, coords)
idw <- lapply(dsts, function(x) 1 / (x / 1000))
Sy0_lw_idwB <- nb2listw(Sy0_nb, glist = idw, style = "B")
summary(unlist(Sy0_lw_idwB$weights))
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.3062 0.7481 0.9547 1.0154 1.2232 2.7686
summary(sapply(Sy0_lw_idwB$weights, sum))
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1.321 4.129 5.896 5.577 6.967 9.860
Se presentan 3 tipos de pesos espaciales:
Sy0_lw_B <- nb2listw(Sy0_nb, style = "B")
pal <- brewer.pal(9, "Reds")
oopar <- par(mfrow = c(1, 3), mar = c(1, 1, 3, 1) + 0.1)
z <- t(listw2mat(Sy0_lw_w))
brks <- c(0, 0.1, 0.143, 0.167, 0.2, 0.5, 1)
nbr3 <- length(brks) - 3
image(1:63, 1:63, z[, ncol(z):1],
breaks = brks,
col = pal[c(1, (9 - nbr3):9)],
main = "W style", axes = FALSE
)
box()
z <- t(listw2mat(Sy0_lw_B))
image(1:63, 1:63, z[, ncol(z):1],
col = pal[c(1, 9)], main = "B style",
axes = FALSE
)
box()
z <- t(listw2mat(Sy0_lw_idwB))
brks <- c(0, 0.35, 0.73, 0.93, 1.2, 2.6)
nbr3 <- length(brks) - 3
image(1:63, 1:63, z[, ncol(z):1],
breaks = brks,
col = pal[c(1, (9 - nbr3):9)],
main = "IDW B style", axes = FALSE
)
box()
par(oopar)
El último argumento a tener en cuenta en la función nb2listw() es zero.policy. Cuando hay regiones que no tienen vecinos, es necesario especificar el argumento zero.policy = TRUE para evitar que se produzca un error. Esto se debe a que, por defecto, la función nb2listw() asume que cada región tiene al menos un vecino.
Al establecer zero.policy = TRUE, se le indica a la función que permita regiones sin vecinos y que no genere un error en tales casos. Esto es útil cuando se trabaja con conjuntos de datos en los que algunas regiones pueden no tener vecinos debido a su ubicación geográfica o a otras características particulares.
try(
expr = {
nb2listw(neighbours = Sy11_nb, style = "B", zero.policy = F)
}
)
## Error in nb2listw(neighbours = Sy11_nb, style = "B", zero.policy = F) :
## Empty neighbour sets found
Luego de especificar como verdadero dicho argumento, se obtiene el resultado, sin fallas computacionales:
Sy0_lw_D1 <- nb2listw(neighbours = Sy11_nb, style = "B", zero.policy = T)
print(Sy0_lw_D1, zero.policy = T)
## Characteristics of weights list object:
## Neighbour list object:
## Number of regions: 63
## Number of nonzero links: 156
## Percentage nonzero weights: 3.930461
## Average number of links: 2.47619
## 8 regions with no links:
## 1 10 20 36 46 57 60 61
##
## Weights style: B
## Weights constants summary:
## n nn S0 S1 S2
## B 55 3025 156 312 2240
Una vez que hemos construido diferentes tipos de pesos espaciales, podemos comenzar a utilizarlos para analizar la presencia de autocorrelación espacial. Sin embargo, antes de adentrarnos en un análisis más detallado, es importante revisar los supuestos subyacentes a las pruebas de autocorrelación espacial; utilizaremos la I de Moran como ejemplo, pero las consecuencias se aplican también a otras pruebas.
Existen dos tipos de test de autocorrelación espacial para este tipo de datos:
Test globales: Se utilizan para verificar si existe autocorrelación espacial entre dos o más regiones en algún lugar del área de estudio (no se especifica donde).
Test locales: Detectan clusters de vecinos con observaciones muy diferentes de los vecinos en general. Encuentran hotspots.
Basicamete, es la forma más común de abordar la autocorrelación espacial. Se calcula como la razón del producto de la variable de interés y su rezago espacial, con el producto cruzado de la variable de interés y ajustada por los pesos espaciales usados.
\[I = \frac{n}{\sum_{i=1}^{n} \sum_{j=1}^{n} w_{ij}}\ \frac{\sum_{i=1}^{n} \sum_{j=1}^{n} (y_i - \bar{y})(y_j - \bar{y})}{\sum_{i=1}^{n} (y_i - \bar{y})^2}\] donde:
Al enfocarnos en la media, estamos asumiendo que el modelo adecuado tiene una media constante, y cualquier patrón residual que persista después de centrar los datos se debe a las relaciones espaciales codificadas en los pesos espaciales.
Al centrar los datos, eliminamos la influencia de la media en el análisis, lo que nos permite examinar y evaluar específicamente los patrones espaciales presentes en los datos. Si después de centrar los datos aún se observa un patrón espacial significativo, esto sugiere que hay una estructura espacial más allá de las variaciones en la media.
Se calcula la esperanza como:
\[E(I) = \frac{-1}{n-1}\]
En el siguiente paso, procedemos restando el valor observado al valor esperado analíticamente (I - E(I)), y luego dividimos esta diferencia por la raíz cuadrada de la varianza analítica. El resultado obtenido se compara con la distribución normal para determinar el valor de probabilidad del estadístico observado, bajo la suposición nula de ausencia de dependencia espacial para los pesos espaciales seleccionados. Es importante tener en cuenta que los resultados pueden variar según las elecciones de las ponderaciones, los vecindarios y el cumplimiento de los supuestos requeridos.
\[H_0: Ausencia \ de \ dependencia \ espacial\] \[H_1: El \ estadístico \ observado \ es \ significativamente \ más \ grande \ que \ el \ valor \ esperado\]
Es importante tener en ceunta que el dominio del I de Moran es [-1, 1]. Además, se evidencia autocorrelación espacial positiva cuando I > 0. Esto permite concluir que las unidades de análisis vecinas tienden a ser similares.
moran.test(x = ny$Cases, listw = nb2listw(NY_nb))
##
## Moran I test under randomisation
##
## data: ny$Cases
## weights: nb2listw(NY_nb)
##
## Moran I statistic standard deviate = 3.9778, p-value = 3.477e-05
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic Expectation Variance
## 0.146882990 -0.003571429 0.001430595
Por defecto, al utilizar moran.test, se aplica el supuesto de aleatorización, lo cual difiere del supuesto más simple de normalidad al introducir un término de corrección basado en la curtosis de la variable de interés. Este enfoque considera que la distribución de la variable puede desviarse de la normalidad, y ajusta la varianza en consecuencia.
Cuando la curtosis de la variable se asemeja a la de una distribución normal, ambas suposiciones resultan en la misma varianza. Sin embargo, a medida que la variable se aleja de la normalidad, la suposición de aleatorización compensa este hecho aumentando la varianza y disminuyendo la desviación estándar.
moran.test(x = ny$Cases, listw = nb2listw(NY_nb), randomisation = F)
##
## Moran I test under normality
##
## data: ny$Cases
## weights: nb2listw(NY_nb)
##
## Moran I statistic standard deviate = 3.9731, p-value = 3.547e-05
## alternative hypothesis: greater
## sample estimates:
## Moran I statistic Expectation Variance
## 0.146882990 -0.003571429 0.001433975
Se observa que la varianza no cambia, por lo tanto, el supuesto de normalidad se cumple.
Es posible también realizar test de Monte Carlo para evaluar la hipótesis de dependencia espacial con el test de Moran I.
moran.mc(x = ny$Cases, listw = nb2listw(NY_nb), nsim = 999)
##
## Monte-Carlo simulation of Moran I
##
## data: ny$Cases
## weights: nb2listw(NY_nb)
## number of simulations + 1: 1000
##
## statistic = 0.14688, observed rank = 1000, p-value = 0.001
## alternative hypothesis: greater
Waller y Gotway (2004, p. 231) proponen un enfoque adicional para evaluar la autocorrelación en los recuentos de casos, utilizando un modelo de riesgo constante de Poisson. Este enfoque se basa en calcular una tasa global constante, denotada como \(r\), que se utiliza posteriormente para generar los recuentos esperados para cada unidad geográfica. Estos recuentos esperados se obtienen multiplicando la tasa global por la población correspondiente a cada área censal.
lw_B <- nb2listw(NY_nb, style = "B")
r <- sum(NY8$Cases)/sum(NY8$POP8)
rni <- r * NY8$POP8
CR <- function(var, mle) rpois(length(var), lambda = mle)
MoranI.pboot <- function(var, i, listw, n, S0, ...) {
return(moran(x = var, listw = listw, n = n, S0 = S0)$I)
}
set.seed(1234)
boot2 <- boot(NY8$Cases, statistic = MoranI.pboot,
R = 999, sim = "parametric", ran.gen = CR,
listw = lw_B, n = length(NY8$Cases), S0 = Szero(lw_B),
mle = rni)
pnorm((boot2$t0 - mean(boot2$t))/sd(boot2$t[, 1]), lower.tail = FALSE)
## [1] 0.1472112
Los recuentos esperados también pueden ser obtenidos como los valores ajustados de una regresión de Poisson, teniendo en cuenta un desplazamiento ajustado al logaritmo de la población de cada unidad geográfica. Este enfoque muestra una conexión con los modelos lineales generalizados. Sin embargo, es importante tener en cuenta que como los casos no siempre son números enteros, pueden generarse advertencias al aplicar este método.
Para generar los conjuntos de datos sintéticos, se utilizan los recuentos esperados rni como parámetros en la función rpois, que simula la distribución de Poisson. A partir de estos datos sintéticos, se calcula la probabilidad de salida, que se obtiene a partir de la diferencia entre el I de Moran observado y la media de los valores simulados de I, dividida por la desviación estándar de estos valores simulados.
# Monte Carlo test
set.seed(1234)
bperm <- moran.mc(NY8$Cases, listw=lw_B, nsim=999)
bperm
##
## Monte-Carlo simulation of Moran I
##
## data: NY8$Cases
## weights: lw_B
## number of simulations + 1: 1000
##
## statistic = 0.11039, observed rank = 1000, p-value = 0.001
## alternative hypothesis: greater
r <- sum(NY8$Cases)/sum(NY8$POP8)
rni <- r*NY8$POP8
CR <- function(var, mle) rpois(length(var), lambda=mle)
MoranI.pboot <- function(var, i, listw, n, S0, ...) {
return(moran(x=var, listw=listw, n=n, S0=S0)$I)
}
set.seed(1234)
boot2 <- boot(NY8$Cases, statistic=MoranI.pboot, R=999, sim="parametric",
ran.gen=CR, listw=lw_B, n=length(NY8$Cases), S0=Szero(lw_B), mle=rni)
pnorm((boot2$t0 - mean(boot2$t))/sd(boot2$t[,1]), lower.tail=FALSE)
## [1] 0.1472112
oopar <- par(mfrow=c(1,2))
xlim <- range(c(bperm$res, boot2$t[,1]))
hist(bperm$res[-length(bperm$res)], main="Permutation bootstrap", xlab=expression(I[std]), xlim=xlim, density=15, angle=45, ylim=c(0,260))
abline(v=bperm$statistic, lty=2)
hist(boot2$t, col=rgb(0.4,0.4,0.4), main="Parametric bootstrap", xlab=expression(I[CR]), xlim=xlim, ylim=c(0,260))
hist(bperm$res[-length(bperm$res)], density=15, angle=45, add=TRUE)
abline(v=boot2$t0, lty=2)
par(oopar)
Los resultados del índice de Bayes empírico indican que una posible explicación para la falta de significancia en el bootstrap paramétrico del riesgo constante observado y los valores esperados podría ser la presencia de valores inusuales y extremos en segmentos con poblaciones reducidas. Después de aplicar técnicas de suavizado a las tasas, se observa cierta autocorrelación a nivel global.
Al utilizar las medidas globales de asociación espacial, se puede descomponer dichas medidas para crear pruebas locales que buscan identificar clusters (observaciones con vecinos altamente similares) y hotspots (observaciones con vecinos altamente diferentes). Estas pruebas también pueden utilizarse para evaluar el impacto de los estadísticos individuales en los indicadores globales correspondientes.
(Anselin, 1995)
Cualquier estadístico que cumpla las siguientes condiciones:
El LISA (Local Indicators of Spatial Association) para cada observación proporciona una medida del grado de agrupación espacial significativa de valores similares alrededor de dicha observación.
La suma de los LISA para todas las observaciones es proporcional al indicador global de asociación espacial.
Estos estadísticos permiten verificar si la contribución local a la agrupación alrededor de la observación “i” es significativamente diferente de cero, lo que permite identificar áreas donde existe un grado significativo de agrupación espacial.
Partiendo del índice global de Moran:
\[ I = \frac{n}{\sum_{i=1}^{n} \sum_{j=1}^{n} w_{ij}}\ \frac{\sum_{i=1}^{n} \sum_{j=1}^{n} (y_i - \bar{y})(y_j - \bar{y})}{\sum_{i=1}^{n} (y_i - \bar{y})^2} \]
Se reescribe como:
\[ I = n \left[ \sum_k \sum_j w_{kj} \right]^{-1}\left[ \sum_k (y_k-\bar{y})^2 \right]^{-1} \sum_i I_i \]
Donde:
\[ I_i = (y_i-\bar{y}) \sum_j w_{ij} (y_j - \bar{y}) \]
De manera que:
\(n \left[ \sum_k \sum_j w_{kj} \right]^{-1}\left[ \sum_k (y_k-\bar{y})^2 \right]^{-1}\) no depende de i, entonces para un conjunto dado de \(z_i\) esta expresión se comporta como una constante.
\[ I = cte \cdot \sum_i I_i \]
Reemplazando \(z6_i = y_i - \bar{y}\), se obtiene la expresión original propuesta por Anselin, 1995.
\[ I_i = z_i \sum_j w_{ij}z_j \]
\(I_i\) es el producto de \(z_i\) y la media de los valores \(z_j\) de los vecinos del polígono \(i\)
Si tanto el valor \(z_i\) como el valor medio de los vecinos \(z_j\) están por encima de la media, la cantidad será alta, lo que indica la presencia de un cluster de valores por encima de la media, centrado en el polígono “i”.
Si los signos de \(z_i\) y \(\sum_j w_{ij}z_j\) son diferentes y el valor de \(I_i\) es ampliamente negativo, esto podría sugerir la existencia de repulsión local (outliers).
Si la magnitud de \(I_i\) no es especialmente grande, esto indica que hay poca evidencia para concluir sobre la presencia de clusters o repulsión.
Finalmente, se puede aplicar un test de significancia estadística a cada valor de \(I_i\), utilizando una hipótesis nula que postula la ausencia de asociación espacial.
Cuadrantes de asociación espacial. Modificado de Siabato et al., 2018
Antes de abordar la creación del diagrama de dispersión de Moran, se proporciona una breve explicación sobre los rezagos espaciales, los cuales son fundamentales para la construcción de dicho gráfico.
Una vez que se ha definido la estructura de pesos en la matriz \(W\), los rezagos espaciales se definen como el resultado de multiplicar la matriz de pesos por el valor de la variable de interés \(y\). En otras palabras, un rezago espacial es una suma de los valores de los vecinos, ponderados de acuerdo a su proximidad espacial.
\[ Wy \] Esta operación está bien definida ya que \(W \in \mathbb{R}^{n\times n}\) y \(y \in \mathbb{R}^{n \times 1}\).
En la práctica, suele hacerse como:
\[ [Wy]_i = \sum_{j=1}^n w_{ij}y_j \] Esto se puede expresar de manera equivalente a la operación matricial mencionada anteriormente. Sin embargo, en la práctica, al trabajar con muestras de gran tamaño, almacenar la matriz \(W\) como una “matriz pura” puede ser ineficiente en términos de uso de memoria. Por lo tanto, es común utilizar una estructura de datos conocida como “sparse matrix” para almacenar los valores de \(W\), ya que estos tienden a ser dispersos.
En el gráfico de dispersión de Moran, siguiendo una convención establecida, se coloca la variable de interés en el eje x y los valores de los rezagos espaciales en el eje y. El índice global de Moran se basa en una relación lineal entre estos valores y se representa gráficamente como la pendiente de la línea de tendencia.
(ggplot(moran_plot, aes(x, wx)) +
geom_point(aes(shape = is_inf, color = is_inf), size = 0.75) +
scale_color_manual(values = c("black", "red")) +
geom_hline(
yintercept = moran_plot$wx %>% mean(),
linetype = "dashed", alpha = 0.5
) +
geom_vline(
xintercept = moran_plot$x %>% mean(),
linetype = "dashed", alpha = 0.5
) +
geom_text(aes(x, wx, label = labels),
data = filter(moran_plot, is_inf),
size = 2.5
) +
geom_smooth(method = "lm", se = F, size = .6, col = "black") +
labs(
x = "Cases", y = "Spatial lagged cases",
title = "Moran Scatterplot",
shape = "Significativo", color = "Significativo"
) +
theme_bw() +
theme(plot.title = element_text(hjust = 0.5))) %>%
plotly::ggplotly()
El gráfico se divide en cuatro cuadrantes, cada uno con su significado específico. En el cuadrante superior derecho se encuentran las áreas con una alta incidencia de casos de leucemia, rodeadas por áreas que también presentan niveles superiores al promedio de casos (high-high). Estas áreas se conocen como hotspots. Por otro lado, en el cuadrante inferior izquierdo se encuentran las áreas con una baja incidencia de casos de leucemia, rodeadas por áreas con una incidencia por debajo del promedio (low-low). Estas áreas se conocen como coldspots.
En la diagonal opuesta se encuentran los valores atípicos espaciales, lo que indica que estas áreas están rodeadas por vecinos que difieren significativamente de ellas.
Al igual que en el caso de la estadística global, se puede evaluar la divergencia de los estadísticos locales con respecto a los valores esperados, asumiendo la normalidad y aleatoriedad, utilizando métodos analíticos como el de punto de silla y exacto. Estos métodos permiten comprobar la significancia estadística de los resultados obtenidos.
local <- as.data.frame(localmoran(ny$Cases,
listw = nb2listw(NY_nb, style = "C")
))
local2 <- as.data.frame(localmoran.sad(lm(Cases ~ 1, ny),
nb = NY_nb, style = "C"
))
local3 <- as.data.frame(localmoran.exact(lm(Cases ~ 1, ny), nb = NY_nb, style = "C"))
ny %>%
select(Cases) %>%
mutate(
p_value = moran_plot$is_inf,
rezago = lag.listw(nb2listw(NY_nb, style = "B"), Cases),
cuadrante = case_when(
(Cases > mean(Cases)) & (rezago > mean(rezago)) &
(p_value == T) ~ "High-High",
(Cases <= mean(Cases)) & (rezago <= mean(rezago)) &
(p_value == T) ~ "Low-Low",
(Cases > mean(Cases)) & (rezago <= mean(rezago)) &
(p_value == T) ~ "High-Low",
(Cases <= mean(Cases)) & (rezago > mean(rezago)) &
(p_value == T) ~ "Low-High",
TRUE ~ "NS"
),
index = moran_plot$labels
) -> resultados
resultados_coords <- filter(resultados, p_value == T) %>%
mutate(
x = (st_centroid(resultados$geometry) %>% st_coordinates())[1],
y = (st_centroid(resultados$geometry) %>% st_coordinates())[2]
)
(ggplot(resultados) +
geom_sf(aes(fill = cuadrante), alpha = 0.8) +
scale_fill_manual(values = viridisLite::viridis(5)) +
labs(
title = "Lugares con influencia de Leucemia \n",
x = "Longitud", y = "Latitud"
) +
geom_sf_text(
data = resultados_coords,
mapping = aes(x, y, label = index),
color = "white"
) +
theme_bw() +
theme(
plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
axis.text = element_blank(),
axis.ticks = element_blank()
)) %>%
plotly::ggplotly()
Es posible realizar una evaluación de riesgo constante al asumir una distribución Poisson con un valor de \(\lambda\) que representa la probabilidad de ocurrencia de la enfermedad. Para estandarizar la variable, se utiliza la propiedad de que tanto la media como la desviación estándar son iguales en esta distribución. Luego, se calculan los rezagos espaciales y se compara el índice de Moran actual con el índice de riesgo constante.
ny %>%
transmute(
p_afectada = sum(Cases) / sum(POP8) * POP8,
casos_std = (Cases - p_afectada) / sqrt(p_afectada),
rezago = stats::lag(nb2listw(NY_nb, style = "C"), casos_std),
indice_riesgo = casos_std * rezago,
indice = local$Ii
) -> riesgo
m_riesgo <- ggplot(riesgo) +
geom_sf(aes(fill = indice_riesgo)) +
labs(title = "Mapa de riesgo Constante") +
scale_fill_gradientn(
colours = viridisLite::viridis(20,
begin = 0.17,
end = 0.98
),
limits = c(-2.2, 3.7)
) +
theme_bw() +
theme(
plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
axis.text = element_blank(),
axis.ticks = element_blank()
)
m_actual <- ggplot(riesgo) +
geom_sf(aes(fill = indice)) +
labs(title = "Mapa de riesgo Standard") +
scale_fill_gradientn(
colours = viridisLite::viridis(20,
begin = 0.17,
end = 0.98
),
limits = c(-2.2, 3.7)
) +
theme_bw() +
theme(
plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
axis.text = element_blank(),
axis.ticks = element_blank()
)
cowplot::plot_grid(m_actual, m_riesgo, align = "hv", ncol = 2)
# set.seed(1234)
# nsim <- 999
# N <- length(rni)
# sims <- matrix(0, ncol = nsim, nrow = N)
# for (i in 1:nsim) {
# y <- rpois(N, lambda = rni)
# sdCRi <- (y - rni)/sqrt(rni)
# wsdCRi <- lag(lw, sdCRi)
# sims[, i] <- sdCRi * wsdCRi
# }
# xrank <- apply(cbind(I_CR, sims), 1, function(x) rank(x)[1])
# diff <- nsim - xrank
# diff <- ifelse(diff > 0, diff, 0)
# pval <- punif((diff + 1)/(nsim + 1))
monte_carlo_sim <- function(nsim, prop, Ii, nb) {
N <- length(prop)
sims <- matrix(0, ncol = nsim, nrow = N)
for (i in 1:nsim) {
y <- rpois(N, lambda = prop)
z <- (y - prop) / sqrt(prop)
rezago <- stats::lag(nb2listw(nb, style = "C"), z)
sims[, i] <- z * rezago
}
xrank <- apply(cbind(Ii, sims), 1, function(x) rank(x)[1])
diff <- nsim - xrank
diff <- ifelse(diff > 0, diff, 0)
pval <- punif((diff + 1) / (nsim + 1))
return(pval)
}
mc_sim <- riesgo %>%
select(p_afectada, indice_riesgo) %>%
mutate(
pvalue_cr = monte_carlo_sim(
999, p_afectada,
indice_riesgo, NY_nb
),
pvalue_sad = local2$`Pr. (Sad)`,
pvalue_exact = local3$`Pr. (exact)`,
pvalue_rand = local$`Pr(z != E(Ii))`,
pvalue_norm = local2$`Pr. (N)`
) %>%
pivot_longer(
cols = c(
"pvalue_cr", "pvalue_sad",
"pvalue_exact", "pvalue_rand", "pvalue_norm"
),
names_to = "type", values_to = "p_value"
) %>%
mutate(discrete = cut(p_value,
breaks = c(
0, 0.05, 0.1,
0.9, 0.95, 1, max(p_value)
),
include.lowest = T
))
aux_labs <- c(
"pvalue_cr" = "Riesgo constante",
"pvalue_exact" = "Exacto",
"pvalue_norm" = "Normal",
"pvalue_rand" = "Aleatorio",
"pvalue_sad" = "Saddlepoint"
)
ggplot(mc_sim) +
geom_sf() +
geom_sf(aes(fill = discrete),
data = filter(mc_sim, p_value < 0.1 | p_value > 0.9 &
p_value < 1)
) +
facet_wrap(~type, labeller = labeller(type = aux_labs)) +
labs(title = "") +
scale_fill_manual(values = viridisLite::viridis(5), name = "P-value") +
theme_bw() +
theme(
plot.title = element_text(size = 14, face = "bold", hjust = 0.5),
axis.text = element_blank(),
axis.ticks = element_blank()
)
En el gráfico presentado, podemos realizar una verificación considerando
diferentes distribuciones con el fin de determinar si un área es inusual
o presenta agrupamiento. Esta información nos permite evaluar si los
índices observados tienen respaldo estadístico, lo cual refuerza su
validez y relevancia.
Los modelos estadísticos nos ofrecen diversas formas de modelar la dependencia espacial. Aunque normalmente se asume independencia entre las observaciones o distribuciones, esto no se aplica a los datos espaciales. Sin embargo, podemos explicar la autocorrelación espacial entre áreas vecinas. En el caso de que el vector de variables respuesta siga una distribución normal multivariada, se puede expresar de la siguiente manera:
\[ Y=\mu + e, \] Una de las alternativas recomendadas es utilizar una transformación logarítmica que incluya los pesos, en nuestro caso la cantidad de población, para tener en cuenta la heterogeneidad del riesgo. Esta transformación logarítmica puede ser una opción viable para abordar este aspecto.
\[ Z_i=log \left( \frac{1000(Y_i+1)}{n_i}\right) \]
TCE <- readOGR("data", "TCE")
## OGR data source with driver: ESRI Shapefile
## Source: "C:\Users\Usuario\Videos\trabajo3\data", layer: "TCE"
## with 11 features
## It has 5 fields
ny <- readOGR("data",'NY8_utm18')
## OGR data source with driver: ESRI Shapefile
## Source: "C:\Users\Usuario\Videos\trabajo3\data", layer: "NY8_utm18"
## with 281 features
## It has 17 fields
nylm <- lm(Z~PEXPOSURE+PCTAGE65P+PCTOWNHOME, data=ny)
summary(nylm)
##
## Call:
## lm(formula = Z ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME, data = ny)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.7417 -0.3957 -0.0326 0.3353 4.1398
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.51728 0.15856 -3.262 0.00124 **
## PEXPOSURE 0.04884 0.03506 1.393 0.16480
## PCTAGE65P 3.95089 0.60550 6.525 3.22e-10 ***
## PCTOWNHOME -0.56004 0.17031 -3.288 0.00114 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.6571 on 277 degrees of freedom
## Multiple R-squared: 0.1932, Adjusted R-squared: 0.1844
## F-statistic: 22.1 on 3 and 277 DF, p-value: 7.306e-13
Para analizar los datos de un área determinada, se utiliza el centroide de cada polígono y se asignan diversas covariables con el objetivo de construir un modelo de regresión lineal que explique la variable Z. A continuación, se presenta un ejemplo que considera tres covariables en el modelo.
ny$lmresid <- residuals(nylm) # residuales modelo sin pesos
NYlistw <- nb2listw(NY_nb, style = "B")
lm.morantest(nylm, NYlistw)
##
## Global Moran I for regression residuals
##
## data:
## model: lm(formula = Z ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME, data = ny)
## weights: NYlistw
##
## Moran I statistic standard deviate = 2.638, p-value = 0.004169
## alternative hypothesis: greater
## sample estimates:
## Observed Moran I Expectation Variance
## 0.083090278 -0.009891282 0.001242320
Si consideramos que la tendencia de la variable de interés ha sido eliminada y que las ponderaciones espaciales están estandarizadas por filas, el estimador de un paso del parámetro de regresión espacial puede proporcionar más información comparativa que el Índice de Moran. Para realizar una comparación, presentamos la estimación ajustada del parámetro de máxima verosimilitud utilizando los mismos datos:
NYlistwW <- nb2listw(NY_nb, style = "W")
aple(residuals(nylm), listw=NYlistwW)
## [1] 0.2051536
spautolm(Z~PEXPOSURE+PCTAGE65P+PCTOWNHOME, data=ny, listw=NYlistwW)$lambda
## lambda
## 0.2169261
nysar <- spautolm(Z~PEXPOSURE+PCTAGE65P+PCTOWNHOME, data=ny, listw=NYlistw)
summary(nysar)
##
## Call: spautolm(formula = Z ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME, data = ny,
## listw = NYlistw)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.56754 -0.38239 -0.02643 0.33109 4.01219
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.618193 0.176784 -3.4969 0.0004707
## PEXPOSURE 0.071014 0.042051 1.6888 0.0912635
## PCTAGE65P 3.754200 0.624722 6.0094 1.862e-09
## PCTOWNHOME -0.419890 0.191329 -2.1946 0.0281930
##
## Lambda: 0.040487 LR test value: 5.2438 p-value: 0.022026
## Numerical Hessian standard error of lambda: 0.017201
##
## Log likelihood: -276.1069
## ML residual variance (sigma squared): 0.41388, (sigma: 0.64333)
## Number of observations: 281
## Number of parameters estimated: 6
## AIC: NA (not available for weighted model)
Al analizar los resultados obtenidos, se observa una correlación en los residuos, dado que el valor estimado de \(\lambda\) es 0.0405 y el valor p asociado es 0.022 en la prueba de máxima verosimilitud. Aunque el parámetro resulte significativo a un nivel de confianza del 95%, es recomendable realizar una verificación adicional con otro tipo de modelo para no descartar la posibilidad de una asociación. De esta manera, se evita basar las conclusiones únicamente en un único enfoque estadístico y se asegura una evaluación más completa y precisa.
Por otro lado, se observa que la covariable exposición no es significativa.
nylam1 <- c(nysar$lambda)
nylam2 <- c(LR1.Spautolm(nysar)$p.value)
ny$sar_trend <- nysar$fit$signal_trend
ny$sar_stochastic <- nysar$fit$signal_stochastic
rds <- colorRampPalette(brewer.pal(8, "RdBu"))
tr_at <- seq(-1, 1.3, length.out=21)
tr_rds <- rds(sum(tr_at >= 0)*2)[-(1:(sum(tr_at >= 0)-sum(tr_at < 0)))]
tr_pl <- spplot(ny, c("sar_trend"), at=tr_at, col="transparent", col.regions=tr_rds, main=list(label="Trend", cex=0.8))
st_at <- seq(-0.16, 0.39, length.out=21)
st_rds <- rds(sum(st_at >= 0)*2)[-(1:(sum(st_at >= 0)-sum(st_at < 0)))]
st_pl <- spplot(ny, c("sar_stochastic"), at=st_at, col="transparent", col.regions=st_rds, main=list(label="Stochastic", cex=0.8))
plot(tr_pl, split=c(1,1,2,1), more=TRUE)
plot(st_pl, split=c(2,1,2,1), more=FALSE)
Es importante tener en cuenta que este modelo no considera la distribución heterogénea de la población, es decir, asume que la población es uniforme en todas las zonas. Por lo tanto, se incluye el argumento “weights = POP8” en el modelo LM.
nylmw <- lm(Z~PEXPOSURE+PCTAGE65P+PCTOWNHOME, data=ny, weights=POP8)
summary(nylmw)
##
## Call:
## lm(formula = Z ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME, data = ny,
## weights = POP8)
##
## Weighted Residuals:
## Min 1Q Median 3Q Max
## -129.067 -14.714 5.817 25.624 70.723
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.77837 0.14116 -5.514 8.03e-08 ***
## PEXPOSURE 0.07626 0.02731 2.792 0.00560 **
## PCTAGE65P 3.85656 0.57126 6.751 8.60e-11 ***
## PCTOWNHOME -0.39869 0.15305 -2.605 0.00968 **
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 33.5 on 277 degrees of freedom
## Multiple R-squared: 0.1977, Adjusted R-squared: 0.189
## F-statistic: 22.75 on 3 and 277 DF, p-value: 3.382e-13
ny$lmwresid <- residuals(nylmw)
Cuando se incorpora la ponderación de pesos, se observa que la variable covariable “exposición” se vuelve significativa, lo cual difiere del modelo anterior. Esto tiene sentido, ya que es plausible que exista una relación entre los casos de leucemia y el nivel de exposición.
lm.morantest(nylmw, NYlistw)
##
## Global Moran I for regression residuals
##
## data:
## model: lm(formula = Z ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME, data = ny,
## weights = POP8)
## weights: NYlistw
##
## Moran I statistic standard deviate = 0.4773, p-value = 0.3166
## alternative hypothesis: greater
## sample estimates:
## Observed Moran I Expectation Variance
## 0.007533246 -0.009309771 0.001245248
Los hallazgos son intrigantes, ya que indican que la mala especificación identificada por el índice de Moran está más relacionada con la heteroscedasticidad que con la autocorrelación espacial.
nysarw <- spautolm(Z ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME,
data = ny, listw = NYlistw, weights = POP8)
summary(nysarw)
##
## Call: spautolm(formula = Z ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME, data = ny,
## listw = NYlistw, weights = POP8)
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.48488 -0.26823 0.09489 0.46552 4.28343
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.797063 0.144054 -5.5331 3.146e-08
## PEXPOSURE 0.080545 0.028334 2.8428 0.004473
## PCTAGE65P 3.816731 0.576037 6.6258 3.453e-11
## PCTOWNHOME -0.380778 0.156507 -2.4330 0.014975
##
## Lambda: 0.0095636 LR test value: 0.32665 p-value: 0.56764
## Numerical Hessian standard error of lambda: 0.016522
##
## Log likelihood: -251.6017
## ML residual variance (sigma squared): 1104.1, (sigma: 33.229)
## Number of observations: 281
## Number of parameters estimated: 6
## AIC: NA (not available for weighted model)
Observando esto, se nota que no hay rastros de espacio.
gry <- c(rev(brewer.pal(6, "Reds")[1:4]), colorRampPalette(brewer.pal(5, "Blues"))(9))
TCEpts <- list("sp.points", TCE, pch=16, col="grey5")
spplot(ny, c("lmresid", "lmwresid"), sp.layout=list(TCEpts), col.regions=gry, col="transparent", lwd=0.5, at=seq(-2,4.5,0.5))
Se observa que el modelo con ponderación obtiene resudiales mas pequeños que con el modelo sin los pesos, esto dado en pequeños poligonos.
ny$sarw_trend <- nysarw$fit$signal_trend
ny$sarw_stochastic <- nysarw$fit$signal_stochastic
tr_pl <- spplot(ny, c("sarw_trend"), at=tr_at, col="transparent", col.regions=tr_rds, main=list(label="Trend", cex=0.8))
st_pl <- spplot(ny, c("sarw_stochastic"), at=st_at, col="transparent", col.regions=st_rds, main=list(label="Stochastic", cex=0.8))
plot(tr_pl, split=c(1,1,2,1), more=TRUE)
plot(st_pl, split=c(2,1,2,1), more=FALSE)
Se observa que la variación espacial en la población entre tractos es responsable de la correlación espacial residual después del ajuste por covariables.
La definición de CAR se basa en la distribución condicional de la distribución de los errores, es decir:
\[ e_i | e_{j \sim \: i } \sim N \left( \sum_{j \sim i } \frac{c_{ij}e_j }{\sum_{j\sim i }c_{ij} }, \frac{\sim^{2}_{e_i} }{\sum_{j\sim i }c_{ij} } \right ) \]
Donde \(e_{j\sim i }\) representa los vecinos del área i y \(c_{ij}\) son parámetros dependientes de \(b_{ij}\).
Se obtiene que:
\[ E[Y] =X^T\beta \\ Var(Y) =\sigma^2(1-\lambda W )^{-1}(1-\lambda W^T )^{-1} \]
nycar <- spautolm(Z~PEXPOSURE+PCTAGE65P+PCTOWNHOME , data=ny, family="CAR",listw=NYlistw)
summary(nycar)
##
## Call: spautolm(formula = Z ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME, data = ny,
## listw = NYlistw, family = "CAR")
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.539732 -0.384311 -0.030646 0.335126 3.808848
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.648362 0.181129 -3.5796 0.0003442
## PEXPOSURE 0.077899 0.043692 1.7829 0.0745986
## PCTAGE65P 3.703830 0.627185 5.9055 3.516e-09
## PCTOWNHOME -0.382789 0.195564 -1.9574 0.0503053
##
## Lambda: 0.084123 LR test value: 5.8009 p-value: 0.016018
## Numerical Hessian standard error of lambda: 0.030872
##
## Log likelihood: -275.8283
## ML residual variance (sigma squared): 0.40758, (sigma: 0.63842)
## Number of observations: 281
## Number of parameters estimated: 6
## AIC: NA (not available for weighted model)
Aunque la estimación de los parámetros es similar a la del modelo SAR, se observa que los valores de p para dos covariables, la distancia al TCE más cercano y el porcentaje de personas propietarias de una vivienda, superan el umbral de 0.05 con un nivel de confianza del 95%. Además, la prueba de verosimilitud revela la presencia de una autocorrelación espacial significativa. Es importante destacar que esta conclusión se realiza sin tener en cuenta los pesos ponderados de POP8.
nylam1 <- c(nycar$lambda)
nycarw <- spautolm(Z~PEXPOSURE+PCTAGE65P+PCTOWNHOME, data=ny, family="CAR",listw=NYlistw, weights=POP8)
summary(nycarw)
##
## Call: spautolm(formula = Z ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME, data = ny,
## listw = NYlistw, weights = POP8, family = "CAR")
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.491042 -0.270906 0.081435 0.451556 4.198134
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.790154 0.144862 -5.4545 4.910e-08
## PEXPOSURE 0.081922 0.028593 2.8651 0.004169
## PCTAGE65P 3.825858 0.577720 6.6223 3.536e-11
## PCTOWNHOME -0.386820 0.157436 -2.4570 0.014010
##
## Lambda: 0.022419 LR test value: 0.38785 p-value: 0.53343
## Numerical Hessian standard error of lambda: 0.038977
##
## Log likelihood: -251.5711
## ML residual variance (sigma squared): 1102.9, (sigma: 33.21)
## Number of observations: 281
## Number of parameters estimated: 6
## AIC: NA (not available for weighted model)
Aplicando los pesos, se observa que las tres covariables son significativas ya que el p valor obtenido es muy pequeño.
Mediante la función “spautolm”, se realiza el ajuste de modelos de regresión espacial utilizando el método de máxima verosimilitud. Este proceso implica encontrar el coeficiente autoregresivo que maximiza la función de verosimilitud para la familia de modelos seleccionada y luego ajustar los demás coeficientes mediante mínimos cuadrados generalizados en ese punto.
En otras palabras, el coeficiente autoregresivo espacial se obtiene mediante la búsqueda de líneas utilizando el método de optimización, en lugar de optimizar simultáneamente todos los parámetros del modelo. Se tiene lo siguiente:
\[ log(|I-\lambda W|)=log \left( \prod_{i=1}^n (1-\lambda \zeta_i) \right) \] Donde $ _i$ son los valores propios de \(W\).
nysarwM <- spautolm(Z~PEXPOSURE+PCTAGE65P+PCTOWNHOME, data=ny,family="SAR",listw=NYlistw, weights=POP8, method="Matrix")
summary(nysarwM)
##
## Call: spautolm(formula = Z ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME, data = ny,
## listw = NYlistw, weights = POP8, family = "SAR", method = "Matrix")
##
## Residuals:
## Min 1Q Median 3Q Max
## -2.561100 -0.374524 0.057405 0.591094 5.700142
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.578546 0.090006 -6.4279 1.294e-10
## PEXPOSURE 0.035402 0.013959 2.5361 0.01121
## PCTAGE65P 4.651137 0.421285 11.0404 < 2.2e-16
## PCTOWNHOME -0.666898 0.091443 -7.2931 3.029e-13
##
## Lambda: -0.34423 LR test value: 264.24 p-value: < 2.22e-16
## Numerical Hessian standard error of lambda: 0.036776
##
## Log likelihood: -119.6468
## ML residual variance (sigma squared): 2129.1, (sigma: 46.142)
## Number of observations: 281
## Number of parameters estimated: 6
## AIC: NA (not available for weighted model)
nysar_ll <- spautolm(Z~PEXPOSURE+PCTAGE65P+PCTOWNHOME, data=ny, family="SAR",listw=NYlistw, llprof=100)
nysarw_ll <- spautolm(Z~PEXPOSURE+PCTAGE65P+PCTOWNHOME, data=ny, family="SAR",listw=NYlistw, weights=POP8, llprof=100)
ylim <- range(c(nysarw_ll$llprof$ll, nysar_ll$llprof$ll), na.rm=TRUE)
plot(nysarw_ll$llprof$lambda, nysarw_ll$llprof$ll, type="l", xlab=expression(lambda), ylab="log likelihood", ylim=ylim, lwd=2)
abline(v=nysarw_ll$lambda)
abline(h=nysarw_ll$LL)
lines(nysar_ll$llprof$lambda, nysar_ll$llprof$ll, lty=2, lwd=2)
abline(v=nysar_ll$lambda, lty=2)
abline(h=nysar_ll$LL, lty=2)
legend("bottom", legend=c("weighted SAR", "SAR"), lty=c(1,2), lwd=2, bty="n")
Se observa la función de log verosimilitud en función de \(\lambda\) y donde esta alcanza su máximo.
1/range(eigenw(NYlistw))
## [1] -0.3029200 0.1549552
nysmaw <- spautolm(Z~PEXPOSURE+PCTAGE65P+PCTOWNHOME, data=ny, family="SMA",listw=NYlistw, weights=POP8)
summary(nysmaw)
##
## Call: spautolm(formula = Z ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME, data = ny,
## listw = NYlistw, weights = POP8, family = "SMA")
##
## Residuals:
## Min 1Q Median 3Q Max
## -1.487080 -0.268990 0.093956 0.466055 4.284087
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.795243 0.143749 -5.5321 3.163e-08
## PEXPOSURE 0.080153 0.028237 2.8386 0.004531
## PCTAGE65P 3.820316 0.575463 6.6387 3.165e-11
## PCTOWNHOME -0.382529 0.156160 -2.4496 0.014302
##
## Lambda: 0.0091843 LR test value: 0.30771 p-value: 0.57909
## Numerical Hessian standard error of lambda: 0.01657
##
## Log likelihood: -251.6112
## ML residual variance (sigma squared): 1105.3, (sigma: 33.245)
## Number of observations: 281
## Number of parameters estimated: 6
## AIC: NA (not available for weighted model)
Un punto a favor acerca del análisis de datos espaciales es la amplia gama de disciplinas involucradas, lo cual permite dar multiples enfoques en esto cado para terminos ecónomicos, uno de ellos es la econometría espacial.La econometría espacial es descrita por Anselin (1988, 2002), avanzado por LeSage y Pace (2009) y con comentarios adicionales de Bivand (2002, 2006) con respecto a hacer econometría espacial en el sotfware R.
Cabe resaltar que en el caso de econometria, proponer diferentes supuestos en el área de econometria es algo complejo y no se cuenta con buenos conomientos en esa área.
Se pueden utilizar otros metodos para explicar la correlación espacial como los GAM donde se asume una distribución, no necesariamente normal.
ny$x <- coordinates(ny)[, 1]/1000
ny$y <- coordinates(ny)[, 2]/1000
nyGAM1 <- gam(Z ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME +
s(x, y), weights = POP8, data = ny)
anova(nylmw, nyGAM1, test = "Chisq")
## Analysis of Variance Table
##
## Model 1: Z ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME
## Model 2: Z ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME + s(x, y)
## Res.Df RSS Df Sum of Sq Pr(>Chi)
## 1 277.00 310778
## 2 273.19 305229 3.8096 5549.7 0.2671
En este caso, no agrega valor a los modelos ya vistos anteriormente.
nyGLMp <- glm(Cases ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME +
offset(log(POP8)), data = NY8, family = "poisson")
summary(nyGLMp)
##
## Call:
## glm(formula = Cases ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME + offset(log(POP8)),
## family = "poisson", data = NY8)
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -8.13442 0.18261 -44.545 < 2e-16 ***
## PEXPOSURE 0.14893 0.03121 4.773 1.82e-06 ***
## PCTAGE65P 3.99816 0.59783 6.688 2.27e-11 ***
## PCTOWNHOME -0.35710 0.19027 -1.877 0.0605 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for poisson family taken to be 1)
##
## Null deviance: 428.25 on 280 degrees of freedom
## Residual deviance: 353.35 on 277 degrees of freedom
## AIC: Inf
##
## Number of Fisher Scoring iterations: 5
Se observa que hay poca sobredispersión, además, el ajuste con la familia poisson en el que el parámetro de dispersión no se fija en la unidad, por lo que pueden modelar una dispersión excesiva que no da como resultado grandes cambios.
nyGAMp <- gam(Cases ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME + offset(log(POP8)) + s(x, y), data = ny, family = "poisson")
summary(nyGAMp)
##
## Family: poisson
## Link function: log
##
## Formula:
## Cases ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME + offset(log(POP8)) +
## s(x, y)
##
## Parametric coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -8.13659 0.21475 -37.889 < 2e-16 ***
## PEXPOSURE 0.16807 0.05985 2.808 0.00498 **
## PCTAGE65P 3.71993 0.64308 5.785 7.27e-09 ***
## PCTOWNHOME -0.36019 0.19940 -1.806 0.07087 .
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Approximate significance of smooth terms:
## edf Ref.df Chi.sq p-value
## s(x,y) 7.708 10.71 9.989 0.504
##
## R-sq.(adj) = 0.394 Deviance explained = 21.4%
## UBRE = 0.2815 Scale est. = 1 n = 281
anova(nyGLMp, nyGAMp, test = "Chisq")
## Analysis of Deviance Table
##
## Model 1: Cases ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME + offset(log(POP8))
## Model 2: Cases ~ PEXPOSURE + PCTAGE65P + PCTOWNHOME + offset(log(POP8)) +
## s(x, y)
## Resid. Df Resid. Dev Df Deviance Pr(>Chi)
## 1 277.00 353.35
## 2 269.29 336.68 7.7079 16.666 0.02907 *
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1