【问题标题】:How to create an edgelist from a dataframe (expand, group_by?)如何从数据框创建边缘列表(展开,group_by?)
【发布时间】:2021-11-09 06:23:47
【问题描述】:

我在 R 中有一个类似于以下内容的数据框:

INSTITUTION  GROUP
University1  Group1
University1  Group1
University3  Group2
University4  Group2
University1  Group2
University3  Group3

我的目的是创建一个边缘列表,以在 igraph 中创建一个网络,其中包含各自组内机构之间所有可能的连接。这个想法是关系不会重复。它看起来像这样(我假设):

EDGE1        EDGE2       
University1  University1 # for group 1
University3  University4 # for group 2
University3  University1 # for group 2
University4  University1 # for group 2
 
# and I assume that group 3 would not have an edge represented because it is alone.

我一直在试图弄清楚如何使用 igraphtidyverse 来做到这一点,但我不确定如何去做,因为我总是以重复的配对或元素结束,例如来自 @ 的 Univerisity3 987654326@我不需要。

奖金问题!

设置好边列表后,如何限制网络图中显示的边数?例如,我想消除出现少于 10 次的所有边缘。实际数据集比较大,机构很多。

非常感谢!

【问题讨论】:

  • 大学 1 不也是独立的吗?它只是自己连接的?
  • 如果没关系,那么也许delete_vertices(connect(g, order=2), dat$GROUP)

标签: r networking igraph expand


【解决方案1】:

我真的很喜欢基本的 R 解决方案,这就是您从我这里得到的。它有点 hacky 和 ​​ad hoc,但它似乎很快就能完成工作。

out <- do.call("rbind", lapply(split(data, data$GROUP), function(d) {
   if (nrow(d) > 1) unique(do.call("rbind", combn(d$INSTITUTION, 2, simplify = FALSE)))
}))

这会按组拆分原始数据,然后在每个组内执行操作。该操作是,如果组中有不止一行,则取组成员的所有成对组合(删除重复项,尽管不应该有任何重复项)。最后,它将所有结果绑定到一个矩阵中。

要将数据集限制为出现超过 10 次的边,首先,创建一个“边 ID”,然后将边 ID 制成表格并删除所有出现次数不超过 10 次的边。

edgeID <- do.call(paste, as.data.frame(out))
tab <- table(edgeID)
out <- out[edgeID %in% names(tab)[tab > 10],,drop = FALSE]

【讨论】:

  • 非常感谢!在操作基础 R 中的数据方面,我从这个解决方案中学到了很多东西。:)
【解决方案2】:

split + make_full_graph + get.data.frame试试下面的代码

do.call(
  rbind,
  lapply(
    with(df, split(INSTITUTION, GROUP)),
    function(v) {
      make_full_graph(length(v)) %>%
        set_vertex_attr(name = "name", value = v) %>%
        get.data.frame()
    }
  )
)

给了

                from          to
Group1   University1 University1
Group2.1 University3 University4
Group2.2 University3 University1
Group2.3 University4 University1

【讨论】:

  • 非常感谢@ThomasIsCoding!这个答案很棒,因为它维护了唯一的组代码,所以很容易验证我得到了我想要的那种边缘列表。
【解决方案3】:

你可以先构造一个二分图,然后做一个所谓的bipartite projection

library(igraph)

df <- read.table(header=T,text=
"INSTITUTION  GROUP
University1  Group1
University1  Group1
University3  Group2
University4  Group2
University1  Group2
University3  Group3")

g <- graph_from_data_frame(df)

V(g)$type <- V(g)$name %in% df[,1]

igraph 使用type 顶点属性来编码哪个顶点属于二分图中的哪个分区。

现在我们可以进行投影了:

> bipartite_projection(g)
$proj1
IGRAPH 98f44c3 UNW- 3 2 -- 
+ attr: name (v/c), weight (e/n)
+ edges from 98f44c3 (vertex names):
[1] Group1--Group2 Group2--Group3

$proj2
IGRAPH ac701ec UNW- 3 3 -- 
+ attr: name (v/c), weight (e/n)
+ edges from ac701ec (vertex names):
[1] University1--University3 University1--University4
[3] University3--University4

这为我们提供了大学-大学以及两个结果图中的组-组关系。

要仅获取大学-大学关系,请使用

bipartite_projection(g, which="true")

这将为您提供在type 属性中具有用TRUE 标记的顶点的图形。在我们的例子中,这就是大学。

详情请看这里:https://igraph.org/r/html/latest/bipartite_projection.html

【讨论】:

    猜你喜欢
    • 2020-07-20
    • 2018-06-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多