Reputation: 2070
I have a graph where nodes belong to two different religion, and I need to select nodes of one religion and fully connect them. Is there a more concise way than:
g<-graph.empty(n=0, directed=T)
## add nodes
g<-add.vertices(g, length(df[,1]), attr=df)
for(i in V(g)[religion == "x"]){
for(ii in V(g)[religion == "x"]){
if(i!=ii){
g<-add.edges(g, c(i,ii))
}
}
}
an example data frame could be:
df<-structure(list(id = c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12), name = c("a", "b",
"c", "d", "e", "f", "g", "h", "i", "l", "m", "n"), village = c("A", "B", "C", "D", "E",
"F", "G", "H", "I", "L", "M", "N"), religion = c("x", "y", "y", "y", "y", "x", "x", "x",
"x", "x", "y","x"), adoption.lag = c(30, 32, 32, 32, 0, 30, 30, 30, 0, 1, 22, 22),
type = c("potter", "potter", "potter", "potter", "city", "potter", "potter", "potter",
"potter", "potter", "city", "potter")), .Names = c("id", "name", "village", "religion",
"adoption.lag", "type"), row.names = c(NA, -12L), class = "data.frame")
Upvotes: 0
Views: 70
Reputation: 10825
Here is a simple way instead of the nested for loops:
relnodes <- V(g)[religion == "x"]
g[relnodes, relnodes] <- 1
This works because you can treat an igraph graph as an adjacency matrix. See more examples here: http://igraph.org/r/doc/graph.structure.html
If you want to remove the loop edges, you can do:
g <- simplify(g, remove.loops=TRUE, remove.multiple=FALSE)
Upvotes: 2
Reputation: 59345
Well, here's one way.
library(igraph)
x <- df[df$religion=="x",] # subset the df
z <- expand.grid(x$name,x$name) # every combination of edge
z <- with(z,z[Var1!=Var2,]) # remove loops
g <- graph.data.frame(z)
g <- add.vertices(g,nv=nrow(df)-nrow(x),attr=df[df$religion!="x",])
par(mar=c(0,0,0,0)) # set plot margins to 0...
plot(g)
Upvotes: 1