【问题标题】:How do I generate a raw count of how many times a set of individuals is connected to an individual?如何生成一组个人与个人相关联的次数的原始计数?
【发布时间】:2021-12-13 20:44:30
【问题描述】:

假设我有以下数据集:

name1 <- c("John", "Mary", "Anne", "Joe", "David")
name2 <- c("Mary", "John", "Linda", "David", "Joe")

df <- data.frame(name1, name2)

> df
  name1 name2
1  John  Mary
2  Mary  John
3  Anne Linda
4   Joe David
5 David   Joe

name3 <- c("Kate", "Kate", "Kate", "Roger", "Roger", "Patty", "Patty")
name4 <- c("Mary", "John", "Bob", "David", "Joe", "Anne", "Linda")

df2 <- data.frame(name3, name4)

> df2
  name3 name4
1  Kate  Mary
2  Kate  John
3  Kate   Bob
4 Roger David
5 Roger   Joe
6 Patty  Anne
7 Patty Linda

名称相互配对时被视为“集合”。所以“约翰和玛丽”是一对,因为还有“玛丽和约翰”。

我想查看 df 中的每一对(John & Mary 和 Joe & David)有多少次与 df2 中的个人相关联。所以在这个玩具示例中,John 和 Mary 都与 Kate 相关联,而 David 和 Joe 都与 Roger 相关联。如果 John 和 Mary 也与 Roger 有关联,那么他们将是一个人两次的集合,因此在 No. of times 下,它将是“2”。

对于当前的 dfs,我想要一个显示:

Pair              No. of times
John – Mary       1
Roger – Joe       1

有一些社交网络包可以直观地展示这些人的联系方式,但我只是在寻找一个显示计数数量的简单表格。

【问题讨论】:

    标签: r dataframe data-manipulation


    【解决方案1】:

    这是一个使用igraph 包的方法。首先,我们从主 data.frame 创建一个图表,保持在“集合”上(那些顶点由多个节点边缘连接)。然后我们通过给它们“main”的边缘属性来标记那些是我们感兴趣的。然后我们将它们与其余数据连接起来。

    gg1 <- graph_from_data_frame(df, directed = FALSE)
    gg1 <- delete_edges(gg1, which(!which_multiple(gg1)))
    E(gg1)$main <- TRUE
    
    gg2 <- graph_from_data_frame(df2, directed = FALSE)
    
    ggfull <- union(gg1, gg2)
    
    # (optional) preview results
    E(ggfull)$color <- ifelse(!is.na(E(ggfull)$main), "red", "grey")
    plot(ggfull)
    

    现在这里有一个辅助函数,它将遍历图形并找到其中一条边来自“主”集合的所有“三角形”。

    find_main_trios <- function(g) {
      tricnt <- numeric(gsize(g))
      triset <- triangles(g)
      for(i in seq(1, length(triset), by=3)) {
        edges <- c(
          E(g)[triset[i]%--%triset[i+1]], 
          E(g)[triset[i+1]%--%triset[i+2]],
          E(g)[triset[i]%--%triset[i+2]]
        )
        for (edge in edges)
          if (!is.na(E(g)[edge]$main)) {
            tricnt[edge]  = tricnt[edge] + 1
          }
      }
      do.call("rbind", lapply(which(tricnt>0), function(i) {
        names <- V(g)[inc(i)]$name
        data.frame(name1=names[1], name2=names[2], count=tricnt[i], edgeid=i)
      }))
    }
    

    大部分工作由triangles() 函数完成,该函数查找三个节点的集合,这些节点都相互连接。然后,我们需要确保每个三角形都包含我们感兴趣的第一个 data.frame 中的一个集合。函数的最后一个投标只是将所有内容整理到一个 data.frame 中。所以当我们运行它时,我们得到

    find_main_trios(ggfull)
    #   name1 name2 count edgeid
    # 1   Joe David     1      5
    # 2  John  Mary     1      9
    

    这给出了您所追求的摘要。

    【讨论】:

    • 当我为我的示例数据执行union(gg1, gg2) 时,我得到一个 ggfull 对象,它是一个列表,而不是 igraph。如何防止这种情况发生?
    • 我意识到我有另一个使用union 的包,所以我只使用了igraph::union。谢谢!!
    猜你喜欢
    • 2014-11-23
    • 1970-01-01
    • 2012-09-27
    • 1970-01-01
    • 2011-07-13
    • 2021-05-15
    • 2012-05-21
    • 1970-01-01
    • 2014-01-04
    相关资源
    最近更新 更多