在 R 中按组绘制网络关系

Plot network ties by group in R

我有一个曲棍球运动员的数据集,以及他们在比赛中与谁打架。我想将所有玩家折叠到他们的团队中,并用连接团队的边缘绘制网络,并根据玩家在团队之间战斗的次数进行加权。

我用节点文件和边缘文件创建了图形。节点文件包含每个球员和他们所属的球队。示例:

节点文件:

name   team
Joe    anaheim_ducks
Greg   anaheim_ducks
Marc   anaheim_ducks
Chad   sanjose_sharks
Ed     sanjose_sharks
Perry  sanjose_sharks
Jack   vegas_goldenknights
Dan    vegas_goldenknights
Devin  vegas_goldenknights

边缘文件:

source  target
Perry   Jack
Devin   Joe
Jack    Chad
Greg    Jack
Ed      Marc
Dan     Joe

我想要一个文件或一种基于团队绘制网络的方法。边缘文件看起来像:

team_1                team_2               number_fights
anaheim_ducks         vegas_goldenknights  3
vegas_goldenknights   sanjose_sharks       2
sanjose_sharks        anaheim_ducks        1

下面粘贴的是我到目前为止的代码:

nhl_nodes <- read_xlsx("nhl_nodes.xlsx")
nhl_edges <- read_xlsx("nhl_edges.xlsx")

ncolor <- 31
nhl_color <- randomcoloR::distinctColorPalette(k = 31)
nhl_color <- as.data.frame(nhl_color)

teams <- as.data.frame(unique(nhl_nodes$team)) %>%
         rename(team = "unique(nhl_nodes$team)") %>%
         cbind(., nhl_color)

nhl_nodes$color <- NA

nhl_nodes <- left_join(nhl_nodes , teams) %>%
             rename(color = nhl_color)


nhl_g<-graph_from_data_frame(d = nhl_edges, vertices = nhl_nodes, 
                             directed=F)

iso <- V(nhl_g)[degree(nhl_g)==0]
nhl_g_test <- delete.vertices(nhl_g, iso)

V(nhl_g_test)$vertex_degree <-  degree(nhl_g_test)

layout=layout.fruchterman.reingold(nhl_g_test)

plot(nhl_g_test, vertex.size=V(nhl_g_test)$vertex_degree,
                 vertex.label=NA)

可以使用 nhl_g 上的 igraph 包中的 contract.vertices 函数。

nhl_nodes <- data.frame(name, team) 
nhl_edges <- data.frame(source, target)
nhl_g <- graph_from_data_frame(edgelist, directed = F, vertices = vertices)
E(nhl_g )$weight <- 1  # one edgeweight per "fight"
nhl_g_con <- contract.vertices(nhl_g , mapping = as.factor(V(nhl_g )$team),
                                       vertex.attr.comb = list(team = "first", name = "concat"))

这里我生成了一个新的图对象,contract顶点基于team类别。参数 vertex.attr.comb 声明对于 team-vector 仅应使用 first 元素,并且玩家的 name-vector 应粘贴在一起(串联)。结果如下所示。

请注意,此图在节点之间有多个边,并且显示的是球员的名字,而不是相应的球队。这在以下代码段中得到修复:

nhl_g_simple <- simplify(nhl_g_con)
par(mfrow = c(1,2))  # plotting parameters
plot(nhl_g_con, main = "nhl_g_con")
plot(nhl_g_simple , edge.label = E(nhl_g_simple )$weight, 
                    vertex.label = V(nhl_g_simple)$team, main = "nhl_g_simple")

得到的两张对比图:

从这里也可以提取所需的 data.frame:

> V(nhl_g_simple)$name <- V(nhl_g_simple)$team
> get.data.frame(nhl_g_simple)
            from                  to weight
1  anaheim_ducks      sanjose_sharks      1
2  anaheim_ducks vegas_goldenknights      3
3 sanjose_sharks vegas_goldenknights      2

希望对您有所帮助。

PS:请考虑使用dput()来共享您的数据,这样可以让人们更轻松地使用它。