Grafik untuk hubungan antara dua variabel ordinal

46

Apa grafik yang sesuai untuk menggambarkan hubungan antara dua variabel ordinal?

Beberapa opsi yang dapat saya pikirkan:

  1. Scatter plot dengan menambahkan jitter acak untuk menghentikan titik persembunyian satu sama lain. Rupanya grafik standar - Minitab menyebutnya sebagai "plot nilai individu". Menurut pendapat saya itu mungkin menyesatkan karena secara visual mendorong semacam interpolasi linier antara tingkat ordinal, seolah-olah data berasal dari skala interval.
  2. Plot sebar diadaptasi sehingga ukuran (area) titik mewakili frekuensi kombinasi level tersebut, daripada menggambar satu titik untuk setiap unit sampling. Saya kadang-kadang melihat plot seperti itu dalam praktik. Mereka mungkin sulit dibaca, tetapi poin-poinnya terletak pada kisi-kisi yang ditempatkan secara teratur, yang agak mengatasi kritik dari plot scatter yang gugup sehingga secara visual "menskala" data.
  3. Khususnya jika salah satu variabel diperlakukan sebagai dependen, plot kotak dikelompokkan berdasarkan level variabel independen. Kemungkinan terlihat mengerikan jika jumlah level variabel dependen tidak cukup tinggi (sangat "datar" dengan kumis yang hilang atau kuartil yang runtuh lebih buruk yang membuat identifikasi visual median menjadi tidak mungkin), tetapi setidaknya menarik perhatian median dan kuartil yang statistik deskriptif yang relevan untuk variabel ordinal.
  4. Tabel nilai atau kotak kosong sel dengan peta panas untuk menunjukkan frekuensi. Berbeda secara visual tetapi secara konsep mirip dengan sebaran plot dengan area titik menunjukkan frekuensi.

Apakah ada ide lain, atau pemikiran tentang plot mana yang lebih disukai? Apakah ada bidang penelitian di mana plot ordinal-vs-ordinal tertentu dianggap sebagai standar? (Sepertinya saya ingat frekuensi peta panas tersebar luas dalam genomik tetapi menduga itu lebih sering untuk nominal-vs-nominal.) Saran untuk referensi standar yang baik juga akan sangat disambut, saya menebak sesuatu dari Agresti.

Jika ada yang ingin mengilustrasikannya dengan plot, kode R untuk data sampel palsu berikut.

"Seberapa pentingkah olahraga untukmu?" 1 = sama sekali tidak penting, 2 = agak tidak penting, 3 = tidak penting atau tidak penting, 4 = agak penting, 5 = sangat penting.

"Seberapa teratur Anda berlari 10 menit atau lebih lama?" 1 = tidak pernah, 2 = kurang dari sekali per dua minggu, 3 = sekali setiap satu atau dua minggu, 4 = dua atau tiga kali per minggu, 5 = empat atau lebih kali per minggu.

Jika itu wajar untuk memperlakukan "sering" sebagai variabel dependen dan "kepentingan" sebagai variabel independen, jika plot membedakan keduanya.

importance <- rep(1:5, times = c(30, 42, 75, 93, 60))
often <- c(rep(1:5, times = c(15, 07, 04, 03, 01)), #n=30, importance 1
           rep(1:5, times = c(10, 14, 12, 03, 03)), #n=42, importance 2
           rep(1:5, times = c(12, 23, 20, 13, 07)), #n=75, importance 3
           rep(1:5, times = c(16, 14, 20, 30, 13)), #n=93, importance 4
           rep(1:5, times = c(12, 06, 11, 17, 14))) #n=60, importance 5
running.df <- data.frame(importance, often)
cor.test(often, importance, method = "kendall") #positive concordance
plot(running.df) #currently useless

Pertanyaan terkait untuk variabel kontinu yang saya temukan bermanfaat, mungkin titik awal yang berguna: Apa alternatif untuk scatterplots saat mempelajari hubungan antara dua variabel numerik?

Silverfish
sumber
1
Bagaimana dengan spineplot?
Dimitriy V. Masterov
Pertanyaan terkait untuk menampilkan data ordinal univariat di beberapa kelompok mungkin juga relevan: Menampilkan Data Ordinal - Berarti, Median, dan Peringkat Rata-rata
Silverfish

Jawaban:

15

Spineplot (plot mosaik) berfungsi dengan baik untuk data contoh di sini, tetapi bisa sulit dibaca atau ditafsirkan jika beberapa kombinasi kategori jarang atau tidak ada. Tentu saja wajar, dan diharapkan, bahwa frekuensi rendah diwakili oleh ubin kecil, dan nol dengan tidak ada ubin sama sekali, tetapi kesulitan psikologis tetap ada. Wajar jika orang yang suka spineplots memilih contoh yang cocok untuk kertas atau presentasi mereka, tetapi saya sering membuat contoh yang terlalu berantakan untuk digunakan di depan umum. Sebaliknya, spineplot menggunakan ruang yang tersedia dengan baik.

Beberapa implementasi mengandaikan grafik interaktif, sehingga pengguna dapat menginterogasi setiap ubin untuk mempelajari lebih lanjut tentang itu.

Alternatif yang juga dapat bekerja dengan baik adalah diagram batang dua arah (banyak nama lain ada).

Lihat misalnya tabplotdalam http://www.surveydesign.com.au/tipsusergraphs.html

Untuk data ini, satu kemungkinan plot (diproduksi menggunakan tabplotdi Stata, tetapi harus mudah dalam perangkat lunak yang layak) adalah

masukkan deskripsi gambar di sini

Format ini berarti mudah untuk menghubungkan bilah individual dengan pengidentifikasi baris dan kolom dan bahwa Anda dapat membuat catatan dengan frekuensi, proporsi, atau persen (jangan lakukan itu jika menurut Anda hasilnya terlalu sibuk, tentu saja).

Beberapa kemungkinan:

  1. Jika satu variabel dapat dianggap sebagai respons terhadap yang lain sebagai prediktor, maka ada baiknya Anda merencanakannya pada sumbu vertikal seperti biasa. Di sini saya berpikir tentang "kepentingan" sebagai mengukur suatu sikap, pertanyaannya kemudian adalah apakah hal itu memengaruhi perilaku ("sering"). Masalah kausal seringkali lebih rumit bahkan untuk data imajiner ini, tetapi intinya tetap ada.

  2. Saran # 1 adalah selalu palsu jika kebalikannya bekerja lebih baik, artinya, lebih mudah untuk dipikirkan dan ditafsirkan.

  3. Persen atau probabilitas gangguan sering kali masuk akal. Sebidang frekuensi mentah juga dapat bermanfaat. (Secara alami, plot ini tidak memiliki keutamaan plot mosaik untuk menunjukkan kedua jenis informasi sekaligus.)

  4. Anda tentu saja dapat mencoba (jauh lebih umum) alternatif bagan batang yang dikelompokkan atau bagan batang bertumpuk (atau bagan titik yang masih sangat jarang dikelompokkan dalam arti WS Cleveland). Dalam hal ini, saya tidak berpikir mereka bekerja dengan baik, tetapi kadang-kadang mereka bekerja lebih baik.

  5. Beberapa mungkin ingin mewarnai berbagai kategori respons secara berbeda. Saya tidak keberatan, dan jika Anda ingin, Anda tidak akan menganggap keberatan dengan serius.

Strategi hibridisasi grafik dan tabel dapat bermanfaat secara lebih umum, atau memang tidak seperti yang Anda inginkan sama sekali. Argumen yang sering diulang adalah bahwa pemisahan Gambar dan Tabel hanyalah efek samping dari penemuan pencetakan dan pembagian kerja yang dihasilkannya; sekali lagi tidak perlu, sama seperti manuskrip para penulis meletakkan ilustrasi persis bagaimana dan di mana mereka suka.

Nick Cox
sumber
Terima kasih telah menambahkan grafik. Hal ini menimbulkan masalah bagaimana grafik dan data tekstual bergabung - Saya tahu beberapa orang tidak suka meletakkan angka di atas bilah (karena itu membuat bilah tampak lebih tinggi daripada yang sebenarnya; saya tidak memiliki kutipan untuk diberikan untuk ini tapi saya pikir itu pendapat yang terkenal).
Silverfish
Di sisi lain, memperbaiki posisi angka tampaknya menciptakan salah satu dari dua masalah: salah satu angka dapat berakhir ditumpuk di bar, yang mengaburkan mereka, atau memperbaiki angka di atas bar dapat "memutuskan" mereka dari bar yang lebih rendah khususnya. Apakah ada diskusi yang baik tentang masalah ini di suatu tempat?
Silverfish
Saya rasa Anda tidak perlu referensi; itu adalah sikap umum. Saya melihat varian lain: (1) saran tampilan khusus bahwa tampilan terlalu sibuk, tidak rapi, dll. (2) banding ke anggapan bahwa teks numerik berlebihan karena informasi yang sama tersirat (atau menurut beberapa eksplisit) ) dalam grafik dengan cara apa pun (3) sikap "anak laki-laki mengenakan warna biru dan anak perempuan memakai warna merah muda" yang Angka adalah angka dan Tabel adalah tabel, dan tidak akan bertemu lagi dengan yang kedua. (3) menganggap saya sebagai prasangka murni; (2) pada prinsipnya benar, tetapi bagaimanapun angka dapat membantu; (1) harus dipikirkan melalui contoh dengan contoh.
Nick Cox
Saya tidak tahu diskusi tentang trade-off tertentu. Meninggalkan batang tanpa warna agar angka-angka dapat dimasukkan di dalamnya seringkali merupakan ide yang bagus. Kadang-kadang jeruji bisa terlalu kecil untuk dilakukan.
Nick Cox
30

Berikut adalah upaya cepat pada peta panas , saya telah menggunakan batas sel hitam untuk memecah sel, tetapi mungkin ubin harus dipisahkan lebih seperti dalam jawaban Glen_b.

Peta panas

library(ggplot2)
runningcounts.df <- as.data.frame(table(importance, often))
ggplot(runningcounts.df, aes(importance, often)) +
   geom_tile(aes(fill = Freq), colour = "black") +
   scale_fill_gradient(low = "white", high = "steelblue")

Berikut ini adalah plot fluktuasi berdasarkan komentar sebelumnya oleh Andy W. Saat ia menggambarkan mereka "mereka pada dasarnya hanya bin scatterplot untuk data kategorikal, dan ukuran suatu titik dipetakan ke jumlah pengamatan yang termasuk dalam bin itu." Untuk referensi, lihat

Wickham, Hadley dan Heike Hofmann. 2011. Plot produk . Transaksi IEEE pada Visualisasi dan Grafik Komputer (Proc. Infovis `11) . Pra-cetak PDF

plot fluktuasi

theme_nogrid <- function (base_size = 12, base_family = "") {
  theme_bw(base_size = base_size, base_family = base_family) %+replace% 
    theme(panel.grid = element_blank())   
}

ggplot(runningcounts.df, aes(importance, often)) +
  geom_point(aes(size = Freq, color = Freq, stat = "identity", position = "identity"), shape = 15) +
  scale_size_continuous(range = c(3,15)) + 
  scale_color_gradient(low = "white", high = "black") +
  theme_nogrid()
Silverfish
sumber
1
" mungkin ubin harus dipisahkan lebih seperti dalam jawaban Glen_b " - Saya tidak yakin itu perlu dalam kasus ini, ada jauh lebih sedikit godaan untuk melihat kategori sebagai berkelanjutan di sini.
Glen_b
18

Berikut adalah contoh tampilan spineplot data. Aku melakukan ini di Stata cukup cepat, tapi ada implementasi R . Saya pikir dalam R seharusnya:

spineplot(factor(often)~factor(importance))

Spineplot sebenarnya tampaknya menjadi default jika Anda memberikan variabel kategori R:

plot(factor(often)~factor(importance))

Rincian pecahan kategori sering ditampilkan untuk setiap kategori kepentingan. Bar bertumpuk digambar dengan dimensi vertikal yang menunjukkan fraksi yang sering diberi kategori kepentingan. Dimensi horizontal menunjukkan fraksi di setiap kategori kepentingan. Dengan demikian bidang ubin yang dibentuk mewakili frekuensi, atau lebih umum totalnya, untuk setiap kombinasi-silang kepentingan dan sering.

masukkan deskripsi gambar di sini

Dimitriy V. Masterov
sumber
1
Saya mengubahnya sekitar.
Dimitriy V. Masterov
1
Mengutip Nick Cox (penulis spineplot Stata): Pembatasan terhadap dua variabel lebih jelas daripada nyata. Variabel komposit dapat dibuat dengan kombinasi silang dari dua atau lebih variabel kategori .... Variabel respon biasanya lebih baik ditunjukkan pada sumbu y. Jika satu variabel adalah biner, seringkali lebih baik untuk memplotnya pada sumbu y. Tentu saja, ada beberapa ketegangan di antara saran-saran ini.
Dimitriy V. Masterov
3
Saya setuju dengan yang di atas. Tetapi skema standar colata [u] r cukup buruk untuk variabel ordinal. Beberapa alternatif yang baik adalah berbagai pilihan merah dan / atau biru, atau hanya gr {a | e}.
Nick Cox
3
@ Dimitriy Saya merasa sangat aneh menggunakan campuran warna yang berubah-ubah dalam situasi yang sama! Saya tidak menyiratkan atau menyimpulkan sesuatu dengan atau dari warna yang tepat, namun terkuantifikasi. Tapi intinya hanya bahwa skala gradasi cocok dengan urutan gradasi warna. Ada beberapa kesewenang-wenangan dalam pewarnaan peta panas juga, dan memang dalam banyak jenis kartografi tematik.
Nick Cox
2
Saya tidak melihat masalah dengan skema warna bertingkat asalkan warnanya berbeda. Mengapa ada orang yang tergoda untuk melakukan interpolasi? Saya tidak bisa melihat logika warna yang berubah-ubah. Urutan pelangi masuk akal dalam fisika, tetapi tidak dalam hal bagaimana orang memandang warna (misalnya kuning dan merah terlalu berbeda). Saya memiliki bukti dalam hal berbicara banyak siswa melalui pilihan, dan saya akan mengatakan 80% dengan tulus mengatakan "Itu jauh lebih baik" ketika mereka melihat urutan bergradasi halus atas pelangi atau salad buah. Biru melalui pucat, biru, pucat, merah, hingga merah bekerja dengan baik. Pastikan Anda mencobanya pada wanita dan juga pria.
Nick Cox
13

Cara saya melakukan ini sedikit fudge, tetapi bisa diperbaiki dengan cukup mudah.

Ini adalah versi modifikasi dari pendekatan jittering.

Melepaskan sumbu mengurangi godaan untuk menafsirkan skala sebagai kontinu; menggambar kotak di sekitar kombinasi yang dikunci menekankan ada sesuatu seperti "skala istirahat" - bahwa intervalnya tidak harus sama

Idealnya, label 1..5 harus diganti dengan nama kategori, tetapi saya akan membiarkannya untuk imajinasi sekarang; Saya pikir itu menyampaikan rasa itu.

 plot(jitter(often)~jitter(importance),data=running.df,bty="n",
    ylim=c(0.5,5.5),xlim=c(0.5,5.5),cex=0.5,pty="s",xaxt="n",yaxt="n") 
 axis(1,tick=TRUE,col=0)
 axis(2,tick=TRUE,col=0)
 rect(rep(seq(0.75,4.75,1),5),rep(seq(0.75,4.75,1),each=5),
       rep(seq(1.25,5.25,1),5),rep(seq(1.25,5.25,1),each=5),
       border=8)

jittered plot ordinal-ordinal


Kemungkinan perbaikan:

i) membuat jeda lebih kecil (saya lebih suka jeda lebih besar dari ini, secara pribadi), dan

ii) mencoba menggunakan urutan quasirandom untuk mengurangi timbulnya pola yang jelas di dalam kotak. Meskipun usaha saya agak membantu, Anda dapat melihat bahwa di dalam sel dengan jumlah poin yang lebih sedikit masih ada beberapa yang memiliki tampilan yang kurang lebih berkorelasi (misalnya kotak di baris atas, kolom ke-2). Untuk menghindari itu, urutan kuasi-acak mungkin harus diinisialisasi untuk setiap sub-kotak. (Alternatif mungkin adalah pengambilan sampel Latin Hypercube.) Setelah itu disortir, ini bisa dimasukkan ke dalam fungsi yang bekerja persis seperti jitter.

quasi-random jitter dan kotak yang lebih besar

library("fOptions")

 hjit <- runif.halton(dim(running.df)[1],2) 
 xjit <- (hjit[,1]-.5)*0.8
 yjit <- (hjit[,2]-.5)*0.8  

 plot(I(often+yjit)~I(importance+xjit),data=running.df,bty="n",
    ylim=c(0.5,5.5),xlim=c(0.5,5.5),cex=0.5,pty="s",xaxt="n",yaxt="n") 
 axis(1,tick=TRUE,col=0)
 axis(2,tick=TRUE,col=0)
 rect(rep(seq(0.55,4.55,1),5),rep(seq(0.55,4.55,1),each=5),
       rep(seq(1.45,5.45,1),5),rep(seq(1.45,5.45,1),each=5),
       border=8)
Glen_b
sumber
1
Saya suka ini, bagi saya pemisahan sangat menekankan sifat ordinal dari data! Sayangnya mata manusia tertarik secara alami ke pola-pola yang terlihat dalam jittering misalnya "tren ke atas" di panel (4,5) dan (5,3). Di sisi positifnya "menghitung poin" terasa lebih alami bagi saya daripada menilai frekuensi berdasarkan ukuran titik. Apakah ada varian di mana titik ditempatkan secara merata, atau digumpal dalam pola reguler di pusat, untuk menghindari "tren jitter" yang mengganggu?
Silverfish
1
@Silverfish, konsep serupa dalam geografi adalah peta titik-kepadatan. Para ahli geografi telah menemukan beberapa bukti bahwa pola-pola reguler atau pola-pola yang mengisi sejumlah spasi putih (sehingga berjarak lebih jauh daripada acak) cenderung menghasilkan persepsi yang lebih akurat di antara para pengamat.
Andy W
IMO ini adalah ide yang bagus, tetapi jarak antar panel sangat besar dalam contoh ini membuat memvisualisasikan tren apa pun sangat sulit. Obatnya lebih buruk daripada penyakitnya (tetapi harus cukup mudah untuk membuat panel lebih dekat bersama).
Andy W
1
@silverfish quasi-random jittering akan menjadi solusi yang memungkinkan untuk itu. Kekhawatiran Anda adalah salah satu yang saya miliki sendiri.
Glen_b
1
Sangat bagus! IMO ini adalah pilihan yang lebih baik daripada spineplot dalam contoh ini (plot tulang belakang atau mosaik lebih baik untuk menilai distribusi bersyarat untuk setiap pasangan kategori - plot titik yang gelisah ini lebih mudah untuk menilai tren - mengambil keuntungan dari sifat ordinal data dan dengan asumsi beberapa jenis hubungan monotonik).
Andy W
7

Menggunakan paket R riverplot:

  data$importance <- factor(data$importance, 
                            labels = c("not at all important",
                                       "somewhat unimportant",
                                       "neither important nor unimportant",
                                       "somewhat important",
                                       "very important"))
  data$often <- factor(data$often, 
                       labels = c("never",
                                  "less than once per fortnight",
                                  "once every one or two weeks",
                                  "two or three times per week",
                                  "four or more times per week"))

  makeRivPlot <- function(data, var1, var2, ...) {

    require(plyr)
    require(riverplot)
    require(RColorBrewer)

    names1 <- levels(data[, var1])
    names2 <- levels(data[, var2])

    var1 <- as.numeric(data[, var1])
    var2 <- as.numeric(data[, var2])

    edges <- data.frame(var1, var2 + max(var1, na.rm = T))
    edges <- count(edges)

    colnames(edges) <- c("N1", "N2", "Value")

    nodes <- data.frame(ID     = c(1:(max(var1, na.rm = T) +
                                      max(var2, na.rm = T))),
                        x      = c(rep(1, times = max(var1, na.rm = T)),
                                   rep(2, times = max(var2, na.rm = T))),
                        labels = c(names1, names2) ,
                        col    = c(brewer.pal(max(var1, na.rm = T), "Set1"),
                                   brewer.pal(max(var2, na.rm = T), "Set1")),
                        stringsAsFactors = FALSE)

    nodes$col <- paste(nodes$col, 95, sep = "")

    return(makeRiver(nodes, edges))

  }

a <- makeRivPlot(data, "importance", "often")

riverplot(a, srt = 45)

masukkan deskripsi gambar di sini

DL Dahly
sumber
1
(+1) Saya suka ide menggunakan koordinat paralel untuk ini! Saya pikir akan lebih mudah untuk melacak jalur melalui diagram, dan melihat bagaimana jawaban "sering" diuraikan, jika warna mengalir dari kiri ke kanan (skema yang secara efektif akan menampilkan "sering" sebagai variabel dependen dan " pentingnya "sebagai variabel penjelas). Pada beberapa implementasi plot yang interaktif, Anda dapat mengeklik sumbu untuk diwarnai oleh variabel tersebut, yang berguna.
Silverfish
1
Sebagai perbandingan, visualisasi "set paralel" Robert Kosara , yang dirancang untuk data kategorikal, memiliki warna yang mengalir melalui diagram.
Silverfish
6

Ide lain yang tidak saya pikirkan awalnya adalah alur saringan .

masukkan deskripsi gambar di sini

Ukuran setiap ubin sebanding dengan frekuensi yang diharapkan; kotak kecil di dalam persegi panjang mewakili frekuensi aktual. Karenanya kepadatan kotak yang lebih besar menunjukkan frekuensi yang lebih tinggi dari yang diharapkan (dan berwarna biru); kepadatan kotak yang lebih rendah (merah) adalah untuk frekuensi yang lebih rendah dari yang diharapkan.

Saya pikir saya akan lebih suka jika warna mewakili ukuran, bukan hanya tanda, dari residu. Hal ini terutama berlaku untuk kasus tepi di mana frekuensi yang diharapkan dan diamati adalah serupa dan sisanya mendekati nol; skema merah / biru dikotomis tampaknya terlalu menekankan penyimpangan kecil.

Implementasi dalam R:

library(vcd)
runningcounts.df <- as.data.frame(table(importance, often))
sieve(Freq ~ often + importance, data=runningcounts.df, shade= TRUE)
Gegat
sumber
1
Mengenai preferensi Anda bahwa warna mewakili ukuran serta tanda, satu kemungkinan adalah membuat warna lebih abu-abu ketika perbedaan dari yang diharapkan relatif kecil.
Glen_b
6

Bagan bilah segi dalam R. Ini menunjukkan distribusi "sering" pada setiap tingkat "kepentingan" dengan sangat jelas. Tapi itu tidak akan bekerja dengan baik jika jumlah maksimum lebih bervariasi antara tingkat "kepentingan"; cukup mudah untuk diatur scales="free_y"dalam ggplot ( lihat di sini ) untuk menghindari banyak ruang kosong, tetapi bentuk distribusinya akan sulit dilihat pada tingkat "kepentingan" frekuensi rendah karena palang akan sangat kecil. Mungkin dalam situasi itu lebih baik menggunakan frekuensi relatif (probabilitas bersyarat) pada sumbu vertikal sebagai gantinya.

grafik batang faceted

Ini tidak begitu "bersih" seperti tabplot di Stata yang terhubung dengan Nick Cox, tetapi menyampaikan informasi serupa.

Kode R:

library(ggplot)
running2.df <- data.frame(often = factor(often, labels = c("never", "less than once per fortnight", "once every one or two weeks", "two or three times per week", "four or more times per week")), importance = factor(importance, labels = c("not at all important", "somewhat unimportant", "neither important nor unimportant", "somewhat important", "very important")))
ggplot(running2.df, aes(often)) + geom_bar() +
  facet_wrap(~ importance, ncol = 1) +
  theme(axis.text.x=element_text(angle = -45, hjust = 0)) +
  theme(axis.title.x = element_blank())
Gegat
sumber