Creating Igraph with Isolated Nodes

creating igraph with isolated nodes

You need to define your vertex list based on both columns of your object data. Some vertices are in column 1, some in column 2. You are missing those in column 2.

You can check this with %in%:

> c(e[,1], e[,2]) %in% v
[1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[19] TRUE TRUE FALSE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE
[37] FALSE TRUE TRUE TRUE

As you can see, there are 2 elements of e that are not in v. Thus you get the error message that says as much.

Create the vertex list v by taking the unique values of both columns in data, less the NAs.

data <- data.frame(ID = c(143918,176206,210749,219170,
247818,314764,321459,335945,
339637,700689,712607,712946,
735907,735907,735907,735907,
735907,735907,735908,735908,
735908,735908,735908,735908,
735910,735911,735912,735913,
746929,746929,747540,755003,
767168,775558,776656,794173,
794175,807493),
relation = c(111098,210749,176206,
NA,NA,NA,NA,NA,NA,807493,
NA,NA,735908,735910,735911,
735912,735913,767168,735907,
735910,735911,735912,735913,
767168,NA,NA,NA,NA,NA,100723,
NA,NA,NA,776656,775558,NA,NA,700689))

v <- unique(c(data[,1], data[,2])) #Define v from both columns in data
v <- na.omit(v)
e <- na.omit(data)

g<-graph.data.frame(e, vertices = v, directed = T)
plot(g)

Sample Image

Plotting isolated nodes in igraph with graph_from_data_frame. Missing

One way to get what you want is to leave out the single node, but then add it using add_vertices

library(igraph)
mydata <- data.frame(from=c("John", "John", "Jim"),
to=c("John", "Jim", "Jack"))
mygraph <- graph_from_data_frame(d=mydata, directed=T)
mygraph = add_vertices(mygraph, 1, name="Jesse")
plot(mygraph, vertex.label.dist=2)

Sample Image

How to create network with both edges and isolates using statnet/igraph

Use add.isolates from the sna package

net1 = as.network(cbind(1:3, 3:5)) #5 vertices, 3 edges
net2 = as.network(add.isolates(net1, 10), matrix.type = "edgelist") #15 v, 3 e

And then you'll probably want to create new vertex names, e.g.

net2%v%"vertex.names" = 1:15

Maximize the number of isolated nodes in a network

You will want to do something like:

  1. Compute the k-coreness of each node (just called Graph.coreness in the python bindings, don't know about R).

  2. Find the node with k-coreness 2, that connects to the largest number of nodes with k-coreness 1.

Edit:

Your counter-example was spot on, so I resorted to brute force (which is still linear time in this case).
This is a brute force python implementation that could be optimised (only loop over nodes with k-coreness 1), but it completes in linear time and should be accessible even if you don't know python.

import numpy as np
import igraph

def maximise_damage(graph):
coreness = graph.coreness()

# find number of leaves for each node
n = graph.vcount()
number_of_leaves = np.zeros((n))
for ii in range(n):
if coreness[ii] == 1:
neighbour = graph.neighbors(ii) # list of length 1
number_of_leaves[neighbour] += 1

# rank nodes by number of leaves
order = np.argsort(number_of_leaves)

# reverse order such that the first element has the most leaves
order = order[::-1]

return order, number_of_leaves[order]

EDIT 2:

Just realised this will not work in general for cases where you want to delete more than 1 node at a time. But I think the general approach would still work -- I will think about it some more.

EDIT 3:

Here we go; still linear. You will need to process the output a little bit though -- some solutions are less than the number of nodes that you want to delete, and then you have to combine them.

import numpy as np
import igraph

def maximise_damage(graph, delete=1):
# get vulnerability
# nodes are vulnerable if their degree count is lower
# than the number of nodes that we want to delete
vulnerability = np.array(graph.degree())

# create a hash table to keep track of all combinations of nodes to delete
combinations = dict()

# loop over vulnerable nodes
for ii in np.where(vulnerability <= delete)[0]:
# find neighbours of vulnerable nodes and
# count the number of vulnerable nodes for that combination
neighbours = tuple(graph.neighbors(ii))
if neighbours in combinations:
combinations[neighbours] += 1
else:
combinations[neighbours] = 1

# determine rank of combinations by number of vulnerable nodes dangling from them
combinations, counts = combinations.keys(), combinations.values()

# TODO:
# some solutions will contain less nodes than the number of nodes that we want to delete;
# combine these solutions

return combinations, counts

R: Selectively display nodes when plotting an igraph

I understand that users should not submit new answers to comment on other answers, but my edit was rejected and I don't have a high enough reputation to leave comments.

I just wanted to point out that in Wine's answer above, the "- 1" index correction in the deletes.isolates function is not necessary from igraph 0.6 onwards. See also Tamas' comment here:

Plot only Edges with a specific weight - igraph



Related Topics



Leave a reply



Submit