Javascript R networkD3包:forceNetwork()着色

Javascript R networkD3包:forceNetwork()着色,javascript,r,d3.js,networkd3,Javascript,R,D3.js,Networkd3,我非常喜欢这个网络的外观: 资料来源: 每个扇区有多种颜色,其中每种颜色表示网络中与其他节点相距足够远的节点的某些不同部分 但是,在任何一个特定的扇区中,我不喜欢src节点与目标节点的颜色是一样的,因此我问了一个问题()如何区分这两种颜色 现在有没有一种方法可以让我在这个代码上进行扩展,以重新获得多个颜色方案(以区分各个扇区),同时保留nicesrc/target的颜色差异?代码如下: # Load package library(networkD3) library(dplyr) # to

我非常喜欢这个网络的外观:

资料来源:

每个扇区有多种颜色,其中每种颜色表示网络中与其他节点相距足够远的节点的某些不同部分

但是,在任何一个特定的扇区中,我不喜欢
src
节点与
目标节点的颜色是一样的,因此我问了一个问题()如何区分这两种颜色

现在有没有一种方法可以让我在这个代码上进行扩展,以重新获得多个颜色方案(以区分各个扇区),同时保留nice
src
/
target
的颜色差异?代码如下:

# Load package
library(networkD3)
library(dplyr) # to make the joins easier

# Create fake data
src <- c("A", "A", "A", "A",
         "B", "B", "C", "C", "D")
target <- c("B", "C", "D", "J",
            "E", "F", "G", "H", "I")
networkData <- data.frame(src, target, stringsAsFactors = FALSE)

nodes <- data.frame(name = unique(c(src, target)), stringsAsFactors = FALSE)
nodes$id <- 0:(nrow(nodes) - 1)


# create a data frame of the edges that uses id 0:9 instead of their names
edges <- networkData %>%
   left_join(nodes, by = c("src" = "name")) %>%
   select(-src) %>%
   rename(source = id) %>%
   left_join(nodes, by = c("target" = "name")) %>%
   select(-target) %>%
   rename(target = id)

edges$width <- 1

# make a grouping variable that will match to colours
nodes$group <- ifelse(nodes$name %in% src, "lions", "tigers")


ColourScale <- 'd3.scaleOrdinal()
            .domain(["lions", "tigers"])
           .range(["#FF6900", "#694489"]);'

forceNetwork(Links = edges, Nodes = nodes, 
             Source = "source",
             Target = "target",
             NodeID ="name",
             Group = "group",
             Value = "width",
             opacity = 0.9,
             zoom = TRUE,
             colourScale = JS(ColourScale))
#加载包
图书馆(网络3)
库(dplyr)#使连接更容易
#创建假数据
src%
重命名(目标=id)

边$width决定颜色的是
节点
数据框中的
列。您可以为每个节点设置
group
值(手动或其他),并且
networkD3
将根据调色板为每组节点着色

例如

edges <- read.table(header = T, text = '
source target width
0      1     1
0      2     1
0      3     1
0      4     1
1      5     1
1      6     1
2      7     1
2      8     1
3      9     1
')

nodes <- read.table(header = T, text = '
name id  group
A    0   panther
B    1   leopard
C    2   tiger
D    3   lion
J    4   panthercub
E    5   leopardcub
F    6   leopardcub
G    7   tigercub
H    8   tigercub
I    9   lioncub
')

forceNetwork(Links = edges, Nodes = nodes, 
             Source = "source",
             Target = "target",
             NodeID ="name",
             Group = "group",
             Value = "width",
             opacity = 0.9,
             zoom = TRUE,
             colourScale = JS("d3.scaleOrdinal(d3.schemeCategory10);"))

edges重新阅读您的问题和回答后,我想您真正想知道的是。。。如何将数据分组。定义集群后,可以将
节点
数据框中每个节点的组值设置为其集群的名称/id,然后
网络3
将相应地为其着色

进一步讨论您的问题,不清楚您希望如何同时组合“不同颜色的源节点和目标节点”“根据集群的颜色节点”。。。这些目标显然是冲突的,因为集群同时包含源节点和目标节点。您的问题的另一个问题是,在这些类型的网络中,节点可能同时是源节点和目标节点,因此您必须更清楚地了解这些节点的颜色。我可以假设您将“目标”节点定义为仅链接到另一个节点的节点(从技术上讲,节点是源节点还是目标节点取决于节点之间链接的方向),但情况并非如此(我可以想象您可能会有其他解释)

要进行聚类,您需要查看
igraph
包及其众多聚类函数。例如

使用
networkD3
中包含的Les Misérables数据,让我们回溯到只有一个包含源字符和目标字符的两列数据帧

library(igraph)
library(networkD3)

data(MisLinks)
data(MisNodes)

lesmis <- data.frame(source = MisNodes$name[MisLinks$source + 1], 
                     target = MisNodes$name[MisLinks$target + 1],
                     stringsAsFactors = F)
现在,如果您想使“目标”节点(只有一个链接的节点)也具有不同的颜色,您可以找出哪些节点在源和目标列表中只出现一次,并将其在
节点
数据框中的组值设置为唯一的值

allnodes <- c(lesmis$links$source, lesmis$links$target)
targetids <- allnodes[!duplicated(allnodes) & ! duplicated(allnodes, fromLast = T)]
lesmis$nodes$group[targetids + 1] <- 'target'

forceNetwork(Links = lesmis$links, Nodes = lesmis$nodes, 
             Source = 'source', Target = 'target', 
             NodeID = 'name', Group = 'group', opacity = 1)

所有节点正如您所提到的,此解决方案需要在
节点
数据框的
列中手动设置值。然而,我想问的是,是否有一种方法可以自动化这个过程,让源代码自动为您着色网络的各个部分。在更大的网络中,这将是一个巨大的优势(即,它将非常好且可扩展)。不过我喜欢你的答案,因为它显示了着色的概念从何而来。你可以对节点数据帧进行预处理,以任意方式设置组值。如果您给出一个特定的用例,我可能会帮助您做到这一点,但是在不知道具体细节的情况下,几乎有无限的可能性。
allnodes <- c(lesmis$links$source, lesmis$links$target)
targetids <- allnodes[!duplicated(allnodes) & ! duplicated(allnodes, fromLast = T)]
lesmis$nodes$group[targetids + 1] <- 'target'

forceNetwork(Links = lesmis$links, Nodes = lesmis$nodes, 
             Source = 'source', Target = 'target', 
             NodeID = 'name', Group = 'group', opacity = 1)