Menetapkan batas sumbu individu dengan facet_wrap dan scale = "free" di ggplot2

116

Saya membuat plot facetted untuk melihat nilai prediksi vs. nilai aktual secara berdampingan dengan plot nilai prediksi vs. residual. Saya akan menggunakan shinyuntuk membantu mengeksplorasi hasil upaya pemodelan menggunakan parameter pelatihan yang berbeda. Saya melatih model dengan 85% data, menguji 15% sisanya, dan mengulanginya 5 kali, mengumpulkan nilai aktual / prediksi setiap kali. Setelah menghitung residu, data.frametampilan saya seperti ini:

head(results)
       act     pred       resid
2 52.81000 52.86750 -0.05750133
3 44.46000 42.76825  1.69175252
4 54.58667 49.00482  5.58184181
5 36.23333 35.52386  0.70947731
6 53.22667 48.79429  4.43237981
7 41.72333 41.57504  0.14829173

Apa yang saya inginkan:

  • Plot berdampingan dari predvs. actdan predvs.resid
  • Rentang / batas x / y untuk predvs. actharus sama, idealnya dari min(min(results$act), min(results$pred))hinggamax(max(results$act), max(results$pred))
  • Rentang / batas x / y untuk predvs. resid tidak akan terpengaruh oleh apa yang saya lakukan pada plot aktual vs. yang diprediksi. Membuat plot xhanya untuk nilai yang diprediksi dan yhanya untuk rentang residual saja boleh.

Untuk melihat kedua plot secara berdampingan, saya mencairkan data:

library(reshape2)
plot <- melt(results, id.vars = "pred")

Sekarang plot:

library(ggplot2)
p <- ggplot(plot, aes(x = pred, y = value)) + geom_point(size = 2.5) + theme_bw()
p <- p + facet_wrap(~variable, scales = "free")

print(p)

Itu cukup dekat dengan yang saya inginkan:

masukkan deskripsi gambar di sini

Yang saya inginkan adalah untuk rentang x dan y untuk aktual vs. yang diperkirakan sama, tetapi saya tidak yakin bagaimana menentukannya, dan saya tidak perlu melakukannya untuk plot prediksi vs. sisa karena rentang benar-benar berbeda.

Saya mencoba menambahkan sesuatu seperti ini untuk keduanya scale_x_continousdan scale_y_continuous:

min_xy <- min(min(plot$pred), min(plot$value))
max_xy <- max(max(plot$pred), max(plot$value))

p <- ggplot(plot, aes(x = pred, y = value)) + geom_point(size = 2.5) + theme_bw()
p <- p + facet_wrap(~variable, scales = "free")
p <- p + scale_x_continuous(limits = c(min_xy, max_xy))
p <- p + scale_y_continuous(limits = c(min_xy, max_xy))

print(p)

Tapi itu mengambil min()nilai sisa.

masukkan deskripsi gambar di sini

Satu ide terakhir yang saya miliki adalah menyimpan nilai minimum actdan predvariabel sebelum melebur, dan kemudian menambahkannya ke bingkai data yang dilelehkan untuk menentukan di mana segi kemunculannya:

head(results)
       act     pred       resid
2 52.81000 52.86750 -0.05750133
3 44.46000 42.76825  1.69175252
4 54.58667 49.00482  5.58184181
5 36.23333 35.52386  0.70947731

min_xy <- min(min(results$act), min(results$pred))
max_xy <- max(max(results$act), max(results$pred))

plot <- melt(results, id.vars = "pred")

plot <- rbind(plot, data.frame(pred = c(min_xy, max_xy),
  variable = c("act", "act"), value = c(max_xy, min_xy)))

p <- ggplot(plot, aes(x = pred, y = value)) + geom_point(size = 2.5) + theme_bw()
p <- p + facet_wrap(~variable, scales = "free")

print(p)

Itu melakukan apa yang saya inginkan, dengan pengecualian bahwa poinnya juga muncul:

masukkan deskripsi gambar di sini

Ada saran untuk melakukan hal seperti ini?


Saya melihat ide ini untuk ditambahkan geom_blank(), tetapi saya tidak yakin bagaimana menentukan aes()bit dan membuatnya berfungsi dengan benar, atau apa yang geom_point()setara dengan penggunaan histogram aes(y = max(..count..)).


Berikut data untuk dimainkan (nilai aktual, prediksi, dan residu saya sebelum mencair):

> dput(results)
structure(list(act = c(52.81, 44.46, 54.5866666666667, 36.2333333333333, 
53.2266666666667, 41.7233333333333, 35.2966666666667, 30.6833333333333, 
39.25, 35.8866666666667, 25.1, 29.0466666666667, 23.2766666666667, 
56.3866666666667, 42.92, 41.57, 27.92, 23.16, 38.0166666666667, 
61.8966666666667, 37.41, 41.6333333333333, 35.9466666666667, 
48.9933333333333, 30.5666666666667, 32.08, 40.3633333333333, 
53.2266666666667, 64.6066666666667, 38.5366666666667, 41.7233333333333, 
25.78, 33.4066666666667, 27.8033333333333, 39.3266666666667, 
48.9933333333333, 25.2433333333333, 32.67, 55.17, 42.92, 54.5866666666667, 
23.16, 64.6066666666667, 40.7966666666667, 39.0166666666667, 
41.6333333333333, 35.8866666666667, 25.1, 23.2766666666667, 44.46, 
34.2166666666667, 40.8033333333333, 24.5766666666667, 35.73, 
61.8966666666667, 62.1833333333333, 74.6466666666667, 39.4366666666667, 
36.6, 27.1333333333333), pred = c(52.8675013282404, 42.7682474758679, 
49.0048248585123, 35.5238560262515, 48.7942868566949, 41.5750416040131, 
33.9548164913007, 29.9787449128663, 37.6443975781139, 36.7196211666685, 
27.6043278172077, 27.0615724310721, 31.2073056885252, 55.0886903524179, 
43.0895814712768, 43.0895814712768, 32.3549865881578, 26.2428426737583, 
36.6926037128343, 56.7987490221996, 45.0370788180147, 41.8231642271826, 
38.3297859332601, 49.5343916620086, 30.8535641206809, 29.0117492750411, 
36.9767968381391, 49.0826677983065, 54.4678549541069, 35.5059204731218, 
41.5333417555995, 27.6069075391361, 31.2404889715121, 27.8920960978598, 
37.8505531149324, 49.2616631533957, 30.366837650159, 31.1623492639066, 
55.0456078770405, 42.772538591063, 49.2419293590535, 26.1963523976241, 
54.4080781796616, 44.9796700541254, 34.6996927469131, 41.6227713664027, 
36.8449646519306, 27.5318686661673, 31.6641793552795, 42.8198894266632, 
40.5769177148146, 40.5769177148146, 29.3807781312816, 36.8579132935989, 
55.5617033901752, 55.8097119335638, 55.1041728261666, 43.6094641699075, 
37.0674887276681, 27.3876960746536), resid = c(-0.0575013282403773, 
1.69175252413213, 5.58184180815435, 0.709477307081826, 4.43237980997177, 
0.148291729320228, 1.34185017536599, 0.704588420467079, 1.60560242188613, 
-0.832954500001826, -2.50432781720766, 1.98509423559461, -7.93063902185855, 
1.29797631424874, -0.169581471276786, -1.51958147127679, -4.43498658815778, 
-3.08284267375831, 1.32406295383237, 5.09791764446704, -7.62707881801468, 
-0.189830893849219, -2.38311926659339, -0.541058328675241, -0.286897454014273, 
3.06825072495888, 3.38653649519422, 4.14399886836018, 10.1388117125598, 
3.03074619354486, 0.189991577733821, -1.82690753913609, 2.16617769515461, 
-0.088762764526507, 1.47611355173427, -0.268329820062384, -5.12350431682565, 
1.5076507360934, 0.124392122959534, 0.147461408936991, 5.34473730761318, 
-3.03635239762411, 10.1985884870051, -4.18300338745873, 4.31697391975358, 
0.0105619669306023, -0.958297985263961, -2.43186866616734, -8.38751268861282, 
1.64011057333683, -6.36025104814794, 0.226415618518729, -4.80411146461488, 
-1.1279132935989, 6.33496327649151, 6.37362139976954, 19.5424938405001, 
-4.17279750324084, -0.467488727668119, -0.254362741320246)), .Names = c("act", 
"pred", "resid"), row.names = c(2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 
10L, 11L, 12L, 13L, 15L, 16L, 17L, 18L, 19L, 20L, 21L, 22L, 23L, 
24L, 25L, 26L, 28L, 29L, 30L, 31L, 32L, 33L, 34L, 35L, 36L, 37L, 
38L, 39L, 41L, 42L, 43L, 44L, 45L, 46L, 47L, 48L, 49L, 50L, 51L, 
52L, 54L, 55L, 56L, 57L, 58L, 59L, 60L, 61L, 62L, 63L, 64L, 65L
), class = "data.frame")
Hendy
sumber
Hanya ingin tahu - mengapa tidak memplot aktual dan residu dalam grafik yang sama?
Ricardo Saporta
2
Saya akan membuat plot secara terpisah dan kemudian menggunakan grid.arrange.
joran
@RicardoSaporta Apakah ada gambar google yang dapat Anda tautkan sebagai contoh? Apakah Anda menyarankan, dengan menggunakan data setelah meleleh, yang akan saya lakukan ggplot(plot, aes(x = pred, y = value)) + geom_point()tanpa facetting? Bukankah itu benar-benar mengecilkan skala residu untuk membuatnya sulit mendeteksi non-randomness / skew?
Hendy
1
Komentar saya yang lain adalah bahwa facetting adalah lebih sedikit kode ... Saya hanya harus mencair, lalu plot dan facet oleh variablenilai yang dibuat oleh melt(). Kemudian lagi, saya kira saya bisa menyimpan ini dalam daftar yang dibuat oleh lapplyuntuk merencanakan berbagai kombinasi. Terima kasih atas masukannya. Jika Anda ingin membuat gridsolusi, saya dapat menerima jawabannya, meskipun jika itu rute yang kami ambil, ini mungkin juga merupakan duplikat dari gridsolusi berbasis lainnya .
Hendy
1
@joran dan saya menemukan saya secara rutin menasihati orang - orang untuk tidak menggunakan grid.arrangeyang hampir selalu mengacaukan tata letak. Saya berharap bug lama gtable ditangani.
baptiste

Jawaban:

115

Berikut beberapa kode dengan geom_blanklapisan tiruan ,

range_act <- range(range(results$act), range(results$pred))

d <- reshape2::melt(results, id.vars = "pred")

dummy <- data.frame(pred = range_act, value = range_act,
                    variable = "act", stringsAsFactors=FALSE)

ggplot(d, aes(x = pred, y = value)) +
  facet_wrap(~variable, scales = "free") +
  geom_point(size = 2.5) + 
  geom_blank(data=dummy) + 
  theme_bw()

masukkan deskripsi gambar di sini

baptiste
sumber
11
Varian yang bagus untuk ini adalah expand_limits(pred=range_act, value=range_act), yang menggunakan geom_blanktetapi lebih mudah digunakan.
eregon
6
Ini hanya memperluas batas (tetapi tidak mengkontraksikannya) Apakah ada cara untuk memperpendek jangkauan? @baptisaja
Indra Gayen
32

Saya tidak yakin saya mengerti apa yang Anda inginkan, tetapi berdasarkan apa yang saya mengerti

skala x tampaknya sama, itu adalah skala y yang tidak sama, dan itu karena Anda menentukan skala = "bebas"

Anda dapat menentukan skala = "free_x" untuk hanya mengizinkan x menjadi bebas (dalam hal ini sama dengan pred memiliki rentang yang sama menurut definisi)

p <- ggplot(plot, aes(x = pred, y = value)) + geom_point(size = 2.5) + theme_bw()
p <- p + facet_wrap(~variable, scales = "free_x")

bekerja untuk saya, lihat gambar

masukkan deskripsi gambar di sini

Saya pikir Anda membuatnya terlalu sulit - Saya sepertinya ingat suatu kali mendefinisikan batas berdasarkan rumus dengan min dan max dan jika segi saya pikir itu hanya menggunakan nilai-nilai itu, tetapi saya tidak dapat menemukan kodenya

pengguna1617979
sumber
7

Anda juga dapat menentukan rentang dengan perintah coord_cartesian untuk mengatur rentang sumbu y yang Anda inginkan, seperti di posting sebelumnya gunakan skala = free_x

p <- ggplot(plot, aes(x = pred, y = value)) +
     geom_point(size = 2.5) +
     theme_bw()+
     coord_cartesian(ylim = c(-20, 80))
p <- p + facet_wrap(~variable, scales = "free_x")
p

masukkan deskripsi gambar di sini

Luis Candanedo
sumber