r - 如何转换二分网络并使用一级节点属性作为 igraph (R) 中二级节点的边权重
问题描述
我现在正在尝试将二分二模图转换为其单模表示。问题是我想将节点属性从双模图保存到单模表示。例如,数据框由以下给出:
Person EventLocation DurationEvent
Peter Bar 90
Jack Bar 90
Franz Train 20
Franz Bar 90
Laurie Train 20
Jack Train 20
...
现在我想在 Person 和 EventLocation 列上使用 igraph 函数 bipartite_projection() 来获取人员网络,但我看不到如何预先保护可能转移到 Person 之间的边权重的附加节点属性(持续时间),例如带有权重的 Peter-Jack 90 或 Franz-Laurie 体重 20。
编辑:为了更精确,我添加了最后一行。边缘“Jack-Franz”现在对应于 90+20 = 110。但基本上我的问题只是与如何实现 bipartite_projection 相关,它将二分 igraph 网络的节点属性传输到单模式中的相应边缘属性igraph 网络。
编辑 2:我刚刚添加了另一个示例。首先,我在人员之间创建一个网络,然后我想将预算信息添加到人员边缘,这意味着两者吸引了多少项目预算(仅来自不同独特项目的预算总和作为权重)。然后我想做一些进一步的加权中心性计算:
person_id <- c("X","Y","Z","Q","W","E","R","X","Y")
project <- c("a","b","c","a","a","b","c","b","a")
budget <- c(100,200,300,100,100,200,300,200,100)
employ.data <- data.frame(person_id, project, budget)
View(employ.data)
sna.complete.list <- employ.data
sna.list.complete.igraph.calc <- graph.data.frame(sna.complete.list)
V(sna.list.complete.igraph.calc)$type <- V(sna.list.complete.igraph.calc)$name%in%sna.complete.list$person_id
sna.list.complete.igraph.calc.one <- try(bipartite.projection(sna.list.complete.igraph.calc, type=V(sna.list.complete.igraph.calc)$type))
sna.statistics.persons <- sna.list.complete.igraph.calc.one[[2]]
plot.igraph(sna.statistics.persons)
EDIT3:我尝试重新表达我的担忧:
总体目标:得到一个加权图(节点之间的边值用一些值加权)
大纲/数据:
参与预算规模不同的不同项目的人员数据
将二分连接图(People-Project)转换为单模-People-People-graph
使用预算大小作为人与人之间边缘的权重。
但是对于两个人来说,这个价值应该只占参与独特项目的总和。因此,如果 A 和 B 仅通过预算大小为 100 的项目 x 连接,则边权重应为 100。如果他们还参与了另一个值为 20 的项目,则结果应为 120,以此类推。
我尝试在使用 bipartite.projection 期间传输此信息,但之后失败或无法实施此信息。
解决方案
bipartite_projection()
只能收集边的结构权重,也就是说,Peter 和 Jack 都隶属于 Train 和 Bar。处理边缘属性比较棘手。
如果您只想保留node属性,正如您在上面写的bipartite_projection()
那样,绝对已经为您做到了。只需重新投影并找到保留的属性,如下所示:
V(unipartite_graph)$your_attributee
但是,如果您需要在重新投影时保留edge属性,那么之前有几个问题要问。
- 当 Franz-Train-Jack 也有 Franz-Bar_Jack 时,应该如何处理多条路径?
- 方向性在计算中起什么作用
几年前我需要完全相同的东西,并通过编写我自己的扩展重投影函数来解决它。这可能不是解决此问题的最短方法,而是通过二部图中每个单部顶点对之间的最短路径计算给定边缘属性的总和,并返回保留(并汇总)一个边缘属性的图。
请注意,该函数不计算单分 Laurie-Peter。您可以根据自己的喜好操作该功能。
这会重现您的示例数据并应用我的功能
# Reproduce your data
df <- data.frame(Person = c("Peter","Jack","Franz","Franz","Laurie","Jack"),
EventLocation = c("Bar","Bar","Train","Bar","Train","Train"),
DurationEvent = c(90,90,20,90,20,20), stringsAsFactors = F)
## Make bipartite graph from example data
g <- graph_from_data_frame(df, directed=FALSE)
# Set vertex type using bipartite.mapping() (OBS type should be boolean for bipartite_projection())
V(g)$type <- bipartite.mapping(g)$type
## Plot Bipartite graph
E(g)$label <- E(g)$DurationEvent
V(g)$color <- ifelse(V(g)$type, "red", "yellow")
V(g)$size <- ifelse(V(g)$type, 40, 20)
plot(g, edge.label.color="gray", vertex.label.color="black")
# Function to reproject a bipartite graph to unipartite projection while
# calculating an attribute-value sum between reprojected vertecies.
unipartite_projection_attr <- function(graph_bi, attribute, projection=FALSE){
## Make initial unipartite projection
graph_uni <- bipartite_projection(graph_bi, which=FALSE)
## List paths in bipartite-graph along which to summarise selected attribute
el <- as_edgelist(graph_uni)
el <- matrix(sapply(el, function(x) as.numeric(which(x == V(graph_bi)$name))), ncol=2)
## Function to summarise given atribute-value
summarise_graph_attribute_along_path <- function(source, target, attribute){
attr_value <- edge_attr(g, attribute)
path <- get.shortest.paths(g, source, target, output="epath")$epath[[1]]
sum(E(g)$DurationEvent[path])
}
attr_uni <- mapply(summarise_graph_attribute_along_path, el[,1], el[,2], attribute)
graph_uni <- set_edge_attr(graph_uni, attribute, value=attr_uni)
(graph_uni)
}
# Use function to make unipartite projection
gg <- unipartite_projection_attr(g, "DurationEvent", FALSE)
# Visualise
V(gg)$color <- "yellow"
E(gg)$label <- E(gg)$DurationEvent
plot(gg, edge.label.color="gray", vertex.label.color="black")
祝你好运
推荐阅读
- go - 如何从 tls.Certificate 中获取 SubjectKeyId?
- apache-kafka - Kafka Streams Applications - 我们可以在一个微服务中拥有 2 个流应用程序吗?
- c# - 使用窗口形式c#中的委托传递数据(订阅和取消订阅)
- git - 从我当地的主人那里挑选上一个提交的最佳方法
- c++ - 如何在 shell 环境(winapi)中获取带扩展名的文件名?
- openedge - Openedge 在现有文本文件的开头添加文本
- react-native - HitRect 如何在 React Native 中与 Pressable 一起使用?
- c++ - 错误:“class Animal::animalSound”的使用无效
- flutter - 从长列表中动态创建小部件
- azure - Azure Build Pipeline - 如何授予对存储帐户的访问权限?