Візуалізація відповідей Лікерта за допомогою R або SPSS


19

У мене є 82 респонденти у 2 групах (43 у групі A та 39 у групі B), які завершили опитування з 65 питань Likert, кожне - від 1 до 5 (сильно згодні - категорично не згодні). Тому у мене є кадр даних з 66 стовпцями (1 для кожного питання + 1 із зазначенням розподілу групи) та 82 рядками (1 для кожного респондента).

Використовуючи R або SPSS, хтось знає хороший спосіб візуалізації цих даних.

Мені потрібно щось подібне: введіть тут опис зображення
(від Джейсон Брайер )

Але я не можу заставити початковий розділ коду працювати. Крім того, я знайшов справді хороші приклади того, як візуалізувати дані Likert з попереднього перехресного підтвердження: Візуалізація даних відповіді пункту Likert, але немає посібників чи інструкцій, як створити ці централізовані графіки підрахунку чи складені діаграми за допомогою R або SPSS.


1
Привіт Адам, для уточнення, чи хотіли ви використати візуалізації, щоб показати відмінності між групами? Якщо так, то це не рекомендується метод.
Мішель

Пакет Джейсона Брайера не працював для мене, але я думаю, що він оновив його, і він працює прекрасно зараз. Я також додав запит на додаток із додатковою функцією для зберігання назв стовпців як атрибутів, так і груп. Використовуючи це, я легко зможу візуалізувати опитувальник Likert за 45 питань, розділений на групи, навіть розділити на іншу змінну, якщо я захочу. (Я виводжу за допомогою в'язального пристрою, так що він закінчується тим же лотом підділів на веб-сайті, а не одним гігантським сюжетом). Я зробив детальну реєстрацію тут: reganmian.net/blog/2013/10/02/…
Стіян Хеклев

Тільки FYI, для тих, хто читає ці відповіді в майбутньому, схоже, деякі функції та функціональність irutils щодо даних про лікерт перенесені в пакет Likert R ( див. CRAN тут ).
firefly2442

Здається, посилання bryer.org/2011/visualizing-likert-items порушено. Виправлення або заміна буде бажаним.
Нік Кокс

1
Цей питання - з його сильним фокусом на конкретному коді - менш вітається у 2018 році, ніж це було у 2012 році. Незалежно від цього, деякі перехресні посилання для всіх, кого це цікавить, є stats.stackexchange.com/questions/56322/ … Та stats.stackexchange.com/questions/148554/…
Нік Кокс

Відповіді:


30

Якщо ви дійсно хочете використовувати складені барчарти з такою великою кількістю предметів, ось два можливих рішення.

Використання irutils

Я натрапив на цей пакет кілька місяців тому.

За станом на комісію 0573195c07 на Github , код не працюватиме з grouping=аргументом. Перейдемо до налагоджувальної сесії п’ятниці

Почніть із завантаження поштової версії з Github. Вам потрібно буде зламати R/likert.Rфайл, зокрема likertі plot.likertфункції. По- перше, в likert, cast()використовується , але reshapeпакет ніколи не буде завантажений (хоча є більш import(reshape)інструкції в NAMESPACEфайлі). Ви можете заздалегідь завантажити це самостійно. По- друге, є неправильна інструкція для отримання елементів етикетки, де iбовтається навколо лінії 175. Це повинен бути закріплений , а також, наприклад , шляхом заміни всіх входжень likert$items[,i]з likert$items[,1]. Тоді ви можете встановити пакет так, як ви звикли робити на своїй машині. На моєму Mac я це зробив

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

Потім за допомогою R спробуйте наступне:

library(irutils)
library(reshape)

# Simulate some data (82 respondents x 66 items)
resp <- data.frame(replicate(66, sample(1:5, 82, replace=TRUE)))
resp <- data.frame(lapply(resp, factor, ordered=TRUE, 
                          levels=1:5, 
                          labels=c("Strongly disagree","Disagree",
                                   "Neutral","Agree","Strongly Agree")))
grp <- gl(2, 82/2, labels=LETTERS[1:2]) # say equal group size for simplicity

# Summarize responses by group
resp.likert <- likert(resp, grouping=grp)

Це має просто працювати, але візуальне відображення буде жахливим через велику кількість елементів. plot(likert(resp))Однак це працює без групування (наприклад, ).

введіть тут опис зображення

Таким чином, я б запропонував зменшити ваш набір даних до менших підмножин елементів. Наприклад, використовуючи 12 предметів,

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

У мене виходить «читабельний» складений діаграми. Ви, ймовірно, можете їх потім обробити. (Це ggplot2об’єкти, але ви не зможете впорядкувати їх на одній сторінці gridExtra::grid.arrange()через проблему з читабельністю!)

введіть тут опис зображення

Альтернативне рішення

Я хотів би звернути вашу увагу на інший пакет, HH , який дозволяє побудувати ваги Likert як розбіжні складені барчарти. Ми можемо використати вищевказаний код, як показано нижче:

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

але це трохи ускладнить справи, тому що нам потрібно перетворити частоти в підрахунки, підмножити likertоб'єкт, вироблений irutils, від'єднати пакет тощо. Отже, почнемо ще раз із нової статистики:

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

введіть тут опис зображення

Щоб використовувати змінну групування, вам потрібно буде працювати з arrayчисловими значеннями.

# compute responses frequencies separately by 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="")

Це дозволить отримати дві окремі панелі, але вона поміститься на одній сторінці.

введіть тут опис зображення

Редагувати 2016-6-3

  1. На сьогоднішній день likert доступний як окремий пакет.
  2. Вам не потрібна бібліотека переформатування або від'єднання обох ірутилів та переформатування

Останній сюжет нагадує мені піраміди населення. Ми повинні отримати реальні дані, щоб побачити, як вони працюють «в дикій природі», з деякими даними, які не так впорядковані. Я визнаю, що вони привабливі для очей і досить.
Енді Ш

@Andy Це справді так. Див HH::as.pyramidLikert.
chl

1
+1, бібліотека (HH) - це безумовно шлях. Але щось пішло не так з вашим другим останнім сюжетом в порядку упорядкування / незгоди тощо.
Пітер Елліс

@PeterEllis Yup, схоже, категорії відповідей дійсно в неправильному порядку. (Порядок міток був втрачений під час табулювання даних, а назви таблиць розташовані відповідно до лексикографічного порядку.) Для швидкого злому ми можемо просто замінити t(apply(resp, 2, table))на t(apply(resp, 2, table))[,levels(resp[,1])]. І +1 вам теж!
chl

7

Я почав писати публікацію в блозі про відтворення багатьох діаграм у публікації, яку ви згадуєте ( Візуалізація даних відгуку на предмет Likert ) в SPSS, тому я припускаю, що це буде хорошою мотивацією для її завершення.

Як зазначає Мішель, той факт, що у вас є групи, є новим поворотом порівняно з попередніми питаннями. І хоча групи можуть бути враховані за допомогою складених стовпчастих графіків, IMO вони набагато легше включаються в приклад крапкового сюжету в початковому дописі chl. Я включив код SPSS, щоб генерувати це в кінці публікації, по суті це тягне за собою знати, як переробити ваші дані у відповідний формат, щоб генерувати вказаний сюжет (анотація, що міститься в коді, сподіваємось очистити частину цього). Тут я використав надмірне кодування (колір і форму), щоб відрізнити точки, що виходять з двох груп, і зробив точки напівпрозорими, щоб ви могли сказати, коли вони перекриваються (інший варіант - ухилити точки, коли вони перекриваються).

Малюнок 1: Діаграми точок за групами

Чому це краще, ніж штабельні діаграми? Складені діаграми смуг кодують інформацію у довжину брусків. Коли ви намагаєтеся порівняти між довжинами брусків або в межах однієї категорії осей, або між панелями, укладання забороняє барам мати спільну шкалу. Для прикладу я подав зображення на малюнку 2, на якому два бруски розміщені на ділянці, в якому їх початкове розташування відрізняється, який брусок - ширший (вздовж горизонтальної осі)?

Малюнок 2: Штрихи без загальної шкали

Порівняйте це з графіком на малюнку 3 нижче, на якому два бруски (однакової довжини) побудовані з тієї ж початкової точки. Я навмисно ускладнював завдання, але ви повинні мати можливість сказати, яке з них довше.

Малюнок 3: Штрихи із загальною шкалою

Складені діаграми по суті роблять те, що відображено на малюнку 2. Діаграми крапок можна вважати більш схожими на те, що відображено на малюнку 3, просто замініть смугу крапкою в кінці смуги.

Я не збираюсь говорити, що не створювати конкретної діаграми для дослідницького аналізу даних, але я б запропонував уникати складених смужкових діаграм при використанні такої кількості категорій. Діаграми точок також не є панацеєю, але я вважаю, що порівняння між панелями з точковими графіками набагато простіше, ніж зі складеними діаграмами. Розгляньте кілька порад, які я надаю у своєму блозі також для таблиць, спробуйте замовити та / або розділити діаграми на значущі категорії, і переконайтесь, що елементи, які ви хочете подивитися в тандемі, ближче один до одного на графіках. Хоча деякі з методів побудови графіку можуть бути масштабними для багатьох питань (категоричні теплові карти - приклад), без сортування все одно буде важко визначити будь-які сенсульні структури (крім очевидних переживань).

Примітка про використання SPSS. SPSS може генерувати будь-який з попередніх, пов’язаних з діаграмами, хоча це часто тягне за собою знати, як формувати ваші дані (те саме стосується ggplot, але люди розробляють пакети, щоб по суті зробити їх перестановку). Щоб зрозуміти, як краще працює мова GPL SPSS, я б фактично запропонував прочитати книгу Хедлі Вікхема на сайті ggplot2у користуванні R! серія. Він викладає граматику, необхідну для розуміння того, як працює GPL SPSS, і це набагато простіше, ніж посібник з програмування GPL, який поставляється із SPSS! Якщо у вас є якісь питання щодо створення конкретних діаграм у SPSS, найкраще було б задати одне запитання для однієї діаграми (я тут досить говорив, як є!) Я оновлю цю відповідь посиланням, хоча якщо я коли-небудь обійдуся, щоб зробити свій публікація в блозі, що повторює деякі інші діаграми. Для підтвердження концепції теплових карт або графіків флуктуації ви можете побачити ще один мій пост у блозі, Деякі приклади Corrgrams у SPSS .

Код SPSS, який використовується для створення малюнка 1

****************************************.
input program. */making fake data similar to yours.
loop #i = 1 to 82.
compute case_num = #i.
end case.
end loop.
end file.
end input program.
execute.
dataset name likert.

*making number in groups.
compute group = 1.
if case_num > 43 group = 2.
value labels group
1 'A'
2 'B'.

*this makes 5 variables with categories between 0 and 5 (similar to Likert data with 5 categories plus missing data).
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 'missing'
1 'very disagree'
2 'disagree'
3 'neutral'
4 'agree'
5 'very agree'.
formats case_num group V1 to V5 (F1.0).
*****************************************.

*Because I want to panel by variable, I am going to reshape my data so all of the "V" variables are in one column (stacking them in long format).
varstocases
/make V from V1 to V5
/index orig (V).

*I am going to plot the points, so I aggregate that information (you could aggregate total counts as well if you wanted to plot percentages.
DATASET DECLARE agg_lik.
AGGREGATE
  /OUTFILE='agg_lik'
  /BREAK=orig V group
  /count_lik=N.
dataset activate agg_lik.


*now the fun part, generating the chart.
*The X axis, dim(1) is the count of likert responses within each category for each original question.
*The Y axis, dim(2) is the likert responses, and the third axis is used to panel the observations by the original questions, dim(4) here beacause I want to panel
by rows instead of columns.
DATASET ACTIVATE agg_lik.
* Chart Builder.
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("Figure 1: Dot Plots by Group"))
  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.
*The "SCALE: cat" statements map different shapes which I use to assign to the two groups in the plot, and I plot the interior of the points as partially transparent.
*With some post hoc editing you should be able to make the chart look like what I have in the stats post.
****************************************.

Сильний плюс від мене ввічливо, але проникливо обговорюючи недоліки складених штрихових діаграм, які в принципі легко зрозуміти, але часто набагато менш легко розшифрувати на практиці.
Нік Кокс

5

Ну добре, я придумав код, перш ніж ви уточнили. Потрібно було зачекати, але подумав, що я мушу розмістити його, щоб кожен, хто прийшов сюди, міг повторно використовувати цей код.

Дані-манекени для візуалізації

# Response for http://stats.stackexchange.com/questions/25109/visualizing-likert-responses-using-r-or-spss
# Load libraries
library(reshape2)
library(ggplot2)

# Functions
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)}

# Generate dummy dataframe
LikertResponse <- CreateRowsColumns(82, 65)
LikertResponse[LikertResponse == 1] <- "Strongly agree"
LikertResponse[LikertResponse == 2] <- "Agree"
LikertResponse[LikertResponse == 3] <- "Neutral"
LikertResponse[LikertResponse == 4] <- "Disagree"
LikertResponse[LikertResponse == 5] <- "Strongly disagree"

Код для теплової карти

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

# Melt data
LikertResponseSummary <- melt(LikertResponseSummary)
LikertResponseSummaryPercent <- melt(LikertResponseSummaryPercent)

# Merge counts with proportions
LikertResponsePlotData <- merge(LikertResponseSummary, LikertResponseSummaryPercent, by = c("Var1","Var2"))

# Plot heatmap!
# Use the "geom_tile(aes(fill = value.y*100), colour = "white")" to control how you want the heatmap colours to map to.
ggplot(LikertResponsePlotData, aes(x = Var2, y = Var1)) +
    geom_tile(aes(fill = value.y*100), colour = "white") +
    scale_fill_gradient(low = "white", high = "steelblue", name = "% of Respondents") +
    scale_x_discrete(name = 'Response') +
    scale_y_discrete(name = 'Questions') +
    geom_text(aes(label = paste(format(round(value.y*100), width = 3), '% (', format(round(value.x), width = 3), ')')), size = 3) 

Це в основному шаблон для візуалізації предметів Likert на тепловій карті від веб-сайту Джейсона Брайона.


1
github.com/jbryer/irutils/blob/master/R/likert.R є джерелом для складених бар-діаграм.
RJ-

Для уточнення я не хочу порівнювати групи. Просто представити відповіді обом групам витончено. Це чудова відповідь. Дуже ціную це. Спасибі.
Адам

3

@ RJ-код створює такий графік, який справді є таблицею з затіненими клітинками. Його досить зайнято і трохи складно розшифрувати. Проста таблиця без затінення може бути більш ефективною (і ви також можете розмістити дані в більш змістовному порядку).

введіть тут опис зображення

Звичайно, це залежить від того, яке основне повідомлення ви намагаєтеся повідомити, але я думаю, що це простіше і трохи простіше зрозуміти. Він також має запитання та відповіді в (переважно!) Логічному порядку.

    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 = 'Question', breaks=LikertResponseSummary$Var1num,
                        labels=LikertResponseSummary$Var1) +
       scale_y_continuous(name = 'Proportion') +
       scale_fill_discrete(name = 'Response') +
       coord_flip()

введіть тут опис зображення


Домовились, що діаграма виглядає зайнятою. Однак було б корисно, якщо питання згруповані в якомусь порядку, наприклад, Q1 - 10 запитує про певний вимір тощо. З першого погляду, якщо тенденції очевидні, кольори підкажуть.
RJ-
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.