add more than one edge based on edge attributes using igraph

隐身守侯 提交于 2020-01-03 08:30:09

问题


I would like to know wether, using igraph, it is possible to add edges to a graph depending on the values of different edge attributes.

I have a data.frame, which dput is the following:

df <- structure(list(nodeA = c("CFTR", "CFTR", "CFTR", "CFTR", "CFTR", 
"CFTR"), nodeB = c("CYP7A1", "KRT16", "ABCA3", "SLC22A11", 
"PBK", "ACSM1"), score = c(0.239, 0.24, 0.292, 0.269, 
0.233, 0.168), text = c(129L, 0L, 287L, 246L, 
161L, 155L), mining = c(163L, 241L, 413L, 71L, 92L, 56L), 
experiments = c(0L, 0L, 101L, 0L, 75L, 0L), homologs =c(0L, 
0L, 609L, 0L, 0L, 0L)), .Names = c("nodeA", "nodeB", 
"score", "text", "mining","experiments", 
"homologs"), class = "data.frame", row.names = c(NA, 6L))

I would like to add new edges to the graph (g <- graph.data.frame(df, directed=FALSE) if the value of the edge attributes is different from 0, for example for the edge CFTR--CYP7A1, I would like to add a pair of extra edges (one for the text and another for the mining attributes), I am not interested in score (it is the weight of my the graph)


回答1:


Here are a couple of ways.

First, rearranging your original data seems a bit easier. Put the data in to long format and assign colours based on the column names.

library(reshape2)
# Data in long format 
# Create graph, with edges add when attributes / columns are greater than zero
m <- melt(df, id=1:2)
m <- m[m$value != 0, ] # keep non-zero values
g <- graph.data.frame(m, directed=FALSE)

# Add colours to the edges
cols = c(score="black", text="blue", mining="green", 
                                  experiments="red", homologs="yellow")
plot(g, edge.color=cols[E(g)$variable])

If you want to have the original graph and then add coloured edges for each attribute greater than zero, you can loop through the attributes (edge_attr), and add edges (add_edges) when the condition is met.

We can add the additional edges one at a time (shown for the text attribute)

g <- graph.data.frame(df, directed=FALSE)    
names(edge_attr(g)) # attributes

# Which edges should be added conditioned on text attribute being greater than zero
edge_attr(g, "text")
ats <- edge_attr(g, "text") > 0

#Set edges in graph already to black
E(g)$color <- "black"

# Get head and tail of all edges
ed <- get.edgelist(g)

# subset these by the attribute condition
# combine head and tail nodes in correct format for add_edges
# should be c(tail1, head1, tail2, head2, ..., tailn, headn)
ed <- t(ed[ats, 2:1])

# Add the additional edges
g  <- add_edges(g, ed,  color="blue")
plot(g)

Or add the additional edges in one go

g <- graph.data.frame(df, directed=FALSE)    

# Indicator of attribute > 0
ats <- unlist(edge_attr(g)) > 0

# Repeat the head & tail of each edge
# subset so the same length as relevant attributes
ed <- do.call(rbind, replicate(length(edge_attr(g)), get.edgelist(g), simplify=FALSE))
ed <- t(ed[ats, 2:1])
cols <- rep(c("black", "blue", "green", "red", "yellow"), each=length(E(g)))[ats]

g  <- add_edges(g, ed,  color=cols)
plot(g)



回答2:


I think this gets you what you want with a bit of melting and casting:

library(data.table)

setDT(df)

#get list of potential edges
tmp <- melt(df, id.vars = c("nodeA","nodeB","score"), measure.vars = c("text","mining","experiments","homologs"))

#Filter out zeros, create unique group for each edge
tmp <- tmp[value != 0, ][, ind := .I]

#Recast
tmp <- dcast(tmp, ind + nodeA + nodeB + score ~ variable, value.var = "value", fill = 0)

#get rid of index
tmp[, ind := NULL]

#join back to initial edge list
df <- rbindlist(list(df, tmp))
df
    nodeA    nodeB score text mining experiments homologs
 1:  CFTR   CYP7A1 0.239  129    163           0        0
 2:  CFTR    KRT16 0.240    0    241           0        0
 3:  CFTR    ABCA3 0.292  287    413         101      609
 4:  CFTR SLC22A11 0.269  246     71           0        0
 5:  CFTR      PBK 0.233  161     92          75        0
 6:  CFTR    ACSM1 0.168  155     56           0        0
 7:  CFTR   CYP7A1 0.239  129      0           0        0
 8:  CFTR    ABCA3 0.292  287      0           0        0
 9:  CFTR SLC22A11 0.269  246      0           0        0
10:  CFTR      PBK 0.233  161      0           0        0
11:  CFTR    ACSM1 0.168  155      0           0        0
12:  CFTR   CYP7A1 0.239    0    163           0        0
13:  CFTR    KRT16 0.240    0    241           0        0
14:  CFTR    ABCA3 0.292    0    413           0        0
15:  CFTR SLC22A11 0.269    0     71           0        0
16:  CFTR      PBK 0.233    0     92           0        0
17:  CFTR    ACSM1 0.168    0     56           0        0
18:  CFTR    ABCA3 0.292    0      0         101        0
19:  CFTR      PBK 0.233    0      0          75        0
20:  CFTR    ABCA3 0.292    0      0           0      609


来源:https://stackoverflow.com/questions/39800516/add-more-than-one-edge-based-on-edge-attributes-using-igraph

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!