Sơ đồ Sankey trong R?


86

Tôi đang cố gắng hình dung luồng dữ liệu của mình bằng Sơ đồ Sankey trong R.

Tôi thấy bài đăng trên blog này liên kết đến một tập lệnh R tạo ra Sơ đồ Sankey, tiếc là nó khá thô và hơi hạn chế (xem bên dưới để biết mã và dữ liệu mẫu).

Có ai biết về các tập lệnh khác — hoặc thậm chí có thể là một gói — được phát triển hơn không? Mục tiêu cuối cùng của tôi là trực quan hóa cả luồng dữ liệu và tỷ lệ phần trăm theo kích thước tương đối của các thành phần sơ đồ, như trong các ví dụ này về Sơ đồ Sankey .

Tôi đã đăng một câu hỏi hơi tương tự trên danh sách trợ giúp r , nhưng sau hai tuần mà không có bất kỳ câu trả lời nào, tôi đang thử vận ​​may của mình ở đây trên stackoverflow.

Cảm ơn, Eric

Tái bút. Tôi biết về Âm mưu Bộ song song , nhưng đó không phải là thứ tôi đang tìm kiếm.

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

Sơ đồ Sankey được tạo với mã trên, Sơ đồ Sankey được tạo với mã trên


2
Các mũi tên trông ổn đối với tôi, có vẻ như bạn chỉ cần tinh chỉnh văn bản và bạn đang ở trong đó?
Roman Luštrik

@Roman Luštrik, tôi đồng ý, sơ đồ này không tệ chút nào, nhưng kỹ năng R của tôi vẫn còn hạn chế nên tôi thực sự không thể điều chỉnh nhiều như vậy trong R, nếu đó là ý của bạn? Tất nhiên tôi có thể làm điều đó trong Adobe Illustrator, hoặc một cái gì đó tương tự, nhưng điều đó sẽ phá vỡ nguyên tắc nghiên cứu có thể tái tạo, mà đối với tôi là yếu tố trung tâm trong bất kỳ tác phẩm (học thuật) nào. Bạn đã xem các ví dụ tôi liên kết trong bài đăng chưa?
Eric Thất bại

Tôi nhận thấy câu hỏi của mình không phải là một câu hỏi hay theo nghĩa nó không phải là một vấn đề lập trình cụ thể và không trực tiếp thực tế, mà là một câu hỏi hơi mở ( từ Câu hỏi thường gặp ). Để trả lời câu hỏi này, người ta sẽ phải giám sát các tùy chọn vẽ đồ thị khác nhau trong R và trên cơ sở đó trả lời câu hỏi của tôi bằng không, không có tập lệnh hoặc gói nào ở đó được phát triển hơn , hoặc người ta sẽ cần biết về một phương pháp phát triển hơn để tạo Sơ đồ Sankey trong R và chỉ vào nó. Có lẽ có một nơi tốt hơn để đăng câu hỏi này?
Eric Thất bại

1
Nơi duy nhất tôi có thể nghĩ ra có lẽ là crossvalidated.com.
Roman Luštrik

Làm thế nào về danh sách gửi thư trợ giúp R? r-project.org/mail.html
Alex Reynolds

Câu trả lời:


63

Cốt truyện này có thể được tạo thông qua networkD3gói. Nó cho phép bạn tạo sơ đồ sankey tương tác. Ở đây bạn có thể tìm thấy một ví dụ . Tôi cũng đã thêm một ảnh chụp màn hình để bạn có thể biết nó trông như thế nào.

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

nhập mô tả hình ảnh ở đây


4
Ví dụ liên kết bị phá vỡ
rmstmppr

1
Thật. Một giải pháp thay thế tốt hơn kể từ khi giới thiệu htmlwidgetslà cốt truyện sankey từ networkD3gói. Tôi đã cập nhật bài viết.
Jonas Tundo

1
Có thể có giá trị số dưới dạng chú thích thay vì số nguyên không? Các giá trị được lấy chính xác, nhưng chú thích dường như được làm tròn. Ví dụ: value = 0.8 và value = 0.2 có độ rộng dòng khác nhau, nhưng chú thích cho biết '0' cho cả hai.
Naveen Mathew

nếu bạn cố gắng tái tạo điều này với một số mẫu dữ liệu của riêng bạn, hãy đảm bảo rằng id nguồn đầu tiên bắt đầu bằng 0 và id nguồn và id mục tiêu kế tiếp nhau
Richard

43

Tôi đã tạo một gói ( riverplot ) có chức năng hơi khác, nhưng chồng chéo so với hàm Sankey và có thể tạo ra các âm mưu như thế này:

nhập mô tả hình ảnh ở đây


Điều này trông thực sự ấn tượng! Tôi sẽ xem xét nó càng sớm càng tốt.
Eric Thất bại

39

Nếu bạn muốn làm điều đó với R, giá thầu tốt nhất của bạn dường như là gợi ý @Roman - hãy hack chức năng SankeyR . Ví dụ - dưới đây là cách khắc phục rất nhanh của tôi - chỉ cần định hướng các nhãn thẳng đứng, bù trừ chúng và giảm phông chữ cho các giới thiệu đầu vào để làm cho nó trông đẹp hơn một chút. Sửa đổi này chỉ thay đổi dòng 171 và 223 trong hàm 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)

nhập mô tả hình ảnh ở đây

Tôi không phải là át chủ bài về lượng giác, nhưng đây thực sự là thứ bạn cần để thay đổi hướng mũi tên. Điều đó sẽ là lý tưởng theo quan điểm của tôi - nếu bạn có thể điều chỉnh các mũi tên lỏng lẻo để chúng được định hướng theo chiều ngang thay vì theo chiều dọc. Nếu không, tại sao giải pháp của tôi khắc phục sự cố với hướng nhãn, nó không làm cho sơ đồ dễ đọc hơn ...


1
đó là một hack tốt, cảm ơn. Tôi đã làm cho nó tốt hơn nhiều. Bạn có phiếu bầu của tôi và nếu không có gì tốt hơn, tôi rất vui được chuyển tiền thưởng cho bạn khi hết thời gian. Ngoài ra, tôi thích tên người dùng của bạn.
Eric Thất bại

24

Ngoài rCharts , sơ đồ Sankey giờ đây cũng có thể được tạo trong R với googleVis (phiên bản> = 0.5.0). Ví dụ: bài đăng này mô tả việc tạo ra sơ đồ sau bằng googleVis: nhập mô tả hình ảnh ở đây


15

Của R gói cũng sẽ làm điều này (từ ?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") )

nhập mô tả hình ảnh ở đây



6

Đánh giá theo các định nghĩa này, chức năng này, giống như Biểu đồ bộ song song, thiếu khả năng phân chia và kết hợp các luồng (tức là thông qua nhiều hơn một quá trình chuyển đổi).

biểu đồ Sankey là biểu đồ có trọng số có hướng , một gói như qgraph có thể hữu ích.

Các SankeyRchức năng cung cấp nhãn rõ ràng hơn nếu bạn sắp xếp các khoản lỗ theo thứ tự như văn bản giảm dần được đặt gần gũi hơn với người đứng đầu mũi tên mà không chồng chéo.


1
Sắp xếp các khoản lỗ theo thứ tự giảm dần sẽ phá vỡ chất lượng định hướng của biểu đồ. Nếu bạn nhìn kỹ vào biểu đồ tôi đã gửi, bạn sẽ thấy rằng thời gian nằm trên trục x, do đó có thứ tự hiện tại. Tôi biết đến sankey-diagrams.com và các bài báo trên đó, suy nghĩ đầu tiên của tôi khi nhìn thấy trang web đó là mở op R và tạo ra một Sơ đồ Sankey đẹp trong ggplot2 .
Eric Thất bại

5

hãy xem //sankeybuilder.com vì nó cung cấp giải pháp sẵn sàng hoạt động, nơi bạn có thể tải lên dữ liệu của mình và phát lại các biến thể theo thời gian. Quá trình chuyển đổi hoạt động tốt (tương tự như bản trình diễn youtube trong câu hỏi của bạn). Nếu bạn tải bản demo SankeyTrend, nó bao gồm nhiều khe thời gian (Dữ liệu năm). Sau khi tải (xây dựng các sankeys tự động), hãy nhấp vào nút phát ở góc trên bên phải của trang để phát lại các khe thời gian, bạn thậm chí có thể tạm dừng và tiếp tục thời gian. Url demo ở đây: SankeyTrend Hy vọng điều này sẽ giúp ích cho việc tìm kiếm sơ đồ Sankey hoàn hảo.


4

Để hoàn thiện, cũng có ggalluvialgói ggplot2 extensiondành cho sơ đồ phù sa / Sankey.

Đây là một ví dụ được lấy từ tài liệu của gói

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

Được tạo vào ngày 11 tháng 11 năm 2018 bởi gói reprex (v0.2.1.9000)


Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.