【问题标题】:Creating an adjacency list from a data.frame从 data.frame 创建邻接列表
【发布时间】:2010-11-10 00:36:13
【问题描述】:

我有一个包含 2 列的 data.frame:节点 A,节点 B。框架中的每个条目都意味着节点 A 和 B 之间的图中的一条边。

必须有一个很好的单行来将此 data.frame 转换为邻接列表。有什么提示吗?

【问题讨论】:

    标签: r igraph


    【解决方案1】:

    既然你标记了这个,那么使用内置功能怎么样?

    > g <- graph.data.frame( edges )
    > adjlist <- get.adjedgelist(g)
    

    唯一需要注意的是顶点索引为零,这将随着 igraph 0.6 的变化而变化。

    【讨论】:

      【解决方案2】:
      > edges <- data.frame(nodea=c(1,2,4,2,1), nodeb=c(1,2,3,4,5))
      
      > attach(edges)
      
      > tapply(nodeb,nodea,unique)
      
      $`1`
      [1] 1 5
      
      $`2`
      [1] 2 4
      
      $`4`
      [1] 3
      

      【讨论】:

      • 出于某种奇怪的原因,R tapply(as.character(nodeb),as.character(nodea),unique) 将我的超长表格(100,000 行)转换为列表比 tapply(nodeb,nodea,unique) 快 100 倍!!!
      【解决方案3】:

      又快又脏……

      > edges <- data.frame(nodea=c(1,2,4,2,1), nodeb=c(1,2,3,4,5))
      
      > adjlist <- by(edges, edges$nodea, function(x) x$nodeb)
      
      > for (i in as.character(unique(edges$nodea))) {
      +   cat(i, ' -> ', adjlist[[i]], '\n')
      + }
      
      1  ->  1 5
      2  ->  2 4
      4  ->  3
      
      > adjlist
      edges$nodea: 1
      [1] 1 5
      ------------------------------------------------------------
      edges$nodea: 2
      [1] 2 4
      ------------------------------------------------------------
      edges$nodea: 4
      [1] 3
      

      【讨论】:

      • 咕。是的。这是一个完美的单线。奇怪的是,我的 for 循环解决方案的运行速度是 by() 的两倍。
      • 确实,当您的表有 50,000 长(约 5000 个标识符)时,它并不是很快。有更快的替代品吗?
      【解决方案4】:

      你甚至会如何在 R 中表示邻接表?它需要一组相邻节点的可变大小列表;那么你必须使用 list();但是在 R 中使用它有什么好处呢?

      我可以想到类似 sapply 的函数的蹩脚技巧,但它们对每个节点进行线性扫描。但是玩了 1 分钟,这里是:pairlists 的列表,其中每对的第二项是邻接列表。输出比数据结构更疯狂。

      > edgelist=data.frame(A=c(1,1,2,2,2),B=c(1,2,2,3,4))
      > library(plyr)
      > llply(1:max(edgelist), function(a) list(node=a, adjacents=as.list(edgelist$B[edgelist$A==a])))
      [[1]]
      [[1]]$node
      [1] 1
      
      [[1]]$adjacents
      [[1]]$adjacents[[1]]
      [1] 1
      
      [[1]]$adjacents[[2]]
      [1] 2
      
      
      
      [[2]]
      [[2]]$node
      [1] 2
      
      [[2]]$adjacents
      [[2]]$adjacents[[1]]
      [1] 2
      
      [[2]]$adjacents[[2]]
      [1] 3
      
      [[2]]$adjacents[[3]]
      [1] 4
      
      
      
      [[3]]
      [[3]]$node
      [1] 3
      
      [[3]]$adjacents
      list()
      
      
      [[4]]
      [[4]]$node
      [1] 4
      
      [[4]]$adjacents
      list()
      

      【讨论】:

      • Brendan - 标准方式(至少从 igraph 的角度来看)是一个顶点列表 - 每个列表元素都是相邻顶点的向量。
      猜你喜欢
      • 2018-04-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多