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)
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)
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:
Compute the k-coreness of each node (just called Graph.coreness in the python bindings, don't know about R).
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
Remove Some of the Axis Labels in Ggplot Faceted Plots
Ggplot Dotplot: What Is the Proper Use of Geom_Dotplot
Prevent Knitr/Rmarkdown from Interleaving Chunk Output with Code
How to Calculate the Median on Grouped Dataset
Rmarkdown::Render() in a Loop - Cannot Allocate Vector of Size
How to Tell Which Packages I am Not Using in My R Script
How to Use "Cast" in Reshape Without Aggregation
R Equivalent of Stata Local or Global MACros
R Doesn't Reset the Seed When "L'Ecuyer-Cmrg" Rng Is Used
R: Is There a Good Replacement for Plyr::Rbind.Fill in Dplyr
How to Get Dimnames in Xtable.Table Output
Calling External Program from R with Multiple Commands in System
Continuous Color Bar with Separators Instead of Ticks
Calculate Elapsed Time Since Last Event