33 votos

¿Cuál es la mejor visualización para tablas de contingencia?

¿Cuál es el mejor tipo de gráfico, desde el punto de vista estadístico, para mostrar una tabla de contingencia, la cual típicamente se analiza mediante la prueba de chi-cuadrado? ¿Es un gráfico de barras apiladas, un gráfico de barras apiladas, un mapa de calor, un gráfico de contorno, un gráfico de dispersión con jitter, un gráfico de líneas múltiples u otra cosa? ¿Deberían mostrarse valores absolutos o porcentajes?

Edición: O como sugiere @forecaster en los comentarios, la tabla de números en sí misma es un gráfico simple y debería ser suficiente.

4 votos

A veces, la tabla de datos es el mejor método de visualización en comparación con los gráficos. Las tablas de contingencia son un ejemplo clásico de esto.

1 votos

Punto importante, aunque no estoy de acuerdo en que siempre sea la mejor opción.

2 votos

Por eso dije "a veces". Recomendaría, el libro de Stephen Few Show me the numbers, que tiene una sección entera dedicada a las tablas.

16voto

erik Puntos 3923

Diferentes visuales serán mejores resaltando diferentes características, pero los gráficos de mosaico funcionan bien para una visión general (para ver si algo destaca). Tal vez eso es lo que quisiste decir con el gráfico de barras esquivado. Al igual que la mayoría de las opciones, no son simétricos en el sentido de que representan mejor las frecuencias relativas en una dimensión que en la otra. Una característica interesante es que también se representan las frecuencias marginales.

ingresar descripción de la imagen aquí

ingresar descripción de la imagen aquí

0 votos

Esto es bueno. Tanto los números como las proporciones están representados. Los números también se pueden poner en el gráfico. Si el orden de los elementos del eje x está organizado, se verá aún mejor. Cuando mencioné "dodged" me refería a un gráfico de barras común con categorías uno al lado del otro, en lugar de apiladas unas sobre otras (ver posición='dodge' en esta página: r-bloggers.com/using-r-barplot-with-ggplot2).

3 votos

+1 Este diseño a menudo funciona muy bien de hecho para datos relativamente simples ; por otro lado, he encontrado que también rápidamente se vuelve difícil de pensar para datos más complicados, a pesar de que en la literatura se destaca su extensibilidad a tablas de contingencia de dimensiones arbitrarias. Aún así, ningún diseño funciona bien en tales circunstancias. Un detalle pequeño con este ejemplo es que parece que aceptaste el orden alfabético predeterminado "tarde" ... "mediodía" ofrecido por tu programa, mientras que preservar el orden temporal parece una opción más natural.

15voto

Sean Hanley Puntos 2428

No va a haber una solución única aquí. Si tienes una tabla muy simple (por ejemplo, $2\times 2$), simplemente presentar la tabla probablemente sea lo mejor. Si quieres una figura real, los gráficos de mosaico (como sugiere @xan) probablemente sean un buen lugar para empezar. Hay algunas otras opciones que son análogas a los gráficos de mosaico, incluyendo gráficos de filtro, gráficos de asociación y gráficos de presión dinámica (ver mi pregunta aquí: Alternativa a los gráficos de filtro/mosaico para tablas de contingencia); el libro de Michael Friendly, Visualizing Categorical Data, sería un buen recurso (basado en SAS) para este tema y el paquete vcd es un buen recurso para implementar esas ideas en R.

Sin embargo, a medida que las tablas tienen un mayor número de filas y columnas, se vuelven más difíciles de usar, en mi opinión. Una opción de visualización diferente es realizar/graficar un análisis de correspondencias. Un análisis de correspondencias es análogo a ejecutar un análisis de componentes principales tanto en las filas como en las columnas de la tabla de contingencia. Luego ambas se grafican juntas con un biplot. Aquí hay un ejemplo basado en R utilizando los datos de la respuesta de @xan:

library(ca)
tab = as.table(rbind(c(28, 4,  0, 56),
                     c(38, 5,  9, 10),
                     c( 6, 6, 14, 13) ))
names(dimnames(tab)) = c("actividad", "período")
rownames(tab)        = c("alimentación", "social", "viaje")
colnames(tab)        = c("mañana", "mediodía", "tarde", "noche")
tab
#         período
# actividad mañana mediodía tarde noche
#   alimentación        28    4         0      56
#   social                 38    5         9      10
#   viaje                     6      6        14    13
plot(ca(tab))

introducir descripción de la imagen aquí

Para interpretar este gráfico, cuanto más cerca estén dos puntos del mismo tipo, más similares son esos dos perfiles de fila/columna. Y cuanto más cerca estén dos puntos de diferentes tipos, más de su masa de probabilidad está en la celda que representa su intersección.

En R existe el paquete ca; este aviso (pdf) también puede ser útil.

1 votos

Muy útil. Aparentemente falla con valores pequeños, por ejemplo: tt = with(mtcars, table(factor(gear), factor(vs))); plot(ca(tt)); Error in x[, dim] : subscript out of bounds

0 votos

Eso es porque uno de los factores (es decir, factor(vs)) tiene solo dos niveles; necesitas al menos tres. Intenta ttt = with(mtcars, table(factor(gear), factor(cyl))); plot(ca(ttt)).

0 votos

Muy buena exhibición de relaciones entre diferentes factores.

15voto

Nick Cox Puntos 22819

Estoy de acuerdo en que la mejor trama no existe independientemente del conjunto de datos, la audiencia y el propósito. Para dos variables medidas, los gráficos de dispersión son probablemente el diseño que deja a todos los demás atrás, excepto para propósitos específicos, pero no existe un líder del mercado evidente para datos categóricos.

Mi objetivo aquí es simplemente mencionar un método simple, a menudo redescubierto o reinventado, pero no obstante a menudo pasado por alto incluso en monografías o libros de texto que cubren gráficos estadísticos.

Por ejemplo, cubriendo los mismos datos publicados por xan:

introducir descripción de la imagen aquí

Si se desea un nombre, como a menudo sucede, esto es un gráfico de barras bidireccional (en este caso). No catalogaré otros términos aquí, excepto que gráfico de barras múltiple es una alternativa común con un sabor similar. (Mi pequeña objeción al "gráfico de barras múltiple" es que "múltiple" no descarta los gráficos de barras apilados o lado a lado, que son muy comunes, mientras que "bidireccional" para mí implica más claramente un diseño de fila y columna, aunque a su vez puede tomar ejemplos para que eso quede claro.

Las ventajas y desventajas de este tipo de representación gráfica también son simples, pero mencionaré algunas. Como me encanta este diseño (que se remonta al menos a la década de 1930), otros pueden querer agregar críticas más afiladas.

+1. La idea es fácilmente entendible, incluso por grupos no técnicos. En este ejemplo, las alturas o longitudes de las barras codifican las frecuencias. En otros ejemplos, podrían codificar porcentajes calculados de cualquier manera que desee, residuos, etc.

+2. La estructura de fila y columna coincide con la de una tabla. También puede agregar valores numéricos. Las cantidades muy pequeñas e incluso ceros implícitos son claramente evidentes, lo cual no siempre es el caso con otros diseños (por ejemplo, gráficos de barras apilados, gráficos de mosaico). El etiquetado de filas y columnas suele ser más eficiente que agregar una clave o leyenda, con el "vaivén" mental que eso requiere. Así, este diseño hibrida ideas de gráficos y tablas, lo cual aparentemente molesta a algunos lectores; por el contrario, argumentaría que las fuertes distinciones entre Figuras y Tablas son solo vestigios históricos, obsoletos ahora que los investigadores pueden preparar sus propios documentos y no tienen que depender de diseñadores, compositores e impresoras.

+3. Las extensiones a diseños tridimensionales y superiores son fáciles en principio. Ponga dos o más variables como variables compuestas en uno o ambos ejes, o presente una serie de dichos gráficos. Naturalmente, cuanto más complicado sea el diseño, más complicada será la interpretación.

+4. El diseño permite claramente variables ordinales en ambos ejes. El orden se puede expresar (por ej.) por sombreado apropiado, así como por el orden de las categorías en ese eje. El orden de las categorías en los ejes puede estar determinado por su significado, o mejor determinado por las frecuencias; el orden alfabético según las etiquetas de texto puede ser un valor predeterminado, pero nunca debería ser la única elección considerada.

-1. Al ser general en diseño, el gráfico puede ser menos eficiente en mostrar ciertos tipos de relaciones. En particular, un gráfico de mosaico puede mostrar de manera clara las desviaciones de la independencia. Por otro lado, cuando las relaciones entre variables categóricas son complicadas o poco claras, entonces típicamente ningún gráfico es bueno para mostrar más que ese hecho débil.

-2. En ciertos aspectos, el diseño es ineficiente en el uso del espacio al dejar espacio para cada combinación cruzada, independientemente de si ocurre o no con qué frecuencia. Este es el vicio del mismo principio considerado como virtud. El diseño particular anterior espacia las categorías de manera equitativa independientemente de su frecuencia; sacrificar eso a menudo implica sacrificar etiquetas marginales legibles, las cuales valoro mucho. En este ejemplo, las etiquetas de texto resultan ser todas muy cortas, pero eso está lejos de ser típico.

Nota: Parece que los datos de xan son inventados, así que no intentaré una interpretación más allá de lo que se intenta en otras respuestas. Pero una sabiduría casera merece la última palabra aquí: el mejor diseño para ti es aquel que mejor transmite a ti y a tus lectores la estructura de algunos datos reales que te importan.

Otros ejemplos incluyen

¿Cómo se puede visualizar la relación entre 3 variables categóricas?

Gráfico para la relación entre dos variables ordinales

EDIT La idea general, y una implementación en Stata, están ahora escritas en este artículo.

1 votos

+1 por otra opción viable y una gran discusión. Permíteme hacer una pregunta sobre gráficos de barras bidireccionales / señalar otra posible desventaja: Hay una 'caja' no marcada, pero claramente perceptible dentro de la cual se pueden trazar las barras. A medida que la barra se acerca a la parte superior de la caja, alcanza el 100%. ¿Cómo se determina ese valor? (N.B., las tablas de contingencia siempre son multinominales en cierto sentido, con un total conocido.) Hacer que la parte superior de la caja sean sumas de filas o sumas de columnas promoverá inferencias perceptuales diferentes. (No parece que se utilice la suma de la tabla, ya que muchas barras serían demasiado pequeñas para diferenciarlas.)

1 votos

@gung Gracias. Puedo comentar en mi propio programa de Stata, utilizado aquí y en mis ejemplos en otros lugares del CV. El programa es tabplot de SSC. La altura de las barras es necesariamente alguna fracción de la altura de la barra más alta o larga; el espacio disponible para eso se determina por cuántas filas se están mostrando. El usuario puede anular el tamaño de espacio predeterminado, pero luego corre el riesgo de que las barras se toquen u oculten entre sí. Si las barras pueden ser negativas además de positivas, las cosas no son más fáciles. Me imagino que la misma restricción se aplica con cualquier otro programa. ¡En resumen, barras que no se tocan implican espacio en blanco!

0 votos

Actualizando el comentario anterior: para los lectores que utilizan Stata, el comando tabplot ahora está documentado a través del Stata Journal (se añadió un enlace a la respuesta anterior en una EDICIÓN). El artículo es accesible para todos y las personas que no utilizan código de Stata deberían pasar directamente por el código, incluso mientras se preguntan cómo hacerlo en su propio software favorito.

11voto

Devon_C_Miller Puntos 126

Para complementar las respuestas de @gung y @xan, aquí hay un ejemplo de gráficos de mosaico y asociación utilizando vcd en R.

> tab
        periodo
actividad mañana mediodía tarde noche
  comer       28    4         0      56
  social      38    5         9      10
  viajar       6    6        14      13

Para obtener los gráficos:

require(vcd)
mosaic(tab, shade=T, legend=T)
assoc(tab, shade=T, legend=T)

enter image description here

enter image description here

Ambos presentan intuitivamente desviaciones de las frecuencias esperadas... El modelo por defecto es el de independencia mutua, pero puede cambiarse (por ejemplo a independencia conjunta si hay una clara variable de respuesta) a través del argumento expected.

Ver también:

4voto

kjetil b halvorsen Puntos 7012

Una idea que a veces es útil, especialmente para tablas algo grandes, es reordenar filas/columnas para que cualquier estructura sea más clara. Una manera de hacer el reordenamiento es usar el orden de clasificación de los puntajes de filas/columnas del análisis de correspondencia (en el primer autovalor). Voy a mostrar esto con un ejemplo, en R:

data(hobbies, package="FactoMineR")

htable <- matrix(as.numeric(NA), nrow=18, ncol=7,
                 dimnames=list( colnames(hobbies)[1:18],
                                names(with(hobbies, table(Profession)))))

### Luego llenamos las tablas con valores:

for(hob in rownames(htable)) {
    htable[hob, ] <- table(hobbies[, hob],  hobbies[, "Profession"])[2,] 
}

### Esto podría ser criticado, porque da más peso a las personas con más hobbies   

Luego hacemos el simple análisis de correspondencia, reordenamos, y simplificamos algunos nombres para hacer que la tabla quepa en una página:

### Tabla reordenada: 

reorder_table <- function(tab) {
  catable <-  MASS::corresp(tab)
  RS <- catable$rscore ; CS <- catable$cscore
  tab[order(RS), order(CS)]
}

htable_reordered <- reorder_table(htable)

colnames(htable_reordered) <- abbreviate(colnames(htable_reordered))

round(prop.table(htable_reordered, 1), 2)   

                Mngm Frmn Othr Tchn Empl Mnll Unsw
Exhibition      0.28 0.15 0.03 0.06 0.33 0.10 0.04
Show            0.27 0.13 0.03 0.07 0.37 0.09 0.04
Volunteering    0.24 0.15 0.04 0.06 0.35 0.11 0.05
Playing music   0.25 0.13 0.04 0.07 0.37 0.09 0.06
Travelling      0.26 0.14 0.03 0.07 0.33 0.11 0.06
Computer        0.23 0.13 0.03 0.08 0.35 0.12 0.06
Sport           0.23 0.14 0.03 0.07 0.34 0.12 0.06
Cinema          0.23 0.13 0.03 0.06 0.37 0.11 0.07
TV              0.21 0.13 0.04 0.06 0.34 0.14 0.08
Reading         0.20 0.12 0.03 0.05 0.39 0.13 0.08
Walking         0.18 0.13 0.03 0.06 0.37 0.15 0.09
Listening music 0.17 0.11 0.03 0.06 0.38 0.15 0.10
Gardening       0.18 0.12 0.03 0.06 0.34 0.18 0.09
Mechanic        0.18 0.13 0.03 0.08 0.29 0.21 0.09
Collecting      0.16 0.11 0.02 0.07 0.38 0.17 0.09
Cooking         0.15 0.10 0.03 0.05 0.42 0.14 0.10
Knitting        0.10 0.09 0.04 0.03 0.54 0.08 0.12
Fishing         0.13 0.12 0.02 0.08 0.21 0.28 0.14

Para facilitar la lectura, una tabla con nombres con sus abreviaturas:

 "Unskilled worker" "Unsw"
 "Manual labourer"  "Mnll"
 "Technician"       "Tchn"
 "Foreman"          "Frmn"
 "Management"       "Mngm"
 "Employee"         "Empl"
 "Other"            "Othr"

¡El grupo "Otro" parece extraño, con un interés uniformemente menor en hobbies que todos los demás! Y observa "Fishing", los grupos con un alto interés general en hobbies tienen un interés bajo, mientras que para "Manual labourer" y "Unskilled worker" puntúan más alto. ¿Es tan fácil de ver en la tabla original?

Editar

Pero aun así la tabla reordenada puede ser difícil de leer. Intentamos mejorarlo. Primero, expresamos la tabla en porcentajes y no en proporciones. Luego colorearemos los números usando el paquete gt. El resultado abajo:

tabla reordenada con porcentajes de colores

Código R para esto:

rtable <- round(100*prop.table(htable_reordered, 1), 0)  

library(gt)

as.data.frame(rtable) |> gt(rownames_to_stub=TRUE) |> 
  data_color(palette="Blues", method="numeric", apply_to="text",
             domain=c(-10,54)) |> gtsave(filename="./gthobbies.png")

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X