R networkD3:单击操作以显示来自节点数据框的信息

R networkD3: click action to show information from node data frame

我有这个代码:

library(networkD3)

# Load data
data(MisLinks)
data(MisNodes)

new.nodes <- MisNodes
new.nodes$var1 <- runif(nrow(MisNodes),1,2)
new.nodes$var2 <- runif(nrow(MisNodes),1,2)

# Some script to show the node index in the new.nodes data frame
script <- 'alert("row: " + (d.index + 1));'

# Plot
forceNetwork(Links = MisLinks, Nodes = new.nodes,
             Source = "source", Target = "target",
             Value = "value", NodeID = "name",
             Group = "group", opacity = 0.8,
             clickAction = script)

我想出了通过询问d.index + 1来获取节点数据框的行号。但是我想显示一个包含所有节点信息的 table,就像这样(也许格式更好):

    name group size     var1     var2
1 Myriel     1   15 1.501311 1.053062

这需要 JavaScript 访问节点数据框,因为我对 JavaScript 知之甚少,我不知道如何请求此数据。

不幸的是,我认为即使不是不可能,也不容易做到。似乎只有 forceNetwork 与节点相关的参数在底层代码中被初始化:

考虑例如:

script <- 'alert("row: "     + (d.index + 1) + 
                 ", name: "  + d.name + 
                 ", group: " + d.group + 
                 ", size: "  + d.nodesize + 
                 ", var1: "  + d.var1)'

# Plot
d3 <- forceNetwork(Links = MisLinks, Nodes = new.nodes,
             Source = "source", Target = "target",
             Value = "value", NodeID = "name", 
             Nodesize = "size",
             Group = "group", opacity = 0.8,
             clickAction = script)

print(d3)

正如您在单击下面的节点时看到的那样,var1 未定义。注意我在函数调用中添加了 Nodesize 参数,现在可以通过脚本 d.nodesize(而不是 d.size)访问它。在本例中,group 变量和参数的名称相同,因此这里没有区别。但是,NodeID 显然是由我发现不一致的指定名称访问的。

保存即可看到生成的源码:

saveNetwork(d3, file = "test.html")

你可以通过查看它注意到,你打算输出的值没有存储在文件中。

编辑:

根据您自己的建议,这有点接近解决方法:

new.nodes$newname  <- with(new.nodes, paste(", name: ", name, ", group: ", group, 
                                ", size: ", size, ", var1: ", var1,
                                ", var2: ", var2))

newscript <- 'alert("row: " + (d.index + 1) + d.name)'

forceNetwork(Links = MisLinks, Nodes = new.nodes,
             Source = "source", Target = "target",
             Value = "value", NodeID = "newname", Nodesize = "size",
             Group = "group", opacity = 0.8, opacityNoHover = 0,
             clickAction = newscript)

因此,只需按您希望显示的方式格式化字符串即可。缺点是 name/NodeIDs 很长。正如您所看到的,NodeID 在 JS 端总是被称为 name

发生这种情况的原因是 forceNetwork 函数在它传递给 JavaScript 的数据框中删除了所有不必要的 variables/columns,这通常是有利的,但不是这个案例。您可以通过保存 forceNetwork 创建的 htmlwidget 对象来解决它,然后添加回您需要访问的变量,然后 'print'/显示它。

library(networkD3)

data(MisLinks)
data(MisNodes)

MisNodes$var1 <- runif(nrow(MisNodes),1,2)

script <- 'alert("var1: " + (d.var1));'

fn <- forceNetwork(Links = MisLinks, Nodes = new.nodes, Source = "source", 
                   Target = "target", Value = "value", NodeID = "name", 
                   Group = "group", opacity = 0.8, clickAction = script)

fn$x$nodes$var1 <- MisNodes$var1

fn


这也可以完成 with/for 多个变量,例如...

library(networkD3)

data(MisLinks)
data(MisNodes)

MisNodes$var1 <- runif(nrow(MisNodes),1,2)
MisNodes$var2 <- runif(nrow(MisNodes),1,2)

script <- 'alert("var1: " + d.var1 + "\n" + "var2: " + d.var2);'

fn <- forceNetwork(Links = MisLinks, Nodes = new.nodes, Source = "source", 
                   Target = "target", Value = "value", NodeID = "name", 
                   Group = "group", opacity = 0.8, clickAction = script)

fn$x$nodes$var1 <- MisNodes$var1
fn$x$nodes$var2 <- MisNodes$var2

fn