Capítulo 6 Análisis de datos categóricos

6.1 Introducción

Este documento presenta algunos métodos básicos para el análisis de datos categóricos y las funciones de R que nos permiten llevarlos a cabo. Nos concentraremos en la creación de tablas de contingencia, ajuste de modelos de independencia \(\chi\)22 y loglineales y medidas de asociación para variables categóricas nominales, además de algunos métodos gráficos para visualizar datos categóricos. Otros métodos más avanzados serán cubiertos en documentos posteriores, puntualmente los métodos de modelado lineal –modelos logit–, reducción de la dimensionalidad –Análisis de Correspondencias Múltiples– e inferencia de variables latentes –Análisis de Clases de Latentes. Sin embargo su comprensión y aplicación reposan en el conocimiento de los métodos básicos.

6.1.1 Datos categóricos

Entendemos por datos categóricos a aquellos que definen la pertenencia de un objeto estadístico a una categoría o clase de acuerdo a alguno de sus atributos. De acuerdo con el nivel de medición los datos categóricos corresponden a las variables medidas en escalas nominales u ordinales, aunque aquí nos centraremos en las nominales. Una variable nominal asigna pertenencia a una categoría excluyente, es decir, señala una igualdad o diferencia. En términos lógicos la única operación que podemos realizar es a=b o a\(\neq\)b. En el caso de las ordinales existe una magnitud, algunas categorías tienen más y otras tienen menos de algún atributo, por lo que es posible hacer operaciones como a>b o a<b. Sin embargo esa magnitud expresa una distancia desconocida.

Niveles de medición. Adaptado de Stevens, 1946.
Escala de Medición Propiedad Sistema Numérico Operación Matemática Ejemplos
Nominal Identidad Contar Frecuencias Sexo
Ordinal Magnitud Ordenar NSE
Intervalo Distancia Suma, Resta Calificaciones del Mora
Razón Cero indica ausencia de valor Multiplicación, División Ingreso, Edad

6.2 Tablas

En su forma directa una variable categórica es un vector de nombres de categorías.

Table 6.1: Variable Género
Género
F
M
LGBT
M
M
F
F
F
M
M

Sin embargo para tratar a las variables categóricas con generalmente recurrimos a conteos. Esos conteos tienen la forma de y reciben el nombre de tablas. La tabla de conteos de una variable categórica tiene dos filas: una con las categorías de la variable y otra con la frecuencia o cantidad de veces que se observa esa categoría.

Table 6.2: Tabla de conteos de la variable Género
genero Freq
F 4
LGBT 1
M 5

Adicionalmente podemos expresar expresar expresar esos mismos datos como proporciones del total.

Table 6.3: Tabla de conteos de la variable Género
genero Freq
F 0.4
LGBT 0.1
M 0.5

¿Por qué pudimos expresar a los conteos como proporciones, lo que cuál implica realizar una división, operación matemática imposible para las variables nominales? Porque no realizamos la operación la operación sobre la variable, lo hacemos los conteos de la variable. Nos es posible dividir masculino entre género, pero podemos dividir 5 entre 10.

6.2.1 Tablas de contingencia de dos dimensiones.

Las tablas de una sola variable son útiles para conocer la distribución univariada de una variable categórica, expresada en cantidades o proporciones. Sin embargo el análisis de datos categóricos generalmente implica trabajar con más de una variable. Con más de una variable también podemos trabajar con tablas, a las que llamaremos tablas de contingencia.25 En función de la cantidad de variables que contemos en una tabla de contingencia definiremos el número de dimensiones de la tabla. Así, la Tabla 2 es una tabla de una dimensión. Una tabla de contingencia tiene 2 o más dimensiones. Es importante no confundir el número de categorías de las variables con el número de dimensiones de la tabla.

Para tablas de contingencia bidimensionales visualmente las dimensiones se nos presentan como filas y columnas. En la intersección de cada fila y columna hay una celda que registra el conteo de las observaciones que pertenecen a ambas categorías. En términos de conjuntos, el conteo de objetos en la intersección de A y B. Nótese que la tabla debe incluir todas las intersecciones posibles, dadas por las categorías de la variable, aun cuando no haya observación en ese conjunto de datos en particular. Se les asigna el conteo correspondiente: 0.

Table 6.4: Tabla de contingencia para género y edad
19 20 32 42 56
F 1 2 1 0 0
LGBT 1 0 0 0 0
M 0 0 1 1 3

Para tablas de contingencia bidimensionales también es posible expresar los conteos como proporciones, pero en este caso podemos calcular diferentes tipos de proporciones: sobre el total, sobre las filas o sobre las columnas.

Table 6.5: Proporciones sobre el total
19 20 32 42 56
F 0.1 0.2 0.1 0.0 0.0
LGBT 0.1 0.0 0.0 0.0 0.0
M 0.0 0.0 0.1 0.1 0.3
Table 6.5: Proporciones sobre las filas
19 20 32 42 56
F 0.25 0.5 0.25 0.0 0.0
LGBT 1.00 0.0 0.00 0.0 0.0
M 0.00 0.0 0.20 0.2 0.6
Table 6.5: Proporciones sobre las columnas
19 20 32 42 56
F 0.5 1 0.5 0 0
LGBT 0.5 0 0.0 0 0
M 0.0 0 0.5 1 1

6.2.2 Tablas de contingencia en R.

En R la función básica para obtener tablas de conteos –incluyendo tablas de contingencia– es table(). Es importante mencionar que la función table() no está pensada primariamente para el análisis visual de tablas, aunque podamos hacerlo. Produce solamente la tabla con los conteos con determinada estructura, de modo que podamos proseguir el análisis pasando esa tabla a otras funciones. Existen librerías con funciones para producir tablas de contingencias similares a las que ofrecen otros paquetes de software estadístico como SPSS, que incluyen además de los conteos proporciones sobre el total, filas, columnas, conteos marginales, residuales, modelos de independencia, etc. La aproximación de table() es de múltiples pasos, primero obtenemos la tabla y después realizamos, sobre esa estructura de datos, realizamos las demás operaciones. Existen funciones que imitan el estilo verboso de esos paquetes, como gmodels::CrossTable(). En mi opinión la sintaxis complicada de estas funciones y el exceso de información no las hacen recomendables.

6.2.2.1 Tablas de contingencia con table()

Esta función recibe como input 1 o más vectores de las clases factor, caracter o numérico. A estos últimos los coerciona a factor para poder operar sobre ellos. Los vectores deben tener el mismo largo. Nos regresa un objeto de la clase table, una estructura de datos especial para tablas. Dado que esta estructura forma parte de base:: muchas funciones la reciben como input. Crear la tabla con table() usualmente es es un paso intermedio en el análisis, no el uotput final.

La sintaxis de table() es table(x, y, useNA= c("no", "ifany", "always")), donde x y y son vectores y useNA= define el modo en que trataremos con los casos perdidos. "no" los excluye del conteo, "ifany" los incluye cuando están observados y "always" los incluye siempre en la tabla, aunque el conteo sea 0. Por defecto excluye a los NA del conteo. Dependerá de nuestro interés analítico incluir o no los casos perdidos en la tabla, en caso de hacerlo aparecerán como una nueva categoría de las variables.

table() nos regresa un objeto de la clase table. Al tener esta clase muchas otras funciones pueden reconocer que es una tabla de contingencia y hacer operaciones. chisq.test() para pruebas \(\chi\)22, ca::ca() para Análisis de Correspondencia, vcd::mosaic() para gráficos de mosaicos, entre otras, reciben como input un objeto de la clase table. También existe un método genérico summary() para tablas de contingencia, que regresa información sumaria sobre el objeto incluyendo una prueba de \(\chi\)2.

La estructura de datos que subyace a los objetos table es el array, una matriz que puede tener más de dos dimensiones.26 Los arrays producidos por table() tiene tantas dimensiones como variables hayamos incluido en la tabla. Al ser un array podemos hacer todas las operaciones –matemáticas y de manipulación– que podemos hacer con esa estructura: todas las operaciones algebraicas entre matrices y con escalares como sumas, restas, etc.; extraer subconjuntos con [,,,], etc. Cuando decimos que en R una tabla es un insumo para seguir trabajando lo decimos en serio.

Ese array tiene el atributo dimnames() con los nombres de filas, columnas, etc. tomados de los niveles del factor de las variables originales. Sin embargo al ser un atributo no están en la estructura de datos, la acompañan. El tipo de datos es numérico, así que nunca tendremos problemas para las operaciones matemáticas.

6.2.2.2 Proporciones y sumas marginales para una tabla de contingencia.

Cuando analizamos tablas de contingencia las proporciones marginales –totales, de fila o columna– facilitan la visualización de las diferencias. La función prop.table() se encarga de calcularlos. Esta función recibe como input una tabla y regresa otra, con las proporciones en lugar de los conteos.

La sintaxis de prop.table() es prop.table(x, márgen), donde x es un objeto de la clase table y margen es un número del 0 al 2 que indica el margen sobre el que se computará la proporción: 0 para el total de la tabla, 1 para las filas y 2 para la columnas. Para tablas de más de dos dimensiones podemos usar números mayores.

Si queremos obtener los perfiles de fila o columna podemos usar margin.table(), que regresa un vector con los perfiles marginales. La sintaxis de margin.table() es margin.table(x, márgen), donde x es un objeto de la clase table y margen un número del 1 al 2: uno para las sumas marginales de las filas y 2 para las columnas. Nos regresa un vector.

Si queremos agregar a la tabla las sumas marginales usamos la función addmargins(), con la sintaxis addmargins(x, c(margen, margen)). El vector de márgenes creado con c() observa las mismas reglas ya expuestas. Nos regresa un objeto de la clase table con las mismas dimensiones del original al que ha agregado una fila y/o una columna para las sumas marginales.

## rock
## No Sí 
##  7  3
## cumbia
## No Sí 
##  3  7
##     cumbia
## rock No Sí
##   No  1  6
##   Sí  2  1
##     cumbia
## rock  No  Sí
##   No 0.1 0.6
##   Sí 0.2 0.1
##     cumbia
## rock        No        Sí
##   No 0.1428571 0.8571429
##   Sí 0.6666667 0.3333333
##     cumbia
## rock       No       Sí
##   No 33.33333 85.71429
##   Sí 66.66667 14.28571
## rock
## No Sí 
##  7  3
## cumbia
## No Sí 
##  3  7
##      cumbia
## rock  No Sí Sum
##   No   1  6   7
##   Sí   2  1   3
##   Sum  3  7  10

6.3 Prueba de hipótesis de independencia estadística para tablas de contingencia.

Como vimos en las tablas del ejemplo anterior los oyentes de rock y cumbia parecen no ser las mismas personas: quién escucha rock tiene una probabilidad baja de escuchar cumbia y viceversa. Si cumbia y rock fueran variables medidas en la escala razón podríamos estimar el coeficiente de correlación, pero como son variables categóricas no es posible. Lo que sí podemos es verificar si hay alguna tipo de relación entre esas variables comparando los datos observados con una tabla ideal que presenta la distribución que recíproca que tendrían esas variables si estuvieran distribuidas al azar. Es decir, si escuchar cumbia no afectara la probabilidad de escuchar rock y viceversa. Esa tabla ideal no existe, pero podemos crearla y llamarla modelo de independencia: nos indica la forma que tendrían los conteos si las variables fueran independientes. Si la tabla observada tiene una gran divergencia con respecto al modelo de independencia podríamos afirmar que no hay independencia entre filas y columnas: hay algo que no es el azar que está incidiendo en su distribución.

6.3.1 El modelo de independencia.

Acompáñeme a un situación hipotética. Rexthor, the dog-bearer, una criatura mitológica y malvada que acecha a los analistas cualitativos nos ha robado una tabla de contingencia, pero ha olvidado llevarse las sumas marginales. Empecemos por agradecer que fue Rexthor y no \\\\\\\\\\\… y luego preguntémonos cómo podríamos reconstruir la tabla original con esos datos. La respuesta es: ninguna manera. Sin embargo podríamos crear una tabla completa en la que se respeten las sumas marginales y se aproxime -más o menos, nunca lo sabremos– a la tabla original.

Table 6.6: La tabla robada
No No 0
No 0
Sum No 3
No 0
0
Sum 7
No Sum 7
Sum 3
Sum Sum 10

¿Cómo lo hacemos? La forma más simple es multiplicar los conteos marginales para cada celda y luego dividirlos por la n, el total de observaciones. Las proporciones marginales indican la probabilidad de que un objeto –en el sentido estadístico– pertenezca a cierta categoría. En cada celda ubicamos el conteo según la probabilidad conjunta de la categoría de las filas y de la de las columnas. Por las proporciones marginales de la tabla robada sabemos sabemos que una observación tiene una probabilidad de 0.6 de no escuchar rock y \(P=0.3\) de no escuchar cumbia. Es decir, una probabilidad conjunta de 0.18 obtenida al multiplica 0.6 y 0.3. Podemos describir a ese valor como \(P(Rock_{no}|Cumbia_{no})\): la probabilidad de no escuchar rock ni cumbia.

En esta tabla las probabilidades marginales son conocidas, pero las centrales no. Estamos usando un criterio para construirla: que las probabilidades marginales tienen información suficiente para crear la tabla y que cualquier otra variación es producto del azar. Según nuestro supuesto las únicas variables que afectan la probabilidad de cada celda son ellas mismas, el resto es azar. Este modelo reconstruye los conteos asumiendo que esas variables son independientes en su distribución, es decir, dependen solamente de ellas mismas. Por eso lo llamamos modelo de independencia: son la reconstrucción ideal de una distribución de probabilidades conjuntas en el que ambas variables son independientes.

Veamos, pues, que conteos produce el modelo de independencia para la tabla robada.

## Warning in l + padding: longitud de objeto mayor no es múltiplo de la
## longitud de uno menor
## Warning in w * (side == "left"): longitud de objeto mayor no es múltiplo de
## la longitud de uno menor
## Warning in w1 * (side == "both"): longitud de objeto mayor no es múltiplo
## de la longitud de uno menor
## Warning in w * (side == "right"): longitud de objeto mayor no es múltiplo
## de la longitud de uno menor
## Warning in (w - w1) * (side == "both"): longitud de objeto mayor no es
## múltiplo de la longitud de uno menor
Table 6.7: Frecuencias esperadas bajo el supuesto de independencia estadística
A A 2.1
B A 0.9
A B 4.9
B B 2.1

Agradezcamos la amabilidad de Rexthor, the dog-bearer, que nos ha regresado la tabla original. Ahora podemos comparar cuan buena era la predicción de nuestro modelo. Directamente computaremos la diferencia entre los valores centrales de la tabla –los marginales ya sabemos que son iguales.

Table 6.8: Residuales crudos
No
No -1.1 1.1
1.1 -1.1

El modelo exageró el número de de personas que no escuchar cumbia o rock y el número de personas que escuchan ambos, y subestimó el número de personas que escuchan uno u otro. A esas divergencias entre el valor esperado –que el que el modelo había predicho– y el valor observado –el de la tabla original– es el error del modelo, a los que llamamos residuos crudos y son un paso intermedio, pero no tienen gran utilidad. Si quisiéramos obtener un estadístico que resumiera en un número la diferencia la suma de los residuos crudos siempre nos daría 0, lo cuál no es muy informativo. Karl Pearson resolvió este problema matemático con el estadístico \(\chi\)2. Al elevar al cuadrado los residuos se soluciona el problema de los signos positivos y negativos: cualquier número elevado al cuadrado es positivo. Al dividir la diferencia al cuadrado por el valor esperado se logra un efecto de normalización. Para obtener el estadístico usamos la formula \(\chi^2=\frac{\sum(O-E)^2}{E}\).

Aplicando la formula del estadístico \(\chi\)22 para nuestra tabla encontramos que el valor para nuestra tabla es 2.7437642. Para otras tablas podría ser un número mayor o menor, dependiendo de la divergencia entre datos observados y esperados.

6.3.2 Prueba de independencia para una tabla bidimensional.

Conociendo el estadístico \(\chi\)2 tenemos una medida sintética de la desviación entre los conteos que arrojó el modelo de independencia y los de la tabla observada. Como mencionamos previamente la tabla que obtenemos a partir del modelo de independencia no es la única tabla al azar posible, sólo la más probable. Podría ser interesante estimar la probabilidad de obtener una tabla como la observada bajo condiciones de independencia. Esto es lo que hacemos cuando realizamos una prueba de hipótesis de independencia estadística para una tabla de contingencia: estimar la probabilidad de nuestra tabla dada la hipótesis de independencia entre filas y columnas. Es preciso tener muy claro que no estamos estimando la probabilidad de nuestra hipótesis dados los datos, estamos haciendo exactamente lo contrario.

Para estimar la probabilidad de nuestros datos dada la hipótesis de independencia usamos la distribución \(\chi\)2, que se resume en una tabla que asigna una probabilidad a cada valor del estadístico \(\chi\)2. Resta solventar otro problema. El estadístico \(\chi\)2 es sintético, quizás demasiado sintético. Nuestra tabla es de 2x2 y podemos esperar que, todas las cosas igual, produzca siempre menos residuos que una tabla con más celdas, por un efecto simplemente matemático. Para corregir este problema la distribución \(\chi\)2 estipula grados de libertad, que corrigen las probabilidades por el tamaño de la tabla. Los grados de libertad se calculan usando la fórmula \(gl=(filas-1)(columnas-1)\). El número de filas menos uno multiplicado por el número de columnas menos uno, es decir, tenemos un grado de libertad. Con el valor del estadístico \(\chi\)2 y el valor de los grados de libertad podemos estimar la probabilidad de la tabla observada bajo condiciones de independencia estadística. En este caso es 0.0976345, este es nuestro p-value. Dependiendo del criterio que usemos para la prueba de hipótesis rechazamos o no la hipótesis de nulidad.

Nota general sobre las pruebas de hipótesis.
Las pruebas de hipótesis son una de las operaciones estadísticas más importantes, hay pocas dudas al respecto. Sin embargo es de la mayor importancia no ritualizarlas, reduciéndolas a verificar si el p-value es menor a 0.001 –¡tiene tres asteriscos! ¡es cienciaTM!– ni interpretarlas como lo que no son –una prueba de nuestra hipótesis sustantiva de investigación. En el marco frecuentista en el que nos estamos ubicamos una prueba de hipótesis sólo nos informa sobre la probabilidad de nuestros datos dada una hipótesis de nulidad, formalmente \(p(D|H0)\), donde H0 es la hipótesis de nulidad a la que podemos aceptar o rechazar. Esto no es igual a \(p(H~0~|D)\), la probabilidad de la hipótesis de nulidad dados nuestros datos. Y tampoco nos dice mucho sobre la calidad de la hipótesis de nulidad. Si nuestra hipótesis de nulidad es lisa y llanamente disparatada nuestros datos siempre tendrán una probabilidad muy baja de ocurrir dada esa hipótesis disparatada, pero en el mundo quien sabe. Siempre que sea posible es una buena práctica probar nuestros datos contra una hipótesis informada. La hipótesis de nulidad formulada como independencia estadística que probamos más arriba es bastante razonable, pero una hipótesis más sólida surgida de una teoría sustantiva sería muchísimo mejor. Nuestra hipótesis de nulidad podría ser cumbia y rock no son independientes, pero las probabilidades de escuchar ambos géneros musicales son mayores que 0.2. En ese caso haríamos una prueba de hipótesis más sólida.

6.4 Análisis de los residuos.

Aunque las pruebas de hipótesis de independencia estadística nos dan un criterio para considerar si hay o no una relación entre las variables que hemos tabulado el análisis de datos categóricos no se detiene allí. Si queremos saber cuáles categorías son las más divergentes –es decir, en cuáles es mayor la diferencia entre valores esperados y observados– podemos observar como se distribuyen los residuos. Los residuos crudos que elaboramos anteriormente nos dan una idea de las diferencias entre valores observados y esperados, pero es difícil compararlos de manera directa ya que no son sensibles a los tamaños de fila o columna. En nuestro caso todos los residuos son 1.1 o -1.1, pero no sabemos si un residuo de 1.1 eso es mucho o poco. Para nuestra tabla, con sólo 10 observaciones, es una divergencia bastante grande, pero esos mismos números para una para una tabla con conteos en el orden de los miles sería muy poco. Para solucionar este problema Karl Pearson ideó una fórmula que estandariza los residuos según la cuál \(Residuales Estandarizados=\frac{(O-E)}{\sqrt{E}}\). De este modo obtenemos los Residuales de Pearson.

Table 6.9: Residuales de Pearson
No
No -0.7590721 0.4969293
1.1595018 -0.7590721

6.4.1 Prueba \(\chi\)2 en R.

6.4.1.1 Pruebas de independencia con chisq.test()

La función chisq.test() de R realiza todos los pasos que hemos llevado a cabo de una manera muy simple y, dado que incluye algunos factores de corrección que no hemos considerado en el desarrollo anterior, más preciso. La sintaxis básica es chisq.test(x, correct=TRUE), donde x es un objeto de la clase table y correct= es un valor lógico que señala si se hará la corrección de Yates (TRUE, por defecto) o no (FALSE, opcional).27 En consola nos regresa un sumario de la prueba de hipótesis, pero podemos guardar el objeto completo resultante. Este pertenece a las clases htest y list y contiene información muy detallada sobre el modelo.

## Warning in chisq.test(x): Chi-squared approximation may be incorrect
## 
##  Pearson's Chi-squared test with Yates' continuity correction
## 
## data:  x
## X-squared = 0.81633, df = 1, p-value = 0.3663
## Warning in chisq.test(x, correct = FALSE): Chi-squared approximation may be
## incorrect
## 
##  Pearson's Chi-squared test
## 
## data:  x
## X-squared = 2.7438, df = 1, p-value = 0.09763
## Warning in chisq.test(x, correct = FALSE): Chi-squared approximation may be
## incorrect
## List of 9
##  $ statistic: Named num 2.74
##   ..- attr(*, "names")= chr "X-squared"
##  $ parameter: Named int 1
##   ..- attr(*, "names")= chr "df"
##  $ p.value  : num 0.0976
##  $ method   : chr "Pearson's Chi-squared test"
##  $ data.name: chr "x"
##  $ observed : 'table' int [1:2, 1:2] 1 2 6 1
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ rock  : chr [1:2] "No" "Sí"
##   .. ..$ cumbia: chr [1:2] "No" "Sí"
##  $ expected : num [1:2, 1:2] 2.1 0.9 4.9 2.1
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ rock  : chr [1:2] "No" "Sí"
##   .. ..$ cumbia: chr [1:2] "No" "Sí"
##  $ residuals: 'table' num [1:2, 1:2] -0.759 1.16 0.497 -0.759
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ rock  : chr [1:2] "No" "Sí"
##   .. ..$ cumbia: chr [1:2] "No" "Sí"
##  $ stdres   : 'table' num [1:2, 1:2] -1.66 1.66 1.66 -1.66
##   ..- attr(*, "dimnames")=List of 2
##   .. ..$ rock  : chr [1:2] "No" "Sí"
##   .. ..$ cumbia: chr [1:2] "No" "Sí"
##  - attr(*, "class")= chr "htest"

6.4.1.2 Pruebas de independencia paso a paso.

Aunque chisq.test() nos regresa una prueba de independencia muy detallada puede valer la pena el código completo con el que podemos producir esos mismos resultados. Quizás le resulte más clara la sintaxis de R que la notación matemática o quiera tomar alguno de los pasos intermedios para realizar una prueba de hipótesis diferente. La función más importante que definiremos es esperados(), una función que recibe una tabla de conteos y regresa los conteos esperados dado el modelo de independencia entre filas y columnas.

6.4.1.4 Estadístico chi cuadrado para la tabla x.

\(\chi^2=\sum\frac{(E-O)^2}{E}\)

## [1] 2.743764

6.4.1.6 Residuales de Pearson.

\(Residuales Estandarizados=\frac{(O-E)}{\sqrt{E}}\)

##     cumbia
## rock         No         Sí
##   No -0.7590721  0.4969293
##   Sí  1.1595018 -0.7590721

6.5 Métodos gráficos para tablas de contingencia.

La librería vcd::, Visualizing Cathegorical Data, ofrece varios métodos visuales para la exploración de tablas de contingencia. Los más importantes son mosaic(), que produce un gráfico de mosaico fortificado con información del modelo de independencia y assoc() para visualizar la distribución de los residuales de Pearson. No existe un equivalente a estas funciones dentro de ggplot2::.

## Loading required package: grid

6.5.1 Modelos loglineales para datos categóricos.

6.6 Análisis práctico de datos categóricos.

Este documento acompaña al más teórico Introducción al análisis de datos categóricos con R. Presenta un ejemplo práctico de análisis exploratorio de datos categóricos con una base de datos real, la que prepara el Instituto Nacional para el Federalismo y el Desarrollo Municipal compilando información sobre presidentes municipales en México. Se trabajan paralelamente los problemas de análisis de datos con los de manipulación de datos que surgen con frecuencia en el análisis.

6.6.1 La base de datos.

La base de datos primaria sobre la que trabajaremos es elaborada por el Sistema Nacional de Información Municipal y está disponible en formato .csv en http://www.snim.rami.gob.mx/

Trabajaremos especialmente con dos variables, el género de las y los presidentes municipales y el partido político al que representan.

## # A tibble: 2,389 x 19
##    estado  municipio  id_estado id_municipio nombre  ap_paterno ap_materno
##    <chr>   <chr>          <int>        <int> <chr>   <chr>      <chr>     
##  1 Aguasc… Aguascali…         1            1 MARIA … JIMENEZ    ESQUIVEL  
##  2 Aguasc… Asientos           1            2 LORENZ… CARRILLO   LARA      
##  3 Aguasc… Calvillo           1            3 FRANCI… LUEVANO    MARTINEZ  
##  4 Aguasc… Cosío              1            4 JUAN M… VILLALPAN… ADAME     
##  5 Aguasc… Jesús Mar…         1            5 NOEL    MATA       ATILANO   
##  6 Aguasc… Pabellón …         1            6 CUAUHT… ESCOBEDO   TEJEDA    
##  7 Aguasc… Rincón de…         1            7 FRANCI… RIVERA     LUEVANO   
##  8 Aguasc… San José …         1            8 MARIA … LOPEZ      GONZALEZ  
##  9 Aguasc… Tepezalá           1            9 OMAR    ISRAEL     CAMARILLO 
## 10 Aguasc… El Llano           1           10 RAMIRO  SALAS      PIZAÑA    
## # ... with 2,379 more rows, and 12 more variables: sexo <chr>,
## #   email_oficial <chr>, partido <chr>, descripcion <chr>,
## #   integrantes <chr>, pdo_gob_ini <chr>, pdo_gob_fin <chr>,
## #   direccion <chr>, pag_web <chr>, telefono <chr>, fax <chr>,
## #   fecha_actualizacion <chr>

6.7 Género y partido político.

Table 6.10: Presidentes municipales por partido en orden alfabético. ¿Error de codificación o categoría de adscripción?
H M presidente@jojutla.gob.mx
AP 27 2 0
APTS 8 0 0
C.C. 16 8 0
C.I. 9 0 0
C5M 73 9 0
CACPC 9 1 0
CAGYPT 3 0 0
CI 2 0 0
CJXT 7 3 0
COAL. 316 73 0
CPU 30 2 0
CPUCS 9 10 0
CPUGHYE 26 2 0
CPYB 3 1 0
CUHCR 10 5 0
DPDG 1 0 0
ES 1 0 0
MOR. 36 6 0
PAC 4 0 0
PAN 294 66 0
PARTIDO SOCIALDEMÓCRATA 0 0 1
PCHU 10 1 0
PES 19 0 0
PH 2 0 0
PI 5 1 0
PMACH 10 0 0
PMC 71 9 0
PNA 42 3 0
PRD 137 40 0
PRI 341 97 0
PRS 3 0 0
PS 2 0 0
PSD 4 1 0
PSI 4 0 0
PSIN 1 0 0
PT 64 2 0
PUP 4 1 0
PVEM 61 18 0
QROOUNE 0 1 0
SQROO 0 1 0
UYC 327 24 0

Esta tabla tiene varios problemas.

  1. La diferencia en las cantidades de municipios gobernados por partido complica dificulta la interpretación. Sería mejor expresar los conteos como proporciones de fila: ¿qué proporción de hombres y mujeres representan en el gobierno a cada partido?

  2. Tiene demasiadas filas. Hay muchos partidos pequeños que tiene sólo una presidencia municipal. Sería conveniente compactarlos en la categoría “Otros”.

  3. La categoría modal es “COAL.”, es decir, una coalición de partidos. No sabemos qué partidos la integran, así que valdría la pena recuperar la información de la columna integrantes en la misma base de datos.

Comenzaremos por atender cada punto.

  1. R inlcuye la función prop.table(), que toma como input a una tabla y regresa coo output una tabla con la misma estrucura, excepto que con los las proporciones en lugar de los conteos. La sintaxis básica de la función es prop.table(tabla, margen). Donde tabla es un objeto de la clase tabla, creado con la función table() o xtabs() y margen es un número que señala el márgen respecto al cuál se computará la proporción. Usamos 1 para proporciones sobre filas y 2 para proporciones sobre columnas. El valor por defecto es NULL y calcula las proporciones sobre el total de la tabla.
Table 6.11: Proporción de género por partido
H M presidente@jojutla.gob.mx
AP 0.9310345 0.0689655 0
APTS 1.0000000 0.0000000 0
C.C. 0.6666667 0.3333333 0
C.I. 1.0000000 0.0000000 0
C5M 0.8902439 0.1097561 0
CACPC 0.9000000 0.1000000 0
CAGYPT 1.0000000 0.0000000 0
CI 1.0000000 0.0000000 0
CJXT 0.7000000 0.3000000 0
COAL. 0.8123393 0.1876607 0
CPU 0.9375000 0.0625000 0
CPUCS 0.4736842 0.5263158 0
CPUGHYE 0.9285714 0.0714286 0
CPYB 0.7500000 0.2500000 0
CUHCR 0.6666667 0.3333333 0
DPDG 1.0000000 0.0000000 0
ES 1.0000000 0.0000000 0
MOR. 0.8571429 0.1428571 0
PAC 1.0000000 0.0000000 0
PAN 0.8166667 0.1833333 0
PARTIDO SOCIALDEMÓCRATA 0.0000000 0.0000000 1
PCHU 0.9090909 0.0909091 0
PES 1.0000000 0.0000000 0
PH 1.0000000 0.0000000 0
PI 0.8333333 0.1666667 0
PMACH 1.0000000 0.0000000 0
PMC 0.8875000 0.1125000 0
PNA 0.9333333 0.0666667 0
PRD 0.7740113 0.2259887 0
PRI 0.7785388 0.2214612 0
PRS 1.0000000 0.0000000 0
PS 1.0000000 0.0000000 0
PSD 0.8000000 0.2000000 0
PSI 1.0000000 0.0000000 0
PSIN 1.0000000 0.0000000 0
PT 0.9696970 0.0303030 0
PUP 0.8000000 0.2000000 0
PVEM 0.7721519 0.2278481 0
QROOUNE 0.0000000 1.0000000 0
SQROO 0.0000000 1.0000000 0
UYC 0.9316239 0.0683761 0
  1. El segundo problema no es de tablas, es un problema de codificación. Es decir, necesitamos recodificar la variable partido de tal modo que que se reduzca el número de categorías. Una posibilidad es hacerlo manualmente con la función dplyr::recode(). Sin embargo la función forcats::fct_lump() se dedica especialmente a compactar factores pasando determinadas categorías a una residual llamada “Otros”. En lugar de especificar que categorías pasan a “Otros” le indicamos cuantas categorías queremos que queden. Consevará n-1 categorías, aquellas con mayor número de observaciones, y creará la categoría “Otros” en la que estarán todas demás reunidas.
Table 6.12: Proporción de género para 19 partidos y Otros
H M presidente@jojutla.gob.mx
AP 0.9310345 0.0689655 0.000000
C.C. 0.6666667 0.3333333 0.000000
C5M 0.8902439 0.1097561 0.000000
CACPC 0.9000000 0.1000000 0.000000
CJXT 0.7000000 0.3000000 0.000000
COAL. 0.8123393 0.1876607 0.000000
CPU 0.9375000 0.0625000 0.000000
CPUCS 0.4736842 0.5263158 0.000000
CPUGHYE 0.9285714 0.0714286 0.000000
CUHCR 0.6666667 0.3333333 0.000000
MOR. 0.8571429 0.1428571 0.000000
PAN 0.8166667 0.1833333 0.000000
PCHU 0.9090909 0.0909091 0.000000
PES 1.0000000 0.0000000 0.000000
PMACH 1.0000000 0.0000000 0.000000
PMC 0.8875000 0.1125000 0.000000
PNA 0.9333333 0.0666667 0.000000
PRD 0.7740113 0.2259887 0.000000
PRI 0.7785388 0.2214612 0.000000
PT 0.9696970 0.0303030 0.000000
PVEM 0.7721519 0.2278481 0.000000
UYC 0.9316239 0.0683761 0.000000
Otros 0.8888889 0.0952381 0.015873
Table 6.12: Proporción de género para 9 partidos y Otros
H M presidente@jojutla.gob.mx
C5M 0.8902439 0.1097561 0.0000000
COAL. 0.8123393 0.1876607 0.0000000
PAN 0.8166667 0.1833333 0.0000000
PMC 0.8875000 0.1125000 0.0000000
PNA 0.9333333 0.0666667 0.0000000
PRD 0.7740113 0.2259887 0.0000000
PRI 0.7785388 0.2214612 0.0000000
PT 0.9696970 0.0303030 0.0000000
PVEM 0.7721519 0.2278481 0.0000000
UYC 0.9316239 0.0683761 0.0000000
Otros 0.8493590 0.1474359 0.0032051
  1. El tercer problema es el más complejo, pues implica tanto problemas técnicos de manejo de cadenas de caracteres como decisiones metodológicas de imputación de datos. La variable integrantes tiene como valor una cadena de caracteres con las abreviaturas de los partidos integrantes de la coalición separadas por guiones medios -. Primero debemos ubicar en columnas separadas a cada partido integrante. Utilizaremos la librería stringr::28, que reúne varias funciones de sintaxis simple para hacer operaciones sobre cadenas de caracteres.
## [1] 6
##                  sexo
## partido_coalicion   H   M presidente@jojutla.gob.mx
##             2016    0   0                         1
##             C.I.    9   0                         0
##             CI      2   0                         0
##             CPU    63   1                         0
##             DPDG    1   0                         0
##             ES      1   0                         0
##             MOR.   36   6                         0
##             PAC     4   0                         0
##             PAN   370  85                         0
##             PCHU   10   1                         0
##             PES    19   0                         0
##             PH      2   0                         0
##             PI      5   1                         0
##             PMACH  10   0                         0
##             PMC    71   9                         0
##             PNA    43   3                         0
##             PRD   203  47                         0
##             PRI   643 171                         0
##             PRS     3   0                         0
##             PS      2   0                         0
##             PSD     4   1                         0
##             PSI     4   0                         0
##             PSIN    2   1                         0
##             PT     69   2                         0
##             PUP     4   1                         0
##             PVEM   84  34                         0
##             UYC   327  24                         0
## Number of cases in table: 2379 
## Number of factors: 2 
## Test for independence of all factors:
##  Chisq = 2468.7, df = 52, p-value = 0
##  Chi-squared approximation may be incorrect

## Number of cases in table: 2379 
## Number of factors: 2 
## Test for independence of all factors:
##  Chisq = 95.43, df = 16, p-value = 2.472e-13
##  Chi-squared approximation may be incorrect

Table 6.13: Independencia estadística condicional al Grado de Marginación
GM pvalue
Alto 0.0e+00
Bajo 0.0e+00
Medio 0.0e+00
Muy alto 0.0e+00
Muy bajo 5.9e-06
Table 6.13: Independencia estadística condicional a Ruralidad
rural valorp
NA 0
No 0
0

  1. preferimos ese términos a tablas cruzadas. Sueno mucho más culto y las cruzadas terminaron en el Siglo XIII.

  2. Datos curiosos: cuando el array es de una dimensión también pertenece a la clase vector, cuando tiene dos dimensiones también pertenece a la clase matriz o matrix.

  3. Dado que no todos los programas estadísticos realizan la corrección de Yates puede ser útil eliminar esta opción para obtener resultados consistentes.

  4. ¿Adivinen quién la escribió?