90

我正在尝试使用 R 中的桑基图可视化我的数据流。

我发现这篇博客文章链接到一个生成桑基图的 R 脚本;不幸的是,它非常原始且有些受限(请参阅下面的示例代码和数据)。

有谁知道其他更发达的脚本——甚至可能是一个包?我的最终目标是通过图表组件的相对大小来可视化数据流和百分比,就像在Sankey Diagrams 的这些示例中一样。

在 r-help list 上发布了一个类似的问题,但是两周后没有任何回复,我在 stackoverflow 上试试运气。

谢谢,埃里克

PS。我知道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")

使用上述代码生成的桑基图,使用上述代码生成的桑基图

4

10 回答 10

66

该图可以通过networkD3包创建。它允许您创建交互式桑基图。在这里你可以找到一个例子。我还添加了一个屏幕截图,以便您了解它的外观。

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

在此处输入图像描述

于 2014-03-18T14:13:12.397 回答
45

我创建了一个包(riverplot),与 Sankey 函数相比,它的功能略有不同,但功能重叠,并且可以生成如下图:

在此处输入图像描述

于 2014-03-03T13:35:13.217 回答
39

如果你想用 R 来做,你最好的出价似乎是@Roman 的建议——破解SankeyR函数。例如 - 下面是我的快速修复 - 只需垂直定位标签,稍微偏移它们并减少输入引用的字体以使其看起来更好一点。此修改仅更改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)

在此处输入图像描述

我不是三角学的高手,但这确实是改变箭头方向所需要的。在我看来,这将是理想的——如果你可以调整松散的箭头,使它们水平定向而不是垂直定向。否则,为什么我的解决方案解决了标签方向的问题,它并没有使图表更具可读性......

于 2012-04-04T13:54:20.163 回答
25

除了rCharts 之外,现在还可以使用googleVis(版本 >= 0.5.0)在 R 中生成桑基图。例如,这篇文章描述了使用 googleVis 生成下图: 在此处输入图像描述

于 2014-11-04T00:40:37.923 回答
16

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

在此处输入图像描述

于 2017-04-25T12:30:53.900 回答
12

plotly与包具有相同的功能networkD3示例链接)。

在此处输入图像描述

于 2017-07-28T03:15:05.920 回答
7

为了完整起见,还有用于冲积/桑基图的ggalluvial包。ggplot2 extension

这是从包的文档中获取的示例

# 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 日创建

于 2018-11-14T00:24:44.973 回答
6

这些定义来看,这个函数,就像并行集图一样,缺乏拆分和合并流的能力(即通过多个转换)。

由于桑基图是有向加权图,因此像qgraph这样的包可能很有用。

如果您按降序对损失进行排序,则该SankeyR函数会提供更清晰的标签,因为文本更靠近箭头而不重叠。

于 2012-04-03T23:16:34.603 回答
5

看看//sankeybuilder.com,因为它提供了一个随时可用的解决方案,您可以随时间上传数据和播放变化。过渡效果很好(类似于您问题中的 youtube 演示)。如果您加载 SankeyTrend 演示,它包含许多时间段(数据年数)。加载后(自动构建sankeys),单击页面右上角的播放按钮播放时隙,您甚至可以暂停和恢复时间。演示网址在这里:SankeyTrend希望这有助于您寻求完美的 Sankey 图。

于 2016-03-21T12:26:28.240 回答
1

刚刚开源了一个使用冲积图可视化工作流程阶段的包。由于使用冲积形式时保留了历史,因此边缘没有任何交叉。

https://github.com/claytontstanley/shiny.alluvial

在此处输入图像描述

于 2017-10-03T21:46:40.623 回答