r - igraph 基于属性的相邻边
问题描述
对于每个顶点,我对基于条件的相邻边的数量感兴趣。在以下示例中,条件是具有不同的性别。
例子:
library(igraph)
library(ggraph)
library(tidyverse)
nodes <- tibble(id = 1:4,
gender = c("M", "F", "F", "M"),
names = c("Bob", "Allie", "Mary", "Johnathon"))
edges <- tibble(from = c(1, 3, 2, 4, 1, 2, 1, 4),
to = c(2, 2, 4, 1, 3, 1, 4, 3))
network <- graph_from_data_frame(d = edges, vertices = nodes, directed = TRUE)
ggraph(network) +
geom_edge_link(arrow = arrow(length = unit(4,
'mm')),
start_cap = circle(4, 'mm'),
end_cap = circle(4, 'mm')) +
geom_node_text(aes(label = names)) +
theme_graph()
期望的结果:
id name adjacent_edges
1 Bob 1
2 Allie 1
3 Mary 2
4 Johnathon 1
解决方案
这是一种将基础 R 与 相结合的方法igraph
:
nodes %>%
mutate(adjacent_edges = colSums(as.matrix(outer(gender, gender, `!=`) * as_adj(network)) != 0))
# A tibble: 4 x 4
# id gender names adjacent_edges
# <int> <chr> <chr> <dbl>
# 1 1 M Bob 1
# 2 2 F Allie 1
# 3 3 F Mary 2
# 4 4 M Johnathon 1
这里
outer(gender, gender, `!=`)
TRUE
当性别不同时构建一个包含条目的矩阵,而as_adj(network))
是通常的图邻接矩阵. 然后他们的产品将在我们想要的时候有非零条目 - 在连接节点具有不同性别的情况下。对这些情况求和会得到预期的结果。
这是另一个,更长但也更透明:
edges %>% full_join(nodes, by = c("from" = "id")) %>%
full_join(nodes, by = c("to" = "id"), suff = c(".from", ".to")) %>%
group_by(to, names.to) %>% summarise(adjacent_edges = sum(gender.to != gender.from)) %>%
rename(id = to, name = names.to)
# A tibble: 4 x 3
# Groups: id [4]
# id name adjacent_edges
# <dbl> <chr> <int>
# 1 1 Bob 1
# 2 2 Allie 1
# 3 3 Mary 2
# 4 4 Johnathon 1
在这种情况下,我们从边列表开始,然后两次添加节点列表:一次是关于from
边的节点信息,一次是关于to
边的节点信息,在同一行中。然后通过对所有不同性别的邻居求和来总结数据。
推荐阅读
- docker - 如何在没有“无安装候选”错误的情况下在 openjdk:11 docker 基础映像上 apt-get install firefox?
- php - 将事件处理程序附加到在循环内创建的表单
- html-email - 自定义模板和 Gmail IOS 客户端的 Mailchimp 问题
- javascript - 如何使用cheerio和fs将网站转换为pdf
- python - 通过字节串中的套接字加载图像在python中需要永远
- node.js - 压缩文件流node.js
- swift - 如何将项目 HStack 与 VStack SwiftUI 对齐
- python - 如何用从另一个数组中采样的数字填充数组的切片?
- linux - 编写 BASH 命令以打印范围
- android - 快速滚动 RecyclerView 会破坏项目放置