Diagram Sankey di R?


89

Saya mencoba untuk memvisualisasikan aliran data saya dengan Diagram Sankey di R.

Saya menemukan posting blog ini tertaut ke skrip R yang menghasilkan Diagram Sankey, sayangnya ini cukup mentah dan agak terbatas (lihat di bawah untuk contoh kode dan data).

Adakah yang tahu tentang skrip lain — atau mungkin bahkan sebuah paket — yang lebih berkembang? Tujuan akhir saya adalah untuk memvisualisasikan aliran data dan persentase dengan ukuran relatif komponen diagram, seperti dalam contoh Diagram Sankey ini .

Saya memposting pertanyaan yang agak mirip di daftar r-help , tetapi setelah dua minggu tanpa tanggapan, saya mencoba keberuntungan saya di sini di stackoverflow.

Terima kasih, Eric

PS. Saya mengetahui tentang Parallel Sets Plot , tapi bukan itu yang saya cari.

# thanks to, https://tonybreyal.wordpress.com/2011/11/24/source_https-sourcing-an-r-script-from-github/
  sourc.https     <- function(url, ...) {
# install and load the RCurl package 
if (match('RCurl', nomatch=0, installed.packages()[,1])==0) {
  install.packages(c("RCurl"), dependencies = TRUE)
  require(RCurl)  
} else require(RCurl)    

# parse and evaluate each .R script
  sapply(c(url, ...), function(u) {
    eval(parse(text = getURL(u, followlocation = TRUE, 
    cainfo  = system.file("CurlSSL", "cacert.pem", 
    package = "RCurl"))), envir = .GlobalEnv)
 } )
 }

# from https://gist.github.com/1423501
sourc.https("https://raw.github.com/gist/1423501/55b3c6f11e4918cb6264492528b1ad01c429e581/Sankey.R")

# My example (there is another example inside Sankey.R):
inputs = c(6, 144)
losses = c(6,47,14,7, 7, 35, 34)
unit = "n ="

labels = c("Transfers",
           "Referrals\n",
           "Unable to Engage",
           "Consultation only",
           "Did not complete the intake",
           "Did not engage in Treatment",
           "Discontinued Mid-Treatment",
           "Completed Treatment",
           "Active in \nTreatment")

SankeyR(inputs,losses,unit,labels)

# Clean up my mess
rm("inputs", "labels", "losses", "SankeyR", "sourc.https", "unit")

Diagram Sankey diproduksi dengan kode di atas, Diagram Sankey diproduksi dengan kode di atas


2
Bagi saya panah terlihat baik-baik saja, sepertinya Anda sudah menyempurnakan teksnya dan Anda sudah siap?
Roman Luštrik

@Roman Luštrik, Saya setuju, diagram ini tidak buruk sama sekali, tetapi keterampilan R saya masih terbatas sehingga saya tidak dapat melakukan banyak penyetelan dengan baik di R, jika itu yang Anda maksud? Saya tentu saja bisa melakukannya di Adobe Illustrator, atau semacamnya, tapi itu akan mematahkan prinsip penelitian yang dapat direproduksi, yang bagi saya adalah elemen sentral dalam pekerjaan (akademis) apa pun. Apakah Anda melihat contoh yang saya tautkan di pos ?
Eric Fail

Saya menyadari pertanyaan saya bukanlah pertanyaan yang baik dalam arti bahwa ini bukan masalah pemrograman spesifik dan tidak praktis secara langsung, tetapi pertanyaan yang agak terbuka ( dari FAQ ). Untuk menjawab pertanyaan ini, seseorang harus memiliki pengawasan atas opsi grafik yang berbeda di R dan atas dasar itu menjawab pertanyaan saya dengan tidak, tidak ada skrip atau paket di luar sana yang lebih berkembang , atau seseorang perlu mengetahui tentang a metode yang lebih berkembang untuk menghasilkan Diagram Sankey di R dan menunjukkannya. Mungkin ada tempat yang lebih baik untuk memposting pertanyaan ini?
Eric Fail

1
Satu-satunya tempat yang bisa saya temukan mungkin adalah crossvalidated.com.
Roman Luštrik

Bagaimana dengan milis R-help? r-project.org/mail.html
Alex Reynolds

Jawaban:


63

Plot ini dapat dibuat melalui networkD3paket. Ini memungkinkan Anda membuat diagram sankey interaktif. Di sini Anda dapat menemukan contohnya . Saya juga menambahkan tangkapan layar sehingga Anda tahu seperti apa tampilannya.

# Load package
library(networkD3)

# Load energy projection data
# Load energy projection data
URL <- paste0(
        "https://cdn.rawgit.com/christophergandrud/networkD3/",
        "master/JSONdata/energy.json")
Energy <- jsonlite::fromJSON(URL)
# Plot
sankeyNetwork(Links = Energy$links, Nodes = Energy$nodes, Source = "source",
             Target = "target", Value = "value", NodeID = "name",
             units = "TWh", fontSize = 12, nodeWidth = 30)

masukkan deskripsi gambar di sini


4
contoh tautan rusak
rmstmppr

1
Memang. Alternatif yang lebih baik sejak pengenalan htmlwidgetsadalah plot sankey dari networkD3paket. Saya memperbarui posting.
Jonas Tundo

1
Apakah mungkin untuk memiliki nilai numerik sebagai teks, bukan integer? Nilai diambil dengan benar, tetapi teksnya tampaknya dibulatkan. Misal: value = 0.8 dan value = 0.2 memiliki lebar garis yang berbeda, tetapi caption-nya mengatakan '0' untuk keduanya.
Naveen Mathew

jika Anda mencoba mereproduksi ini dengan beberapa contoh data Anda sendiri, pastikan id sumber pertama dimulai dengan 0 dan id sumber dan target berurutan
Richard

43

Saya telah membuat paket ( plot sungai ) yang memiliki fungsi yang sedikit berbeda, tetapi tumpang tindih dibandingkan dengan fungsi Sankey, dan dapat menghasilkan plot seperti ini:

masukkan deskripsi gambar di sini


Ini terlihat sangat mengesankan! Saya akan melihatnya secepatnya.
Eric Fail

39

Jika Anda ingin melakukannya dengan R, tawaran terbaik Anda sepertinya adalah saran @Roman - hack fungsi SankeyR . Misalnya - di bawah ini adalah perbaikan saya yang sangat cepat - cukup arahkan label secara vertikal, offset sedikit dan kurangi font untuk referensi input agar terlihat sedikit lebih baik. Modifikasi ini hanya mengubah baris 171 dan 223 dalam fungsi SankeyR :

    #line171 - change oversized font size of input label
    fontsize = max(0.5,frInputs[j]*1.5)#1.5 instead of 2.5 

    #line223 - srt changes from 35 to 90 to orient labels vertically, 
    #and offset adjusts them to get better alignment with arrows
    text(txtX, txtY, fullLabel, cex=fontsize, pos=4, srt=90, offset=0.1)

masukkan deskripsi gambar di sini

Saya bukan jagoan trigonometri, tapi inilah yang Anda butuhkan untuk mengubah arah panah. Itu akan ideal dalam pandangan saya - jika Anda bisa menyesuaikan panah yang hilang sehingga mereka berorientasi horizontal daripada vertikal. Jika tidak, mengapa solusi saya memperbaiki masalah dengan orientasi label, itu tidak membuat diagram lebih mudah dibaca ...


1
itu hack yang bagus, terima kasih. Saya sudah membuatnya jauh lebih baik. Anda memiliki suara positif saya dan jika tidak ada yang lebih baik, saya akan dengan senang hati mentransfer hadiah tersebut kepada Anda saat waktu habis. Juga, saya suka nama pengguna Anda.
Eric Fail

24

Selain rCharts , diagram Sankey sekarang juga dapat dibuat di R dengan googleVis (versi> = 0.5.0). Misalnya, posting ini menjelaskan pembuatan diagram berikut menggunakan googleVis: masukkan deskripsi gambar di sini


15

R's paket juga akan melakukan ini (dari ?alluvial).

# install.packages(c("alluvial"), dependencies = TRUE)
require(alluvial)

# Titanic data
tit <- as.data.frame(Titanic)

# 4d
alluvial( tit[,1:4], freq=tit$Freq, border=NA,
     hide = tit$Freq < quantile(tit$Freq, .50),
     col=ifelse( tit$Class == "3rd" & tit$Sex == "Male", "red", "gray") )

masukkan deskripsi gambar di sini



6

Dilihat dari definisi ini, fungsi ini, seperti Plot Himpunan Paralel, tidak memiliki kapasitas untuk membagi dan menggabungkan aliran (yaitu melalui lebih dari satu transisi).

Karena diagram Sankey diarahkan pada grafik berbobot , paket seperti qgraph mungkin berguna.

The SankeyRFungsi memberikan label yang lebih jelas jika Anda semacam kerugian dalam urutan sebagai teks ditempatkan lebih dekat ke kepala panah tanpa tumpang tindih.


1
Menyortir kerugian dalam urutan menurun akan merusak kualitas arah diagram. Jika Anda melihat lebih dekat pada diagram yang saya kirimkan, Anda akan melihat bahwa waktu berada pada sumbu x, oleh karena itu urutannya saat ini. Saya mengetahui sankey-diagrams.com dan artikel-artikelnya, pikiran pertama saya ketika saya melihat situs web itu adalah membuka op R dan menghasilkan Diagram Sankey yang bagus di ggplot2 .
Eric Fail

5

lihat //sankeybuilder.com karena menawarkan solusi siap pakai di mana Anda dapat mengunggah data dan variasi pemutaran dari waktu ke waktu. Transisi berfungsi dengan baik (mirip dengan demo youtube di pertanyaan Anda). Jika Anda memuat demo SankeyTrend, itu mencakup banyak slot waktu (data Tahun). Setelah dimuat (membangun sankeys secara otomatis), klik tombol putar di sudut kanan atas halaman untuk pemutaran slot waktu, Anda bahkan dapat menjeda dan melanjutkan waktu. Demo url ada di sini: SankeyTrend Semoga ini membantu pencarian Anda untuk diagram Sankey yang sempurna.


4

Untuk kelengkapannya juga tersedia ggalluvialpaket yaitu aggplot2 extension untuk diagram aluvial / Sankey.

Berikut adalah contoh yang diambil dari dokumentasi paket

# devtools::install_github("corybrunson/ggalluvial", ref = "optimization")
library(ggalluvial)

titanic_wide <- data.frame(Titanic)
ggplot(data = titanic_wide,
       aes(axis1 = Class, axis2 = Sex, axis3 = Age,
           y = Freq)) +
  scale_x_discrete(limits = c("Class", "Sex", "Age"), expand = c(.1, .05)) +
  xlab("Demographic") +
  geom_alluvium(aes(fill = Survived)) +
  geom_stratum() + geom_text(stat = "stratum", label.strata = TRUE) +
  theme_minimal() +
  ggtitle("passengers on the maiden voyage of the Titanic",
          "stratified by demographics and survival") +
  theme(legend.position = 'bottom')

ggplot(titanic_wide,
       aes(y = Freq,
           axis1 = Survived, axis2 = Sex, axis3 = Class)) +
  geom_alluvium(aes(fill = Class),
                width = 0, knot.pos = 0, reverse = FALSE) +
  guides(fill = FALSE) +
  geom_stratum(width = 1/8, reverse = FALSE) +
  geom_text(stat = "stratum", label.strata = TRUE, reverse = FALSE) +
  scale_x_continuous(expand = c(0, 0), 
                     breaks = 1:3, labels = c("Survived", "Sex", "Class")) +
  scale_y_discrete(expand = c(0, 0)) +
  coord_flip() +
  ggtitle("Titanic survival by class and sex")

Dibuat pada 2018-11-13 oleh paket reprex reprex (v0.2.1.9000)


Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.