How to plot chosen vertices and total number of edges - r

I'd like to plot two selected nodes and all their edges, not only the ones that connect these two nodes directly. For example:
library(igraph)
o <- read.table(text="
A B C D E F G
A 0 1 0 1 0 1 1
B 1 0 1 1 0 1 0
C 0 0 0 0 0 0 1
D 1 1 0 0 1 0 0
E 0 0 0 1 0 1 1
F 0 1 0 0 1 0 1
G 1 0 1 0 1 1 0", header=TRUE)
mat <- as.matrix(o)
g <- graph.adjacency(mat, mode="undirected", weighted = T, add.rownames = T)
I'm able to choose two nodes of g using the codes below, but the plot includes only the edges that connect them directly. I want them all.
g2 <- induced_subgraph(g, c("A","E"))
plot(g2)
How do I plot the two vertices, and all of their edges? Also, how do I choose path distance for each vertex?
Thanks!

library(igraph)
o <- read.table(text="
A B C D E F G
A 0 1 0 1 0 1 1
B 1 0 1 1 0 1 0
C 0 0 0 0 0 0 1
D 1 1 0 0 1 0 0
E 0 0 0 1 0 1 1
F 0 1 0 0 1 0 1
G 1 0 1 0 1 1 0", header=TRUE)
mat <- as.matrix(o)
g <- graph.adjacency(mat, mode="undirected", weighted = T, add.rownames = T)
plot(g)
# get 1st connections of A and E (their friends)
vertices_input = c("A","E") # specify vertices of interest
ids = as.numeric(E(g)[from(vertices_input)]) # get the ids of the edges from g that correspond to those vertices
g2 = subgraph.edges(g, ids) # keep only those edges from g as a sub-graph g2
plot(g2)
# get up to 2nd connections of A and E (friends of friends)
nms = V(g2)$name # get names of vertices of your sub-graph g2 (main vertices and 1st connections)
ids = as.numeric(E(g)[from(nms)]) # get the ids of the edges from g that correspond to main vertices and 1st connections
g3 = subgraph.edges(g, ids) # keep only those edges from g as a sub-graph g3
plot(g3)

Related

Calculate degree of a subgraph using r igraph

I know the degree of my global graph, but now I need to find the degrees of nodes within a subgraph. So, John has 4 friends in his school, but three friends in his class. How do I instruct igraph to count those three friends in his class, but not the rest in his school?
My global graph
library(igraph)
school <- read.table(text="
A B C D E F G
A 0 1 0 1 0 1 1
B 1 0 1 1 0 1 0
C 0 0 0 0 0 0 1
D 1 1 0 0 1 0 0
E 0 0 0 1 0 1 1
F 0 1 0 0 1 0 1
G 1 0 1 0 1 1 0", header=TRUE)
mat <- as.matrix(school)
g <- graph.adjacency(mat, mode="undirected", add.rownames = T)
My affiliation matrix for classes P, Q, and R
x <- read.table(text="
P Q R
A 1 1 0
B 0 0 1
C 0 0 0
D 1 0 1
E 1 1 0
F 0 1 0
G 1 1 1", header=TRUE)
inc <- as.matrix(x)
ginc <- graph.incidence(inc)
My subgraph for class P
class_nodes <- names(which(inc[,"P"] == 1))
class_adj <- mat[class_nodes, class_nodes]
class_graph <- graph.adjacency(class_adj, mode = "undirected")
I need to calculate the degree of nodes in subgraph "class_graph", but counting only their ties within the subgraph, not the global graph.
You can find all the nodes in class P with (we specifically extract the names so we can look them up in a different graph object).
V(ginc)[.nei("P")]$name
Then you can extract just that subset of connections from the main graph with
subg <- induced.subgraph(g, V(ginc)[.nei("P")]$name)
and you can calculate the degree of those nodes with
degree(subg)
# A D E G
# 2 2 2 2

Assign colour to chosen communities in a plot

In a plot, I need to colour two specific communities. Take the following data frame:
A B C D E F G
A 0 1 0 1 0 1 0
B 1 0 1 1 0 1 0
C 0 1 0 0 0 0 0
D 1 1 0 0 1 1 0
E 0 0 0 1 0 1 0
F 1 1 0 1 1 0 1
G 0 0 0 0 0 1 0
ob <- read.csv("...ties.csv",sep = ",", header = TRUE, row.names = 1)
m <- as.matrix(ob)
g <- graph.adjacency(m, mode="undirected", weighted = T, add.rownames = T)
First, I detect the communities (com) of my graph g using edge.betweenness:
com <- edge.betweenness.community(g)
V(g)$memb <- com$membership
This operation produces a number of communities, com[[1]],com[[2]], etc. I plot the resulting graph -- each community one colour -- with the following code:
plot(g, vertex.color=membership(com))
Now, how do I colour only two chosen communities, say com[[1]] and com[[2]], keeping the rest of the nodes homogeneous?
I had to tweak your adjacency matrix so that more than 1 community showed up.
library(igraph)
ob <- read.table(text="
A B C D E F G
A 0 1 0 1 0 1 0
B 1 0 1 1 0 1 0
C 0 0 0 0 0 0 0
D 1 1 0 0 1 0 0
E 0 0 0 1 0 1 1
F 0 1 0 0 1 0 1
G 0 0 0 0 1 1 0", header=TRUE)
m <- as.matrix(ob)
g <- graph.adjacency(m, mode="undirected", weighted = T, add.rownames = T)
com <- edge.betweenness.community(g)
V(g)$memb <- com$membership
cols <- membership(com)
cols[cols!=3] <- 1
plot(g, vertex.color=cols)

Measure weight of communities for different subgraphs

I detect communities in my adjacency matrix. Parallely, I create an affiliation matrix using the vertices of the same matrix. How do I measure the weight of the communities in each of the columns of the affiliation matrix?
Take the following adjacency matrix:
A B C D E F G
A 0 1 0 1 0 1 0
B 1 0 1 1 0 1 0
C 0 1 0 0 0 0 0
D 1 1 0 0 1 1 0
E 0 0 0 1 0 1 0
F 1 1 0 1 1 0 1
G 0 0 0 0 0 1 0
I identify the communities:
com <- edge.betweenness.community(g)
V(g)$memb <- com$membership
Now take the following affiliation matrix:
P R Q
A 1 1 0
B 1 0 1
C 1 1 0
D 0 1 0
E 1 0 1
F 0 0 1
G 1 1 0
How do I count the number of vertices corresponding to community [[1]] which are affiliated to the "P" in the affiliation matrix?
You can do sum(m[com[[1]],"P"]>0), given that m holds your affiliation matrix. Or lapply(com, function(x) colSums(m[x, ])) for all communities.

(R Igraph) Using affilliation to create subgraph from adjacency matrix

I need to create a subgraph from an adjacency matrix selecting by affiliation data. How do I match an adjacency and an affiliation matrix?
Take the following adjacency matrix:
A B C D E F G
A 0 1 0 1 0 1 0
B 1 0 1 1 0 1 0
C 0 1 0 0 0 0 0
D 1 1 0 0 1 1 0
E 0 0 0 1 0 1 0
F 1 1 0 1 1 0 1
G 0 0 0 0 0 1 0
And the following affiliation matrix:
P R Q
A 1 1 0
B 1 0 1
C 1 1 0
D 0 1 0
E 1 0 1
F 0 0 1
G 1 1 0
How do I create a subgraph from the adjacency matrix only with the nodes corresponding to P in the affiliation matrix?
If your goal is to:
filter out nodes from your adjacency matrix where the corresponding P is 1 in the affiliation matrix
convert filtered adjacency matrix to an igraph object
then you can accomplish that with the following:
# the names(which()) isn't needed for the subset of adj
p_nodes <- names(which(aff[,"P"] == 1))
p_adj <- adj[p_nodes, p_nodes]
p_graph <- igraph::graph.adjacency(p_graph)

Transform ids -> items to {pairs of ids} -> items

I have a data.frame like this:
x1 <- data.frame(id=1:3,item=c("A","B","A","B","C","D"))
x1[order(x1$item),]
id item
1 1 A
3 3 A
2 2 B
4 1 B
5 2 C
6 3 D
I want to get :
id1=c(1,2,1,3,2,3)
id2 = c(2,1,3,1,3,2)
A=c(0,0,1,1,0,0)
B=c(1,1,0,0,0,0)
C = 0
D=0
datawanted <- data.frame(id1,id2,A,B,C,D)
id1 id2 A B C D
1 1 2 0 1 0 0
2 2 1 0 1 0 0
3 1 3 1 0 0 0
4 3 1 1 0 0 0
5 2 3 0 0 0 0
6 3 2 0 0 0 0
if person1 and person2 both have B,then in the datawanted dataframe,column A ,got 1,else get 0.
Can someone give me some suggestions or functions in R,to deal with this problem?
Cool question. You have a bipartite graph, so following Gabor's tutorial...
library(igraph)
g = graph_from_edgelist(as.matrix(x1))
V(g)$type = grepl("[A-Z]", V(g)$name)
For OP's desired output, first we can extract the incidence matrix:
gi = get.incidence(g)
# A B C D
# 1 1 1 0 0
# 2 0 1 1 0
# 3 1 0 0 1
Note (thanks #thelatemail), that if you don't want to use igraph, you can get to gi as table(x1).
Then, we look at the combinations of ids:
res = t(combn(nrow(gi), 2, function(x) c(
as.integer(rownames(gi)[x]),
pmin( gi[x[1], ], gi[x[2], ] )
)))
dimnames(res) <- list( NULL, c("id1", "id2", colnames(gi)))
# id1 id2 A B C D
# [1,] 1 2 0 1 0 0
# [2,] 1 3 1 0 0 0
# [3,] 2 3 0 0 0 0
This essentially is the OP's desired output. They had included redundant rows (e.g., 1,2 and 2,1).
Fun reason to use a graph (ht Chris):
V(g)$color <- ifelse(V(g)$type, "red", "light blue")
V(g)$x <- (1:2)[ V(g)$type + 1 ]
V(g)$y <- ave(seq_along(V(g)), V(g)$type, FUN = seq_along)
plot(g)
Or, apparently this can be done more or less like
plot(g, layout = layout.bipartite(g)[,2:1])

Resources