简体   繁体   English

使用R igraph和dplyr(purrr)有条件地在列表列图中设置边属性

[英]Setting edge attributes conditionally in list-column graphs using R igraph and dplyr (purrr)

I have a dataframe with a series of igraph objects in list-column format. 我有一个数据框,其中包含一系列列列格式的igraph对象。 I would like to conditionally set the edge color attribute. 我想有条件地设置边缘颜色属性。

I've included the dput output for a sample version of the actual dataframe (very large, thousands of graphs) containing just three graphs. 我已经包含了dput包含三个图形的实际数据帧(非常大,数千个图形)的示例版本的dput输出。 It's still long, so I've put it at the bottom of this post and I'll explain a couple of the ideas I've tried so far. 它仍然很长,因此我将其放在本文的底部,我将解释到目前为止我尝试过的一些想法。

First attempt was multiple uses of mutate and map using the purrr package. 首先尝试使用purrr包对mutatemap进行多次使用。

sampleColored <- sampleGraphs %>% mutate(map(graph, function(x) 
E(x)[weights == 0]$color = "blue")) %>% mutate(map(graph, function(x)
    E(x)[weights < 0]$color = "red"))  %>% mutate(map(graph, function(x)
    E(x)[weights > 0]$color = "green"))

No error messages, but the command 没有错误信息,但是命令

 shortPlots <- sampleColored %>%
 mutate(plots = map(graph, function(x) plot(x, layout=layout.circle,
     vertex.size=20,                                                          
     edge.curved=TRUE)))

produced nice graphs with all edges colored grey. 产生了漂亮的图形,所有边缘均为灰色。

Likewise with my second attempt where I created an edgeColor function and used a single map call. 同样,在第二次尝试中,我创建了edgeColor函数并使用了单个map调用。

edgecolor <- function(x) {
E(x)[weights == 0]$color <- "blue"
E(x)[weights < 0]$color <- "red"
E(x)[weights > 0]$color <- "green"
return(E(x))
}
sampleColored <- sampleGraphs %>% mutate(map(graph, function(x) edgecolor(x)))

No error and grey edges. 没有错误和灰色边缘。 Dropping the mutate command gives rise to the error message: 删除mutate命令会产生错误消息:

Error in as.numeric(n): cannot coerce type 'closure' to vector of type 'double'

I'm confident that this is possible and I simply don't have the understanding to get to the correct syntax. 我相信这是可能的,而且我只是不了解要使用正确的语法。 Any suggestions will be appreciated. 任何建议将不胜感激。 Thanks for looking. 感谢您的光临。

Here's the sampleGraph dput : 这是sampleGraph dput

sampleGraphs <- structure(list(ID = 997:1000, graph = list(structure(list(5, 
TRUE, c(0, 1, 2, 0, 3, 4, 1, 2, 4, 3, 0, 4, 2, 3, 0, 1, 3, 
1, 4, 2), c(1, 0, 0, 4, 1, 1, 4, 3, 0, 2, 3, 2, 1, 4, 2, 
3, 0, 2, 3, 4), c(0, 14, 10, 3, 1, 17, 15, 6, 2, 12, 7, 19, 
16, 4, 9, 13, 8, 5, 11, 18), c(1, 2, 16, 8, 0, 12, 4, 5, 
14, 17, 9, 11, 10, 15, 7, 18, 3, 6, 19, 13), c(0, 4, 8, 12, 
16, 20), c(0, 4, 8, 12, 16, 20), list(c(1, 0, 1), structure(list(), .Names = character(0)), 
    structure(list(name = c("3", "0", "2", "4", "1")), .Names = "name"), 
    structure(list(weights = c(3L, -4L, 4L, -3L, 43L, 8L, 
    4L, 14L, 1L, 55L, 2L, 22L, 26L, 64L, 9L, 2L, 13L, -12L, 
    25L, 16L)), .Names = "weights")), <environment>), class = "igraph"), 
structure(list(5, TRUE, c(0, 1, 2, 2, 1, 3, 1, 3, 4, 3, 3, 
0, 4, 0, 4, 4, 2, 1, 2, 0), c(3, 3, 4, 0, 2, 1, 4, 2, 0, 
4, 0, 2, 1, 4, 2, 3, 3, 0, 1, 1), c(19, 11, 0, 13, 17, 4, 
1, 6, 3, 18, 16, 2, 10, 5, 7, 9, 8, 12, 14, 15), c(17, 3, 
10, 8, 19, 18, 5, 12, 11, 4, 7, 14, 0, 1, 16, 15, 13, 6, 
2, 9), c(0, 4, 8, 12, 16, 20), c(0, 4, 8, 12, 16, 20), list(
    c(1, 0, 1), structure(list(), .Names = character(0)), 
    structure(list(name = c("2", "0", "1", "3", "4")), .Names = "name"), 
    structure(list(weights = c(4L, -4L, 25L, 22L, 4L, 3L, 
    2L, -3L, 55L, 2L, 9L, 16L, 43L, 14L, 64L, 13L, 1L, -12L, 
    8L, 26L)), .Names = "weights")), <environment>), class = "igraph"), 
structure(list(5, TRUE, c(0, 1, 2, 3, 4, 0, 1, 2, 1, 3, 1, 
3, 2, 4, 2, 4, 0, 0, 3, 4), c(1, 4, 3, 4, 0, 4, 2, 0, 0, 
2, 3, 1, 4, 1, 1, 2, 3, 2, 0, 3), c(0, 17, 16, 5, 8, 6, 10, 
1, 7, 14, 2, 12, 18, 11, 9, 3, 4, 13, 15, 19), c(8, 7, 18, 
4, 0, 14, 11, 13, 17, 6, 9, 15, 16, 10, 2, 19, 5, 1, 12, 
3), c(0, 4, 8, 12, 16, 20), c(0, 4, 8, 12, 16, 20), list(
    c(1, 0, 1), structure(list(), .Names = character(0)), 
    structure(list(name = c("4", "0", "3", "2", "1")), .Names = "name"), 
    structure(list(weights = c(43L, 4L, 9L, 16L, 25L, 64L, 
    -4L, 2L, 2L, 4L, -11L, 26L, -3L, 8L, 3L, 1L, 55L, 13L, 
    14L, 22L)), .Names = "weights")), <environment>), class = "igraph"), 
structure(list(5, TRUE, c(0, 1, 2, 3, 4, 1, 3, 2, 4, 0, 1, 
3, 2, 4, 0, 0, 2, 4, 1, 3), c(4, 4, 4, 1, 2, 0, 2, 3, 0, 
3, 2, 0, 1, 1, 2, 1, 0, 3, 3, 4), c(15, 14, 9, 0, 5, 10, 
18, 1, 16, 12, 7, 2, 11, 3, 6, 19, 8, 13, 4, 17), c(5, 16, 
11, 8, 15, 12, 3, 13, 14, 10, 6, 4, 9, 18, 7, 17, 0, 1, 2, 
19), c(0, 4, 8, 12, 16, 20), c(0, 4, 8, 12, 16, 20), list(
    c(1, 0, 1), structure(list(), .Names = character(0)), 
    structure(list(name = c("1", "4", "0", "2", "3")), .Names = "name"), 
    structure(list(weights = c(1L, 13L, -4L, 14L, 3L, 64L, 
    26L, -11L, -3L, 22L, 43L, 16L, 2L, 2L, 8L, 25L, 4L, 8L, 
    55L, 4L)), .Names = "weights")), <environment>), class = "igraph"))),     class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -4L), .Names = c("ID", 
"graph"))

Using set_edge_attr rather than igraph 's idiomatic E() edge function helps. 使用set_edge_attr而不是igraph的惯用E()边缘函数会set_edge_attr帮助。 I had to revise the sampleGraph list to a simple list of graphs, upgraded to the newer version of igraph , but this works: 我不得不将sampleGraph列表修改为一个简单的图形列表,将其升级到igraph的较新版本,但这igraph

graphs <- sampleGraphs$graph
graphs <- lapply(graphs, function(x) upgrade_graph(x)) #making a simple list of graphs

edgecolor <- function(x) {
  E(x)[weights == 0]$color <- "blue"
  E(x)[weights < 0]$color <- "red"
  E(x)[weights > 0]$color <- "green"
  return(E(x)$color)
} #The function now returns a list of colors conditional on statements

#Pass the function to the "values" argument of "set_edge_attr"

graphs_colored <- graphs %>% map(., function(x) set_edge_attr(x, "color", value = edgecolor(x)))

par(mfrow = c(2,2), mar = c(0,0,0,0))
shortPlots <- graphs_colored %>%
 map(., function(x) plot(x, 
                         layout=layout.circle,
                         vertex.size=20,                                                          
                         edge.curved=TRUE,
                         edge.arrow.size = 0.5))

在此处输入图片说明

Got it! 得到它了! Thanks to @paqmo for suggestions. 感谢@paqmo的建议。 I needed to use mutate to redefine the graph list-column variable. 我需要使用mutate重新定义graph list-column变量。

edgecolor <- function(x) {
  E(x)[weights == 0]$color <- "#FF000000"
  E(x)[weights < 0]$color <- "red"
  E(x)[weights > 0]$color <- "green"
  return(E(x)$color)
}
sampleColored <- sampleGraphs %>% mutate(graph = map(graph, function(x) 
  set_edge_attr(x, "color", value = edgecolor(x))))

par(mfrow = c(2,2), mar = c(0,0,0,0))
samplePlots <- sampleColored %>%
     mutate(plots = map(graph, function(x) plot(x, layout=layout.circle,
       vertex.size=20,                                                          
       edge.curved=TRUE)))

generates the same image as @paqmo. 生成与@paqmo相同的图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM