20 votos

Visualización de respuestas Likert usando R o SPSS

Tengo 82 encuestados en 2 grupos (43 en el Grupo A y 39 en el Grupo B) que completaron una encuesta de 65 preguntas de Likert, cada una con un rango de 1 a 5 (totalmente de acuerdo - totalmente en desacuerdo). Por lo tanto, tengo un marco de datos con 66 columnas (1 para cada pregunta + 1 que indica la asignación de grupo) y 82 filas (1 para cada encuestado).

Usando R o SPSS, ¿alguien sabe una forma efectiva de visualizar estos datos?

Necesito algo como esto: introducir descripción de la imagen aquí
(desde Jason Bryer)

Pero no puedo hacer funcionar la sección inicial del código. Alternativamente, encontré ejemplos realmente buenos de cómo visualizar datos de Likert de una publicación anterior en Cross Validated: Visualizing Likert Item Response Data pero no hay guías o instrucciones sobre cómo crear estos gráficos de recuento centrados o gráficos de barras apilados utilizando R o SPSS.

1 votos

Hola Adam, para aclarar aún más, ¿querías usar las visualizaciones para mostrar diferencias entre los grupos? Si es así, ese no es un método recomendado.

0 votos

El paquete de Jason Bryer no solía funcionar para mí, pero creo que lo actualizó y ahora está funcionando de maravilla. También agregué una solicitud de extracción con una función adicional para almacenar los nombres de las columnas como atributos y grupos. Utilizando esto, puedo visualizar fácilmente un cuestionario Likert de 45 preguntas dividido en grupos, incluso dividido contra otra variable si así lo elijo. (Genero la salida usando knitr, por lo que termina con muchos subgráficos en un sitio web, no un solo gráfico gigante). Hice una descripción detallada aquí: reganmian.net/blog/2013/10/02/...

0 votos

Solo para tu información, para aquellos de ustedes que estén leyendo estas respuestas en el futuro, parece que algunas de las características y funcionalidades de irutils relacionadas con los datos de Likert se han trasladado al paquete R de Likert (ver CRAN aquí).

31voto

DavLink Puntos 101

Si realmente quieres usar gráficos de barras apiladas con una gran cantidad de elementos, aquí tienes dos posibles soluciones.

Usando irutils

Me encontré con este paquete hace unos meses.

A partir de la confirmación 0573195c07 en Github, el código no funcionará con un argumento grouping=. Vamos a por la sesión de depuración del viernes.

Empieza descargando una versión comprimida desde Github. Necesitarás modificar el archivo R/likert.R, específicamente las funciones likert y plot.likert. Primero, en likert, se usa cast() pero el paquete reshape nunca se carga (aunque hay una instrucción import(reshape) en el archivo NAMESPACE). Puedes cargarlo tu mismo antes. Segundo, hay una instrucción incorrecta para obtener etiquetas de elementos, donde hay una i que sobra alrededor de la línea 175. Esto también debe corregirse, por ejemplo, reemplazando todas las apariciones de likert$items[,i] por likert$items[,1]. Luego puedes instalar el paquete como estás acostumbrado en tu máquina. En mi Mac, hice lo siguiente:

% tar -czf irutils.tar.gz jbryer-irutils-0573195
% R CMD INSTALL irutils.tar.gz

Luego, con R, prueba lo siguiente:

library(irutils)
library(reshape)

# Simula algunos datos (82 encuestados x 66 elementos)
resp <- data.frame(replicate(66, sample(1:5, 82, replace=TRUE)))
resp <- data.frame(lapply(resp, factor, ordered=TRUE, 
                          levels=1:5, 
                          labels=c("Totalmente en desacuerdo","En desacuerdo",
                                   "Neutral","De acuerdo","Totalmente de acuerdo")))
grp <- gl(2, 82/2, labels=LETTERS[1:2]) # supongamos un tamaño de grupo igual por simplicidad

# Resumir respuestas por grupo
resp.likert <- likert(resp, grouping=grp)

Eso debería funcionar sin problemas, pero la representación visual será horrible debido al gran número de elementos. Funciona sin agrupación (por ejemplo, plot(likert(resp))).

enter image description here

Por lo tanto, sugiero reducir tu conjunto de datos a subconjuntos más pequeños de elementos. Por ejemplo, usando 12 elementos,

plot(likert(resp[,1:12], grouping=grp))

Obtengo un gráfico de barras apiladas 'legible'. Probablemente puedas procesarlos después. (Esos son objetos ggplot2, pero no podrás organizarlos en una sola página con gridExtra::grid.arrange() debido a problemas de legibilidad!)

enter image description here

Solución alternativa

Me gustaría llamar tu atención sobre otro paquete, HH, que permite trazar escalas Likert como gráficos de barras apiladas divergentes. Podríamos reutilizar el código anterior como se muestra a continuación:

resp.likert <- likert(resp)
detach(package:irutils)
library(HH)
plot.likert(resp.likert$results[,-6]*82/100, main="")

pero eso complicará un poco las cosas porque necesitamos convertir frecuencias en recuentos, seleccionar el objeto likert producido por irutils, desasociar el paquete, etc. Entonces comencemos de nuevo con estadísticas frescas (recuentos):

plot.likert(t(apply(resp, 2, table)), main="", as.percent=TRUE,
            rightAxisLabels=NULL, rightAxis=NULL, ylab.right="", 
            positive.order=TRUE)

enter image description here

Para usar una variable de agrupación, necesitarás trabajar con una array de valores numéricos.

# calcular frecuencias de respuestas por separado por grp
resp.array <- array(NA, dim=c(66, 5, 2))
resp.array[,,1] <- t(apply(subset(resp, grp=="A"), 2, table))
resp.array[,,2] <- t(apply(subset(resp, grp=="B"), 2, table))
dimnames(resp.array) <- list(NULL, NULL, group=levels(grp))
plot.likert(resp.array, layout=c(2,1), main="")

Esto producirá dos paneles separados, pero caben en una sola página.

enter image description here

Editar 2016-6-3

  1. A partir de ahora likert está disponible como un paquete separado.
  2. No necesitas la librería reshape o desasociar tanto irutils como reshape

0 votos

La última gráfica me recuerda a las pirámides de población. Deberíamos obtener algunos datos reales para ver cómo funcionan "en la naturaleza", con algunos datos que no sean tan ordenados. Aunque debo admitir que son llamativas y bonitas.

0 votos

@Andy Ese es el caso, de hecho. Ver HH::as.pyramidLikert.

1 votos

+1, la librería (HH) es definitivamente la opción correcta. Pero algo ha salido mal con tu penúltimo gráfico en el orden de acuerdo/desacuerdo, etc.

7voto

Judioo Puntos 625

Empecé a escribir una publicación en el blog sobre la recreación de muchas de las gráficas en la publicación que mencionas (Visualizando datos de respuestas de elementos Likert) en SPSS, así que supongo que esto será una buena motivación para terminarlo.

Como señala Michelle, el hecho de que tengas grupos es un giro nuevo en comparación con las preguntas anteriores. Y aunque los grupos pueden tenerse en cuenta utilizando los gráficos de barras apiladas, en mi opinión se incorporan mucho más fácilmente en el ejemplo de gráficos de puntos en la publicación original de chl. He incluido el código SPSS para generar esto al final de la publicación, básicamente implica saber cómo remodelar sus datos en el formato adecuado para generar dicha gráfica (se proporciona una anotación en el código para esperemos aclarar algo de eso). Aquí usé una codificación redundante (color y forma) para distinguir los puntos que provienen de los dos grupos, y hice los puntos semitransparentes para que puedas ver cuando se superponen (otra opción sería evitar los puntos cuando se superponen).

Figura 1: Gráficos de puntos por grupo

¿Por qué esto es mejor que los gráficos de barras apiladas? Los gráficos de barras apiladas codifican información en la longitud de las barras. Cuando intentas hacer comparaciones entre longitudes de barras, ya sea dentro de la misma categoría de eje o entre paneles, el apilamiento impide que las barras tengan una escala común. Por ejemplo, he proporcionado una imagen en la Figura 2 en la que se colocan dos barras en un gráfico en el que su ubicación inicial es diferente, ¿cuál es la más ancha (a lo largo del eje horizontal)?

Figura 2: Barras sin una escala común

Compara eso con el gráfico en la Figura 3 a continuación, en el que las dos barras (de la misma longitud) se trazan desde el mismo punto inicial. He hecho intencionalmente la tarea difícil, pero deberías poder decir cuál es más larga.

Figura 3: Barras con una escala común

Los gráficos de barras apiladas están haciendo esencialmente lo que se muestra en la Figura 2. Los gráficos de puntos pueden considerarse más similares a lo que se muestra en la Figura 3, simplemente reemplaza la barra con un punto al final de la barra.

No voy a decir que no generes un gráfico en particular para el análisis exploratorio de datos, pero sugeriría evitar los gráficos de barras apiladas al usar tantas categorías. Los gráficos de puntos tampoco son una panacea, pero creo que hacer comparaciones entre paneles con los gráficos de puntos es mucho más fácil que con los gráficos de barras apiladas. Considera algunos de los consejos que proporciono en mi publicación de blog aquí para las tablas también, intenta ordenar y/o separar los gráficos en categorías significativas, y asegúrate de que los elementos que deseas mirar juntos estén más cerca en los gráficos. Aunque algunos de los métodos de trazado pueden adaptarse bien a muchas preguntas (los mapas de calor categóricos son un ejemplo), sin ordenar seguirá siendo difícil identificar patrones significativos (además de los valores atípicos obvios).

Una nota sobre el uso de SPSS. SPSS puede generar cualquiera de los gráficos vinculados anteriormente, aunque a menudo implica saber cómo dar forma a sus datos (lo mismo es cierto para ggplot, pero las personas han estado desarrollando paquetes para hacer básicamente la remodelación por usted). Para comprender mejor cómo funciona el lenguaje GPL de SPSS, en realidad sugeriría leer el libro de Hadley Wickham sobre ggplot2 en la serie Use R! . Presenta la gramática necesaria para comprender cómo funciona el GPL de SPSS, ¡y es una lectura mucho más fácil que el manual de programación GPL que viene con SPSS! Si tienes alguna pregunta sobre la generación de gráficos específicos en SPSS, sería mejor hacer una pregunta para cada gráfico (¡he hablado lo suficiente aquí!) Actualizaré esta respuesta con un enlace si alguna vez llego a hacer mi publicación en el blog replicando algunos de los otros gráficos. Para una prueba de concepto de los mapas de calor o gráficos de fluctuación, puedes ver otra publicación de mi blog, Algunos ejemplos de Corrgrams en SPSS.

Código SPSS utilizado para generar la Figura 1

****************************************.
input program. */ haciendo datos falsos similares a los tuyos.
loop #i = 1 to 82.
compute case_num = #i.
end case.
end loop.
end file.
end input program.
execute.
dataset name likert.

*haciendo número en grupos.
compute group = 1.
if case_num > 43 group = 2.
value labels group
1 'A'
2 'B'.

*esto hace 5 variables con categorías entre 0 y 5 (similar a datos Likert con 5 categorías más datos faltantes).
vector V(5).
do repeat V = V1 to V5.
compute V = TRUNC(RV.UNIFORM(0,6)).
end repeat.
execute.

value labels V1 to V5
0 'faltante'
1 'muy en desacuerdo'
2 'en desacuerdo'
3 'neutral'
4 'de acuerdo'
5 'muy de acuerdo'.
formats case_num group V1 to V5 (F1.0).
*****************************************.

*Como quiero dividir por variable, voy a remodelar mis datos para que todas las variables "V" estén en una columna (apilándolas en formato largo).
varstocases
/make V from V1 to V5
/index orig (V).

*Voy a graficar los puntos, así que agrego esa información (también podrías agregar totales si quisieras graficar porcentajes.
DATASET DECLARE agg_lik.
AGGREGATE
  /OUTFILE='agg_lik'
  /BREAK=orig V group
  /count_lik=N.
dataset activate agg_lik.

*ahora la parte divertida, generar el gráfico.
*El eje X, dim(1), es el recuento de respuestas Likert dentro de cada categoría para cada pregunta original.
*El eje Y, dim(2), son las respuestas Likert, y el tercer eje se utiliza para panelar las observaciones por las preguntas originales, dim(4) aquí porque quiero paneles
por filas en lugar de columnas.
DATASET ACTIVATE agg_lik.
* Constructor de gráficos.
GGRAPH
  /GRAPHDATASET NAME="graphdataset" VARIABLES=count_lik V group orig 
    MISSING=LISTWISE REPORTMISSING=NO
  /GRAPHSPEC SOURCE=INLINE.
BEGIN GPL
  SOURCE: s=userSource(id("graphdataset"))
  DATA: count_lik=col(source(s), name("count_lik"))
  DATA: V=col(source(s), name("V"), unit.category())
  DATA: group=col(source(s), name("group"), unit.category())
  DATA: orig=col(source(s), name("orig"), unit.category())
  GUIDE: axis(dim(1), label("Count"))
  GUIDE: axis(dim(2))
  GUIDE: axis(dim(4))
  GUIDE: legend(aesthetic(aesthetic.color.exterior), label("group"))
  GUIDE: text.title(label("Figura 1: Gráficos de puntos por grupo"))
  SCALE: cat(aesthetic(aesthetic.color.exterior), include("1", "2"))
  SCALE: cat(aesthetic(aesthetic.shape), map(("1", shape.circle), ("2", shape.square)))
  ELEMENT: point(position(count_lik*V*1*orig), color.exterior(group), color.interior(group), transparency.interior(transparency."0.7"), size(size."8px"), shape(group))
END GPL.
*Las declaraciones "SCALE: cat" mapean diferentes formas que uso para asignar a los dos grupos en el gráfico, y trazo el interior de los puntos como parcialmente transparente.
*Con algo de edición posterior deberías poder hacer que el gráfico se vea como lo tengo en la publicación de estadísticas.
****************************************.

0 votos

Un punto fuerte para mí por discutir de manera educada pero penetrante las deficiencias de las gráficas de barras apiladas, que son fáciles de entender en principio pero muchas veces mucho menos fáciles de decodificar en la práctica.

5voto

Arthur Knopper Puntos 199

Oh bueno, creé el código antes de que lo aclararas. Debería haber esperado, pero pensé que debería publicarlo para que cualquiera que venga aquí pueda reutilizar este código.

Datos ficticios para visualizar

# Respuesta para http://stats.stackexchange.com/questions/25109/visualizing-likert-responses-using-r-or-spss
# Cargar librerías
library(reshape2)
library(ggplot2)

# Funciones
CreateRowsColumns <- function(noofrows, noofcolumns) {
createcolumnnames <- paste("Q", 1:noofcolumns, sep ="")
df <- sapply(1:noofcolumns, function(i) assign(createcolumnnames[i], matrix(sample(1:5, noofrows, replace = TRUE))))
df <- sapply(1:noofcolumns, function(i) df[,i] <- as.factor(df[,i]))
colnames(df) <- createcolumnnames
return(df)}

# Generar marco de datos ficticio
LikertResponse <- CreateRowsColumns(82, 65)
LikertResponse[LikertResponse == 1] <- "Totalmente de acuerdo"
LikertResponse[LikertResponse == 2] <- "De acuerdo"
LikertResponse[LikertResponse == 3] <- "Neutral"
LikertResponse[LikertResponse == 4] <- "En desacuerdo"
LikertResponse[LikertResponse == 5] <- "Totalmente en desacuerdo"

Código para el mapa de calor

# Preparar datos
LikertResponseSummary <- do.call(rbind, lapply(data.frame(LikertResponse), table))
LikertResponseSummaryPercent <- prop.table(LikertResponseSummary,1)

# Derretir datos
LikertResponseSummary <- melt(LikertResponseSummary)
LikertResponseSummaryPercent <- melt(LikertResponseSummaryPercent)

# Combinar recuentos con proporciones
LikertResponsePlotData <- merge(LikertResponseSummary, LikertResponseSummaryPercent, by = c("Var1","Var2"))

# ¡Graficar mapa de calor!
# Usa "geom_tile(aes(fill = value.y*100), colour = "white")" para controlar cómo quieres que los colores del mapa de calor se muestren.
ggplot(LikertResponsePlotData, aes(x = Var2, y = Var1)) +
    geom_tile(aes(fill = value.y*100), colour = "white") +
    scale_fill_gradient(low = "white", high = "steelblue", name = "% de Encuestados") +
    scale_x_discrete(name = 'Respuesta') +
    scale_y_discrete(name = 'Preguntas') +
    geom_text(aes(label = paste(format(round(value.y*100), width = 3), '% (', format(round(value.x), width = 3), ')')), size = 3) 

Este es básicamente una plantilla para visualizar elementos Likert en un mapa de calor de la página web de Jason Bryon.

1 votos

github.com/jbryer/irutils/blob/master/R/likert.R es la fuente para los gráficos de barras apiladas que deseas.

0 votos

Para aclararlo, no quiero comparar entre grupos. Simplemente presentar las respuestas de ambos grupos de una manera sofisticada. Esta es una excelente respuesta. Realmente lo aprecio. Gracias.

3voto

Dominic D Puntos 936

El código de RJ produce un gráfico como este, que en realidad es una tabla con celdas sombreadas. Es un poco ocupado y un poco complicado de descifrar. Una tabla simple sin sombreado podría ser más efectiva (y también puedes ordenar los datos de una manera más significativa).

introducir descripción de la imagen aquí

Por supuesto, depende del mensaje principal que estás tratando de comunicar, pero creo que esto es más simple y un poco más fácil de entender. También tiene las preguntas y respuestas en un orden (¡en su mayoría!) lógico.

    library(stringr)
    LikertResponseSummary$Var1num <- 
      as.numeric(str_extract(LikertResponseSummary$Var1, "[0-9]+"))
    LikertResponseSummary$Var2 <- 
      factor(LikertResponseSummary$Var2, 
      levels =  c("Strongly disagree", "Disagree", "Neutral", "Agree", "Strongly agree"))

ggplot(LikertResponseSummary, 
       aes(factor(Var1num), value, fill = factor(Var2))) + 
       geom_bar(position="fill") +
       scale_x_discrete(name = 'Pregunta', breaks=LikertResponseSummary$Var1num,
                        labels=LikertResponseSummary$Var1) +
       scale_y_continuous(name = 'Proporción') +
       scale_fill_discrete(name = 'Respuesta') +
       coord_flip()

introducir descripción de la imagen aquí

0 votos

Estoy de acuerdo en que el gráfico se ve ocupado. Sin embargo, sería útil si las preguntas estuvieran agrupadas de alguna manera, por ejemplo, P1 - 10 preguntan sobre una cierta dimensión y así sucesivamente. A simple vista, si las tendencias son obvias, los colores lo dirían.

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