r - 如何使用 R 中的 rcv 和 networkD3 包在 D3 Sankey 图的节点中添加

我正在使用 ranked-choice voting R 中的数据,并希望使用 Sankey 图绘制它(here 是一个例子)。桑基图默认为每个候选人用颜色编码的节点,但我想改为在节点内放置每个候选人的图像。

数据和设置

我有 5 位候选人:A、B、C、D 和 E,以及 27 位选民的优先排序(通过他们的 ID 标识:1、2、3、...、27)。这是我的初始数据:

rcv_data <- 

structure(list(pref_voter_id = 1:27, `1` = c("A", "B", "C", "C", 
"C", "D", "A", "C", "C", "C", "B", "C", "C", "E", "A", "B", "B", 
"A", "B", "C", "C", "C", "B", "E", "D", "B", "E"), `2` = c("C", 
"A", "A", "B", "A", "C", "E", "B", "A", "D", "C", "D", "D", "A", 
"C", "D", "C", "E", "C", "D", "B", "A", "A", "A", "B", "C", "B"
), `3` = c("B", "C", "D", "E", "B", "E", "B", "A", "B", "A", 
"E", "A", "E", "C", "E", "C", "D", "B", "D", "B", "A", "D", "C", 
"C", "E", "D", "D"), `4` = c("E", "E", "B", "A", "D", "B", "D", 
"D", "D", "B", "D", "B", "B", "D", "B", "E", "A", "D", "E", "A", 
"D", "B", "E", "B", "A", "E", "C"), `5` = c("D", "D", "E", "D", 
"E", "A", "C", "E", "E", "E", "A", "E", "A", "B", "D", "A", "E", 
"C", "A", "E", "E", "E", "D", "D", "C", "A", "A")), row.names = c(NA, 
-27L), class = c("tbl_df", "tbl", "data.frame"))

第 1、2、3、4、5 列对应每个选民的“第一选择”、“第二选择”、...、“第五选择”。

我正在使用 networkD3用于在 R Markdown HTML 文档中创建 Sankey 图的包。将数据转换为适合 networkD3::sankeyNetwork 的格式函数(即在节点和边方面),需要使用 rcv 进行一些争论包和 rcv::makde_d3list功能:

library(dplyr)
library(tidyr)
library(rcv)
library(networkD3)

rcv_data %>%
  pivot_longer(2:6, names_to = "vote_rank", values_to = "candidate") %>%
  rcv::rcv_tally(n_winners = 0) %>% # n_winners is 0 for the diagram to display an extra round
  filter(candidate != "NA") %>% # I don't want "NA" to appear in the diagram
  rcv::make_d3list() %>%
  {networkD3::sankeyNetwork(Links = .$values, Nodes = .$names, 
                            Source = "source", Target = "target",
                            Value = "value", NodeID = "candidate", 
                            units = "voters", fontSize = 12, nodeWidth = 50)}

需要帮助

现在,我有一些文件 A.jpg、B.jpg、C.jpg、D.jpg 和 E.jpg,其中包含 5 位候选人的照片。我希望节点包含候选人的这些照片,而不是简单地进行颜色编码,即我想要候选人 C 的图像而不是深蓝色节点,而不是深橙色节点我想要候选人 A 的图像等。

我怀疑有两种途径可以解决问题:

  1. networkD3::sankeyNetwork仅提供更改节点颜色的功能,但使用其他 R 包可能还有其他解决问题的方法?我知道 visNetwork package 允许将图像添加为节点,但它似乎不支持 Sankey 图(?)。
  2. htmlwidgets::onRender函数使人们能够通过将图形保存到对象中来向图形添加额外的 JavaScript 代码,例如graph <- [code above] , 然后像 htmlwidgets::onRender(graph, JS(...)) 这样写 JavaScript .但是,我不确定 ... 中应该包含什么部分 - 如何访问节点并将它们按组附加到适当的图像?

最佳答案

这里是一个添加图像到SVG中每个节点组的例子。仍有许多问题需要解决,例如图像的适当大小和位置,但这为添加它们提供了基础...

library(networkD3)
library(htmlwidgets)
    
nodes <- data.frame(name = c("a", "b", "c", "d"))
links <- data.frame(source = c(0, 0, 1, 1),
                    target = c(2, 3, 2, 3),
                    value = c(1, 3, 2, 4)
                    )

sn <- sankeyNetwork(Links = links, Nodes = nodes, Source = "source",
                    Target = "target", Value = "value", NodeID = "name")
    
js <- 
  '
    function(el) { 
      d3.select(el)
        .selectAll(".node")
        .append("image")
        .attr("xlink:href", d => "https://pngimg.com/uploads/letter_" + d.name + "/letter_" + d.name + "_PNG4.png")
    }
  '

htmlwidgets::onRender(sn, js)
    
    
    

关于r - 如何使用 R 中的 rcv 和 networkD3 包在 D3 Sankey 图的节点中添加图像?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63862385/

相关文章:

google-cloud-platform - 接受 Google 帐户转移请求时如何解决消息 "T

python - 无法通过 Pip 安装 TensorFlow

scala - 在读取 CSV 时,最后一列在 Spark、Scala 中显示为 Null

python-3.x - 安装 github 子模块时,诗歌安装失败并显示 [CalledProce

linux - 用 n 步旋转文本文件中的行

visual-studio - VS代码-OSS : Downloading files and f

python - 使用 Python 的双向方差分析

python - 在使用 pyspark 和预定义的结构模式读取嵌套的 JSON 时,如何将缺失的列

python - open() 中的整数文件描述符 "0"

variables - 如何在 Pyomo 模型中设置决策变量的初始值