在R中使用forceNetwork变得疯狂:没有显示边缘

时间:2015-07-02 21:23:41

标签: r plot htmlwidgets networkd3

我一直试图在R中使用 networkD3 包绘制网络一周。 simpleNetwork函数正常工作,但它不能很好地控制图形的外观。 forceNetwork函数用于此目的:显示具有丰富视觉特征的图形。

我遇到的问题几乎与this问题中的问题相同。我仔细阅读了包文档,并尝试了上述线程中提出的解决方案,没有运气:我得到的是一个没有边连接它们的节点云。

这是data.frame s:

EDG

Gene1 Gene2 Prob
  1    22    3
  2    22    6
  3    22    6
  4    22    9
  5    22    3
  6    22    4
  7    22    8
  8    22    4
  9    22    6
 10    22    8
 11    22    6
 12    22   10
 13    22    6
 14    22    3
 15    22    6
 16    22    6
 17    22    0
 18    22    4
 19    22    6
 20    22    4

VERT

Symbol Chr Expr
   1   21    9
   2   17   10
   3   17    0
   4   20    0
   5    6    9
   6    5   11
   7   12    0
   8    1   20
   9   17   11
  10   17    7
  11   17   11
  12   10    0
  13   17    0
  14    7    7
  15   17    6
  16   17    0
  17    2    5
  18    5   10
  19   17   10
  20   17    9
  21   12    4
  22    3    2

嗯,这导致上面提到的没有边缘的节点云。如果我改变符号'同样的事情带有实际标签的列我放在节点上(根据包的要求,遵守链接表的顺序)。

请注意,该软件包说明了此函数与this示例的使用,如果您打开使用的数据集( MisLinks,MisNodes ),它们的内容与我的内容相同,除了用于节点的标签。运行那个相同的例子有效;运行我的数据不会。

这是我用来绘制网络的函数:

forceNetwork( Links = edg, Nodes = vert, Source = "Gene1", Target = "Gene2", 
              Value = "Prob", NodeID = "Symbol", Group = "Chr", opacity = 0.7,
              colourScale = "d3.scale.category20b()", Nodesize = "Expr", zoom = T,
              legend = T )

每个其他属性都正确显示(节点大小,图例,颜色),但我一直看不到边缘。我的数据集中某处肯定存在错误,我无论如何都找不到。

4 个答案:

答案 0 :(得分:5)

我遇到了同样的问题(simpleNetwork正常工作,forceNetwork首先只显示节点和没有边缘,然后根本没有显示。

问题(当你“重建从0开始编号的数据帧”时,你可能会解决这个问题)是原始的链接数据edg,从1开始而不是0?

networkD3文档http://christophergandrud.github.io/networkD3/有此注释:

  

注意:您可能习惯于R的基于1的编号(即从R开始计数从1开始)。但是,networkD3图是使用JavaScript创建的,它是基于0的。因此,您的数据链接需要从0开始。

重新。不正确的数据类型,我最初认为可能是问题,我测试了所有不同的列(NodeID的因子变量除外)as.numeric vs as.integer - 但现在已经将我的数据更正为0基于而不是基于1,我的forceNetwork显示正常使用任一数据类型。

希望这有帮助!

答案 1 :(得分:2)

我刚刚在自己的forceNetwork中解决了同样的问题。事实证明,我创建的边缘数据框(从iGraph导出)具有character种类型,而不是int种类型。使用as.numeric()将边缘“从'和'转换为'列解决了问题,并且链接正确绘制。

我希望这会有所帮助。

关于,

威尔

答案 2 :(得分:0)

从技术上讲,即使解决了其他可能的问题(例如for<'a>// Emulating `type Type<'a>` by moving `'a` to the trait. trait Apply<'a> { type Type; } struct Plain<T>(std::marker::PhantomData<T>); impl<'a, T> Apply<'a> for Plain<T> { type Type = T; } struct Ref<T: ?Sized>(std::marker::PhantomData<T>); impl<'a, T: ?Sized + 'a> Apply<'a> for Ref<T> { type Type = &'a T; } struct S<A: for<'a> Apply<'a>> { f: Box<for<'a> Fn(<A as Apply<'a>>::Type) -> i32>, } impl<A: for<'a> Apply<'a>> S<A> { fn call<'a>(&self, a: <A as Apply<'a>>::Type) { println!("Return {:?}", (self.f)(a)); } } fn create<A: for<'a> Apply<'a>>( f: Box<for<'a> Fn(<A as Apply<'a>>::Type) -> i32>, ) -> S<A> { S { f } } fn helper() { let x = create::<Ref<i32>>(Box::new(|x: &i32| *x * 2)); let arg = 333; x.call(&arg); } fn main() { helper(); } 是非数字的),示例数据也无法工作的原因是因为您引用了一个节点{{ edg$Gene1数据中的1}},用“基于0的索引”表示指向edg$Gene2数据帧的第23行,该行不存在。

正如已经指出的,这可能是因为它在基于1的索引中并且应该进行转换,这很容易做到

22

或者,一个人可能打算引用另一个节点,无论出于何种原因,该节点都未将其放入edg数据帧中,在这种情况下,该节点将需要添加到vert中数据框,可以轻松地(例如)...

edg$Gene1 <- edg$Gene1 - 1
edg$Gene2 <- edg$Gene2 - 1

您可以使用类似...的方法来测试是否引用了vert数据中不存在的vert数据中的节点。

vert <- rbind(vert, c(23,1,1))

应返回edj。如果没有,那就出了问题。

您可以使用以下命令确定vert数据中不存在的哪些节点被引用...

all(unique(c(edg$Gene1, edg$Gene2)) %in% (1:nrow(vert) - 1))
# [1] FALSE

完全可复制的示例,将TRUE中的索引调整为“从0开始”

edg


完全可复制的示例,其中将节点添加到vert

unique(c(edg$Gene1, edg$Gene2))[which(!unique(c(edg$Gene1, edg$Gene2)) %in% (1:nrow(vert) - 1))]
# [1] 22

答案 3 :(得分:0)

我遇到了相同的问题,但是通过将源和目标的因子级别设置为与节点名称一致,然后再转换为数字,来解决此问题:

edg$Gene1<-factor(edg$Gene1,levels=vert$Symbol)
edg$Gene2<-factor(edg$Gene2,levels=vert$Symbol)
edg$source<-as.numeric(edg$Gene1)-1
edg$target<-as.numeric(edg$Gene2)-1

以使源向量和目标向量具有一致的因子水平作为节点名称(vert$Symbol),然后

forceNetwork( Links = edg, Nodes = vert, Source = "source", Target = "target", 
          Value = "Prob", NodeID = "Symbol", Group = "Chr", opacity = 0.7,
          colourScale = "d3.scale.category20b()", Nodesize = "Expr", zoom = T,
          legend = T )

为我工作。

希望这会有所帮助。