Si recordamos lo que vimos al principio de este curso, una tabla de contigencia es simplemente una tabulación cruzada de dos variables. Nos brinda información sobre la relación que existe entre variables cualitativas, principalmente.
Constaba de los siguientes elementos:
Estos elemenos nos van a dar toda la información necesaria para poder cuantificar y evaluar la existencia (o no) de asociación entre dos variables.
En general, cuando nos preguntamos si dos variables están asociadas podemos definir cuatro grandes preguntas que se desprenden de esta:
Se observa que cada pregunta es más “compleja” que la anterior y, a su vez, están relacionadas una con la otra: no puedo preguntarme por la fuerza o el signo de la asociación si no existe asociación. Si bien no ahondaremos sobre las preguntas 3 y 4 por ahora, sí podemos adelantar que son preguntas apropiadas para variables ordinales y cuantitativas1. Dado que aquí trabajaremos con variables nominales (y alguna ordinal) nos centraremos en las preguntas 1 y 2: es decir por la existencia de asociación y por su fuerza.
Vamos a construir una tabla de contingencia que relacione la
pertenencia a la clase social (según el esquema de Erik Olin Wright) y
el tiempo que pasó desde el ultimo control médico (v139
).
Pero antes de eso, tenemos que realizar algunos preprocesamientos.
> library(tidyverse)
> df <- read_rds('./data/ENES_Personas_M1_EOW.rds')
Primero, agregamos la variable de clase a dos valores: trabajadores y no trabajadores.
> df <- df %>%
+ mutate(
+ class_eow_agg = if_else(class_eow == 'Trabajadores', 'Trabajadores', 'No trabajadores')
+ )
Veamos el cruce, entonces:
> tab1 <- df %>%
+ group_by(class_eow_agg, v139) %>%
+ summarise(n = round(sum(f_calib3),0)) %>%
+ mutate(prop = n/sum(n))
>
> tab1 %>%
+ ggplot(aes(x=class_eow_agg, y=prop, fill=v139)) +
+ geom_col() +
+ geom_text(aes(label=round(prop, 2))) +
+ labs(x="Clase EOW",
+ y="Prop.",
+ fill="Tiempo desde últ. ctrl. médico") +
+ theme_minimal()
Pareciera que las mayores diferencias se concentran en la categoría “Menos de un año”. Vamos, entonces a dicotomizar la variable de visitas al médico:
> df <- df %>%
+ mutate(
+ v139_agg = case_when(
+ v139 == 'Menos de 1 año' ~ '0. Menos de 1 año',
+ v139 == 'De 1 a 3 años' ~ '1. 1 a 3 años',
+ TRUE ~ '2. 3 años o más')
+ )
Finalmente, vamos a realizar una modificación en la escala de la ponderación. En lugar de que “expanda” los casos al total de la población vamos a buscar que lo haga al total de casos de la encuesta (27.610) pero manteniendo la estructura de las calibraciones realizadas. Más adelante veremos por qué hacemos esta operación.
> df <- df %>%
+ mutate(
+ f_calib4 = f_calib3/sum(f_calib3)*nrow(df)
+ )
Y repetimos el gráfico:
> tab2 <- df %>%
+ group_by(class_eow_agg, v139_agg) %>%
+ summarise(n = round(sum(f_calib4),0)) %>%
+ mutate(prop = n/sum(n))
>
> tab2 %>%
+ ggplot(aes(x=class_eow_agg, y=prop, fill=v139_agg)) +
+ geom_col() +
+ geom_text(aes(label=round(prop, 2))) +
+ labs(x="Clase EOW",
+ y="Prop.",
+ fill="Tiempo desde últ. ctrl. médico") +
+ theme_minimal()
Si bien no esperaríamos que el tiempo desde la última consulta y los casos en cada categoría sea exactamente el mismo en las tres clases de preguntas, las proporciones parecen bien diferentes entre las diferentes clases. Parece haber una diferencia entre ambas variables: los trabajadores han ido al médico en el último año en menor proporción que los no trabajadores: 0.679 contra 0.781. ¿Es significativa esta diferencia? Esto nos lleva de nuevo al terreno de las pruebas de hipótesis.
Pero en este caso es más difícil entender cuál es el parámetro sobre el cual queremos realizar la inferencia. Para poder pensar esta cuestión, tenemos que introducir una noción (ya vista en Metodologías cuantitativas) que es la de frecuencia esperada.
Podemos calcular la cantidad de personas que caen en cada categoría de la variable tiempo desde la última consulta si la misma fuera totalmente independiente de la clase social. En general, el cómputo puede hacerse de una forma bien sencilla2.
\[recuento\ esperado_{fila i, columna j} = \frac{n\ de\ fila\ i \times n\ columna\ j}{n\ total}\]
Es decir, que de esta forma obtenemos la distribución de los casos en
las celdas si las variables fueran estadísticamente independientes.
Afortunadamente, podemos realizar esta operación con un llamado a la
función chisq.test
. Enseguida volveremos sobre la función
pero, por ahora, veamos las dos tablas:
Veamos las frecuencias observadas:
> chi$observed %>% as_tibble()
## # A tibble: 3 × 2
## `No trabajadores` Trabajadores
## <dbl> <dbl>
## 1 13553 6962
## 2 2384 1997
## 3 1421 1293
Veamos, ahora, las esperadas:
> chi$expected %>% as_tibble()
## # A tibble: 3 × 2
## `No trabajadores` Trabajadores
## <dbl> <dbl>
## 1 12897. 7618.
## 2 2754. 1627.
## 3 1706. 1008.
La idea será comparar estas tablas mediante una prueba de hipótesis. La idea es comparar nuestra distribución observada con las frecuencias esperadas (bajo supuesto de independencia) con las frecuencias observadas (las que obtuvimos en nuestra muestra).
Para esto vamos a utilizar el test de chi cuadrado. El mismo se calcula a partir de la siguiente fórmula:
\[\chi^2 = \sum_{j}\sum_{i} \frac{(frec\ observada - frec\ esperada)^2}{frec\ esperada} \] 1. Calcula para cada celda la diferencia entre frecuencia observada y esperada
## No trabajadores Trabajadores
## 1 655.5219 -655.5219
## 2 -370.2701 370.2701
## 3 -285.2518 285.2518
## No trabajadores Trabajadores
## 1 429708.98 429708.98
## 2 137099.96 137099.96
## 3 81368.59 81368.59
## No trabajadores Trabajadores
## 1 33.31729 56.41060
## 2 49.77724 84.27949
## 3 47.68850 80.74297
## [1] 352.2161
Lógicamente, hay una función que nos permite resolver esto de forma
más simple sin tener que andar haciendo los cálculos a mano.
chisq.test()
espera un objeto tabla o matriz. Es por eso
que tenemos que hacer algunos pequeños cambios al formato de nuestra
tab2
original. Primero, eleminamos la columna prop. Luego,
pivoteamos para que nos quede la variable clase en las columnas y por
último, eliminamos la columna con las categorías de
v139_agg
.
> chi <- tab2 %>%
+ select(-prop) %>%
+ pivot_wider(names_from = class_eow_agg,
+ values_from = n) %>%
+ select(-v139_agg) %>%
+ chisq.test(., correct=FALSE)
>
> chi
##
## Pearson's Chi-squared test
##
## data: .
## X-squared = 352.22, df = 2, p-value < 2.2e-16
¿Este valor \(\chi^2 = 352.22\) es grande o pequeño? Para ello tenemos que realizar una prueba de hipótesis sobre el mismo.
Si bien podríamos realizar un test de randomización, vamos a aprovechar para introducir otra ofrma de hacer pruebas de hipótesis: mediante modelos matemáticos. Es decir, mediante supuestos sobre la distribución muestral del estimador.
El estadístico chi-cuadrado tiene una distribución matemática llamada distribución (muy originalmente) chi-cuadrado. Un punto importante es que un parámetro fundamental de esta distribución son los llamados “grados de libertad”. Los grados de libertad cambian la forma de la distribución de chi-cuadrado para adaptarse al problema en cuestión.
(Imagen tomada de (Çetinkaya-Rundel and Hardin 2021))
En última instancia \(\chi^2\) es una razón de cómo los recuentos observados varían de los recuentos esperados en comparación con los recuentos esperados. Bajo el supuesto de la hipótesis nula (que salud y clase social no están asociados) podemos plantear que \(H_{0}: \chi^2 = 0\). Lo cual supone que en nuestro caso \(\chi^2\) tiene una distribución con los siguientes grados de libertad: \(df=(filas - 1) \times (columnas -1) = 2\). Esa distribución (bajo el supuesto de que \(H_{0}\) es cierta) se vería más o menos así.
Entonces, el valor que obtuvimos en nuestra prueba anterior \(\chi^2=352.22\) se encuentra bien a la derecha de esta distribución. Lo cual hace que se trate de una muestra muy poco probable si \(H_{0}\) fuese cierta, es decir, si la frecuencia de visitas al médico y la clase no estuviesen asociadas.
Esto podemos verlo en el p-valor:
> chi
##
## Pearson's Chi-squared test
##
## data: .
## X-squared = 352.22, df = 2, p-value < 2.2e-16
El p valor nos muestra la probabilidad de haber obtenido el resultado que hemos obtenido suponiendo que la hipótesis nula \(H_{0}\) fuera cierta. Se suele decir que valores altos de p no permiten rechazar la \(H_{0}\), mientras que valores bajos de p si permiten rechazar la \(H_{0}\). Es un valor de probabilidad, por lo que oscila entre 0 y 1.
En una prueba estadística, se rechaza la hipótesis nula \(H_{0}\) si el valor p asociado al resultado observado es igual o menor que un nivel de significación α establecido arbitrariamente: convencionalmente 0,05 ó 0,013.
¿Cómo podemos interpretarlo en este caso?
Las frecuencias esperadas no deben ser inferiores a 5 en cada casilla.
No provee información sobre el orden de la asociación (es decir, no hay una variable dependiente ni una independiente).
Se trata de una medida muy dependiente del tamaño muestral (n). Si se duplica el tamaño en cada una de las celdas, también lo hace el valor de Ji-cuadrado. Por ello, reescalamos los pesos en la variable `
Calculen el chi cuadrado de la misma tabla pero ponderada con los valores expandidos a la población. ¿Qué observan con el valor de \(\chi^2\)?
> ###
Medir el grado o la fuerza de la asociación supone construir una métrica que sea fácilmente interpretable y que pueda cuantificar de alguna forma la intensidad con la que dos variables están asociadas (muy fuerte/fuerte/moderada/débil/despreciable). A su vez, sería deseable que esta medida permitiera comparar distintas asociaciones estimadas en distintos cruces.
Nos gustaría un estadístico que
¿Por qué no usar el valor absoluto de Chi-Cuadrado? No sirve porque el nivel de significación depende de n. Vamos a introducir un segundo coeficiente llamado “V de Cramer”.
\[V = \sqrt \frac{\chi^2}{n \times min(filas-1, columnas-1)}\] V de Cramer es una normalización de \(\chi^2\) por el tamaño de muestra (\(n\)) y el tamaño de la tabla (\(min(filas-1,columnas-1)\)). Tiene algunas propiedades interesantes:
Dado que no se encuentra implementado en R de forma simple, hemos escrito un función muy simple para hacer el cálculo. La misma toma como input una tabla.
La misma la generamos de la forma en que ya sabemos hacerlo:
group_by() + summarise()
y luego, aplicamos un
pivot_wider()
para pasarla del formato tidy-apilado a un
formato de filas y columnas más similar a una tabla de contingencia
clásica.
> cramerv <- function(table){
+ chi <- chisq.test(table, correct=FALSE)
+ n <- sum(chi$observed)
+ c <- ncol(table)
+ r <- nrow(table)
+ m <- min(c-1, r-1)
+
+ cv <- sqrt((chi$statistic / n) / m)
+
+ results <- list(
+ vcramer = cv,
+ pvalue = chi$p.value,
+ observed = chi$observed,
+ expected = chi$expected
+ )
+ cat('Cramers V=', cv, '\n')
+ cat('Chi squared=', chi$statistic, '\n')
+ cat('p-value=', chi$p.value, '\n')
+
+ return(results)
+
+ }
>
> vdc <- tab2 %>%
+ select(-prop) %>%
+ pivot_wider(names_from = class_eow_agg,
+ values_from = n) %>%
+ select(-v139_agg) %>%
+ cramerv()
## Cramers V= 0.1129461
## Chi squared= 352.2161
## p-value= 3.290405e-77
En términos generales, podemos decir que se trata de una asociación débil entre estas dos variables.
El sentido o signo de la asociación entre las variables distribuidas conjuntamente. Por ejemplo, afirmando que cuando una se incrementa otra disminuye. Es claro que esto es posible con variables cuya escala de medición es al menos ordinal. La forma de la asociación supone que podemos conocer de qué manera varían ambas variables: de forma lineal, monotónica no lineal, no monotónica, etc.↩︎
El fundamento de esta fórmula proviene de la definición de sucesos independientes en teoría de probabilidad. En efecto, dicha teoría dice que la probabilidad conjunta de ocurrencia de dos sucesos independientes es igual a la probabilidad del suceso 1 multiplicada por la probabilidad del suceso 2. Si queremos calcular los conteos y no las probabilidades debemos multiplicar por el total de la tabla.↩︎
Existen numerosísimas discusiones sobre lo que signfica realmente el p-valor. Actualmente, hay todo un debate al respecto y sobre la utilidad o no entre la comunidad de estadísticos. Acá tienen una charla sumamente interesante al respecto.↩︎