R의 Sankey 다이어그램?


88

R의 Sankey Diagram을 사용하여 데이터 흐름을 시각화하려고합니다.

이 블로그 게시물이 Sankey 다이어그램을 생성하는 R 스크립트에 연결되어 있음을 발견 했습니다 . 안타깝게도 상당히 원시적이며 다소 제한적입니다 (샘플 코드 및 데이터는 아래 참조).

누구든지 더 개발 된 다른 스크립트 또는 패키지에 대해 알고 있습니까? 내 최종 목표는 Sankey Diagrams 예제 에서와 같이 다이어그램 구성 요소의 상대적 크기별로 데이터 흐름과 백분율을 시각화하는 것입니다 .

나는 r-help list에 다소 비슷한 질문을 올렸지 만, 아무런 응답도없이 2 주 후에 나는 여기서 내 행운을 시도하고있다.

고마워, 에릭

추신. 저는 Parallel Sets Plot을 알고 있지만 제가 찾고있는 것은 아닙니다.

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

위 코드로 생성 된 Sankey Diagram, 위 코드로 생성 된 Sankey 다이어그램


2
화살표가 나에게 괜찮아 보이는데, 텍스트를 미세 조정하고있는 것 같습니까?
Roman Luštrik 2012

@Roman Luštrik, 동의합니다.이 다이어그램은 전혀 나쁘지 않지만 내 R 기술은 여전히 ​​제한되어 있으므로 R에서 그렇게 많은 미세 조정을 할 수 없습니다. 물론 어도비 일러스트 레이터 나 그와 비슷한 곳에서 할 수는 있지만, 그것은 재현 가능한 연구의 원칙을 깨뜨릴 것입니다. 저에게는 어떤 (학술적인) 작업의 핵심 요소입니다. 게시물에서 링크 한 예제를 보셨습니까 ?
Eric Fail

나는 내 질문이 특정 프로그래밍 문제가 아니며 직접적으로 실용적이지 않다는 점에서 좋은 질문이 아니라 다소 개방적인 질문 ( FAQ에서 ) 임을 알고 있습니다 . 이 질문에 대답하려면 R의 다른 그래프 옵션을 감독해야하고 그에 따라 내 질문에 아니오로 대답 해야합니다. 더 개발 된 스크립트 나 패키지가 없습니다 . R에서 Sankey Diagrams를 생성하고 그것을 가리키는 더 발전된 방법. 이 질문을 게시하기에 더 좋은 곳이 있습니까?
Eric Fail

1
내가 생각 해낼 수있는 유일한 장소는 아마도 crossvalidated.com 일 것입니다.
Roman Luštrik 2012

R-help 메일 링리스트는 어떻습니까? r-project.org/mail.html
Alex Reynolds

답변:


63

이 플롯은 networkD3패키지를 통해 생성 할 수 있습니다 . 대화 형 sankey 다이어그램을 만들 수 있습니다. 여기에서 예를 찾을 수 있습니다 . 또한 스크린 샷을 추가하여 어떻게 생겼는지 알 수 있습니다.

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

여기에 이미지 설명 입력


4
예를 들어 링크가 깨진
rmstmppr

1
과연. 도입 이후 더 나은 대안 htmlwidgetsnetworkD3패키지 의 sankey 플롯입니다 . 게시물을 업데이트했습니다.
Jonas Tundo

1
정수 대신 캡션으로 숫자 값을 가질 수 있습니까? 값이 올바르게 사용되지만 캡션이 반올림 된 것 같습니다. 예 : value = 0.8 및 value = 0.2는 선 너비가 다르지만 캡션은 둘 다 '0'으로 표시됩니다.
Naveen Mathew

당신이 당신의 자신의 일부 데이터 샘플이 재현하려고하면, 0 최초의 소스 ID가 시작되고 소스 및 대상 아이디의 연속 있는지 확인
리처드

43

Sankey 함수와 약간 다르지만 기능이 겹치는 패키지 ( riverplot )를 만들었으며 다음 과 같은 플롯을 생성 할 수 있습니다.

여기에 이미지 설명 입력


이것은 정말 인상적입니다! 최대한 빨리 살펴 보겠습니다.
Eric Fail

39

R로하고 싶다면, 최고의 입찰가는 @Roman 제안 인 것 같습니다 . SankeyR 기능을 해킹하세요 . 예를 들어-아래는 내 매우 빠른 수정 사항입니다. 레이블을 수직으로 맞추고, slighlty 오프셋을 적용하고, 입력 참조 용 글꼴을 줄여 좀 더보기 좋게 만듭니다. 이 수정은 SankeyR 함수 의 171 및 223 행만 변경 합니다.

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

여기에 이미지 설명 입력

나는 삼각법의 에이스가 아니지만, 이것은 화살표의 방향을 바꾸는 데 정말로 필요한 것입니다. 그것은 내 관점에서 이상적 일 것입니다. 만약 당신이 화살표가 수직이 아니라 수평으로 향하도록 루스 화살표를 조정할 수 있다면. 그렇지 않으면 내 솔루션이 레이블 방향 문제를 해결하는 이유는 다이어그램을 훨씬 더 읽기 쉽게 만들지 않습니다.


1
멋진 해킹입니다. 감사합니다. 나는 이미 그것을 훨씬 더 잘 만들었다. 당신은 내 찬성표를 가지고 있고 더 좋은 것이 없다면 나는 시간이 다되었을 때 당신에게 현상금을 전달하게되어 기쁩니다. 또한 사용자 이름이 좋습니다.
에릭 실패

24

이외에도 rCharts , Sankey의 도면 이제 R로 생성 될 수 googleVis (버전> = 0.5.0). 예 를 들어이 게시물 에서는 googleVis를 사용하여 다음 다이어그램을 생성하는 방법을 설명합니다. 여기에 이미지 설명 입력


15

R 패키지도이 작업을 수행합니다 (에서 ?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") )

여기에 이미지 설명 입력



6

이러한 정의로 판단 할 때이 기능은 병렬 집합 플롯과 같이 흐름을 분할하고 결합 할 수있는 능력이 부족합니다 (즉, 하나 이상의 전환을 통해).

이후 Sankey 다이어그램 가중 그래프 관한 같은 패키지 qgraph을 유용 할 수 있습니다.

SankeyR기능은 텍스트가 겹치지 않고 화살표 머리에 더 가깝게 배치되므로 손실을 내림차순으로 정렬하면 더 명확한 레이블을 제공합니다.


1
손실을 내림차순으로 정렬 하면 다이어그램의 방향성이 손상됩니다. 내가 제출 한 다이어그램을 자세히 살펴보면 시간 이 x 축에 있으므로 현재 순서가 표시됩니다. 나는 sankey-diagrams.com 과 그에 관한 기사를 알고 있습니다. 그 웹 사이트를 보았을 때 처음 생각은 op R을 열고 ggplot2 에서 멋진 Sankey Diagram을 생성하는 입니다.
Eric Fail 2012

5

//sankeybuilder.com 은 시간이 지남에 따라 데이터를 업로드하고 변형을 재생할 수있는 즉시 사용할 수있는 솔루션을 제공 하므로 살펴보십시오 . 전환이 잘 작동합니다 (귀하의 질문에있는 YouTube 데모와 유사). SankeyTrend 데모를로드하면 많은 시간 슬롯 (데이터 연도)이 포함됩니다. 로드되면 (자동으로 sankeys 빌드) 시간 슬롯을 재생하기 위해 페이지의 오른쪽 상단 모서리에있는 재생 버튼을 클릭하면 시간을 일시 중지하고 다시 시작할 수도 있습니다. 데모 URL : SankeyTrend 이것이 완벽한 Sankey 다이어그램을 찾는 데 도움이 되기를 바랍니다.


4

완성도를 위해 ggalluvial패키지 도 있습니다 .ggplot2 extension 위해 충적 / Sankey 다이어그램 용 .

다음은 패키지 문서에서 가져온 예입니다.

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

reprex 패키지 (v0.2.1.9000)에 의해 2018-11-13에 생성됨


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.