RまたはSPSSを使用したリッカート応答の視覚化


19

2つのグループに82人の回答者(グループAの43人とグループBの39人)があり、それぞれ1〜5の65のリッカート質問の調査を完了しました(強く同意する-強く同意しない)。したがって、66列(質問ごとに1 +グループ割り当てを示す1)と82行(回答者ごとに1)のデータフレームがあります。

RまたはSPSSを使用することで、このデータを視覚化する優れた方法を誰もが知っています。

このようなものが必要です: ここに画像の説明を入力してください
Jason Bryerから)

しかし、コードの最初のセクションを機能させることはできません。あるいは、以前の相互検証された投稿からリッカートデータを視覚化する方法の非常に良い例を見つけました:リッカートアイテムレスポンスデータを視覚化するが、RまたはSPSSを使用してこれらの中心カウントグラフまたは積み上げ棒グラフを作成する方法に関するガイドも指示もありません。


1
こんにちはアダム、さらに明確にするために、グループ間の違いを示すために視覚化を使用したいですか?その場合、それは推奨される方法ではありません。
ミシェル

Jason Bryerのパッケージは私には役に立たなかったが、彼はそれを更新したと思う。また、列名を属性およびグループとして保存する追加機能を備えたプルリクエストを追加しました。これを使用して、45個の質問リッカートアンケートをグループに分割し、必要に応じて別の変数に分割することも簡単に視覚化できます。(私はknitrを使用して出力しているため、1つの巨大なプロットではなく、Webサイト上に多くのサブプロットが表示されます)。:私はここに詳細な過去記事でしreganmian.net/blog/2013/10/02/...
スティアンHåklev

ちなみに、これらの回答を将来読んでいる人にとっては、リッカートデータに関するirutilsの機能の一部がリッカートRパッケージに移動されているようです(こちらのCRANを参照)。
firefly2442

リンクbryer.org/2011/visualizing-likert-itemsは壊れているようです。修正または交換を歓迎します。
ニックコックス

1
特定のコードに重点を置いたこの種の質問は、2012年よりも2018年には歓迎されません。それにもかかわらず、これに興味がある人のための相互参照は、stats.stackexchange.com / questions / 56322 /です。 ...stats.stackexchange.com/questions/148554/...
ニック・コックス

回答:


30

このような多数のアイテムで積み上げバーチャートを本当に使用したい場合、2つの解決策があります。

を使用して irutils

数ヶ月前にこのパッケージに出会いました。

Githubのコミット0573195c07の時点では、コードはgrouping=引数では機能しません。金曜日のデバッグセッションに行きましょう。

Githubから圧縮バージョンをダウンロードすることから始めます。R/likert.Rファイルをハックする必要がlikertありplot.likertます。具体的には、関数です。まず、likertではcast()が使用されますが、reshapeパッケージはロードされません(ただしimport(reshape)NAMESPACEファイルには命令があります)。これは事前に自分でロードできます。次に、アイテムラベルをフェッチする命令が正しくありませんi。aは行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()、読みやすさの問題があるため、1ページに配置することはできません!)

ここに画像の説明を入力してください

代替ソリューション

リッカートスケールを分岐積み上げ棒グラフとしてプロットできる別のパッケージHHに注目したいと思います。以下に示すように、上記のコードを再利用できます。

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="")

これにより、2つの個別のパネルが作成されますが、1ページに収まります。

ここに画像の説明を入力してください

2016-6-3を編集

  1. 現在、likertは個別のパッケージとして利用可能です。
  2. あなたは必要ありませんリシェイプライブラリをまたは両方を切り離しirutilsリシェイプを

最後のプロットは、人口ピラミッドを思い出させます。それらが実際にどのように機能するかを確認するために、実際のデータを取得する必要があります。私は彼らが目を引くとはいえかなりきれいだと認めます。
アンディW

@Andy確かにそうです。をご覧くださいHH::as.pyramidLikert
-chl

1
+ 1、library(HH)は間違いなく道です。しかし、何かが同意/などに反対の順序であなたの最後から二番目のプロットと共に去りぬ間違っている
ピーター・エリス

@PeterEllisはい、応答カテゴリの順序は間違っているようです。(データを集計する際にラベルの順序が失われた、とテーブル名が辞書順、以下に配置されている。)迅速なハックのために、私たちはただ置き換えることができますt(apply(resp, 2, table))t(apply(resp, 2, table))[,levels(resp[,1])]。そしてあなたにも+1!
chl

7

SPSSであなたが言及した投稿(リッカートアイテムレスポンスデータの視覚化)でチャートの多くを再作成することに関するブログ投稿を書き始めました。

ミシェルが指摘するように、あなたがグループを持っているという事実は、以前の質問と比較して新しいひねりです。また、積み上げ棒グラフを使用してグループを考慮することができますが、IMOはchlの元の投稿のドットプロットの例により簡単に組み込むことができます。ポストの最後にこれを生成するためにSPSSコードを含めましたが、本質的には、適切な形式でデータを再構成して上記のプロットを生成する方法を知る必要があります(コードで提供される注釈は、うまくいくように願っています)。ここでは、2つのグループからのポイントを区別するためにいくつかの冗長エンコード(色と形状)を使用し、ポイントが半透明になるようにして、オーバーラップするタイミングを確認できるようにします(別のオプションは、オーバーラップするポイントをかわすことです)。

図1:グループ別のドットプロット

積み上げ棒グラフよりも優れているのはなぜですか?積み上げ棒グラフは、棒の長さで情報をエンコードします。同じ軸カテゴリ内またはパネル間でバーの長さを比較しようとすると、バーが共通のスケールを持つことができなくなります。例として、図2の画像を提供しました。2つのバーは、開始位置が異なるプロットに配置されています。

図2:共通スケールのないバー

これを下の図3のプロットと比較してください。この図では、2つのバー(同じ長さ)が同じ開始点からプロットされています。私は意図的にタスクを難しくしましたが、どれが長いかを知ることができるはずです。

図3:一般的なスケールのバー

積み上げ棒グラフは、基本的に図2に表示されていることを実行しています。ドットプロットは、図3に表示されているものに似ていると考えることができます。

探索的データ分析用に特定のグラフを生成しないとは言いませんが、非常に多くのカテゴリを使用する場合は、積み上げ棒グラフを避けることをお勧めします。ドットプロットも万能薬ではありませんが、ドットプロットとパネルを比較する方が、積み上げ棒グラフよりもはるかに簡単だと思います。ここでもブログ投稿で表について提供しているいくつかのアドバイスを考慮し、グラフを意味のあるカテゴリに並べたり分離したりして、縦に並べて見たいアイテムがグラフ内でより近くなるようにしてください。一部のプロット方法は多くの質問にうまく対応できますが(カテゴリヒートマップは例です)、並べ替えを行わないと、意味のあるパターンを特定するのは困難です(明らかな外れ値以外)。

SPSSの使用に関する注意。SPSSは、以前のグラフにリンクされたもののいずれかを生成できますが、データの整形方法を頻繁に知る必要があります(ggplotについても同じことが言えますが、人々は基本的に再形成を行うためのパッケージを開発してきました)。SPSSのGPL言語がどのように機能するかを理解するには、実際にggplot2に関するHadley Wickhamの本を読むことをお勧めします。使用中R!シリーズ。SPSSのGPLがどのように機能するかを理解するために必要な文法を示しており、SPSSに付属のGPLプログラミングマニュアルよりもはるかに読みやすくなっています。SPSSで特定のチャートを生成することについて質問がある場合は、1つのチャートについて1つの質問をするのが最善です(ここで十分に話をしました!)他のチャートの一部を複製したブログ投稿。ヒートマップまたは変動プロットの概念の証明については、私の別のブログ投稿、SPSSのCorrgramsの例をご覧ください

図1の生成に使用されたSPSSコード

****************************************.
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) 

これは基本的に、Jason BryonのWebサイトのヒートマップ上で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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.