Le but de ce TP est de prendre en main le paquetage R igraph

Vous aurez à rendre un compte rendu au format Rmd (cf. trucs et astuces plus bas), constitué de d’une suite d’instructions R et de réponses aux questions. Ce fichier Rmd doit pouvoir être compilable (i.e. tricotable, knitable) en HTML ou PDF par nos soins. Ce compte-rendu doit être déposé sous Ametice pour la veille de la prochaine séance, 23h.

Préliminaires

install.packages("igraph", repos="http://cran.biotools.fr")

Cette commande télécharge le code source de la version la plus récente du package igraph depuis la machine http://cran.biotools.fr, télécharge récursivement toutes ses dépendances (i.e. les autres packages que igraph utilise), tente de les compiler (il faut donc que des outils de développement C, C++, Java et Fortran soient installés), puis les installe sur votre système. En mode utilisateur, ils sont installés dans $HOME/R/.

Notes

Pour ce TP, vous avez l’avantage de pouvoir bénéficier de la puissance de RStudio, ce qui peut vous faciliter la tâche (RStudio vous permet par exemple d’installer des paquetages, de les configurer, et de produire des documents en quelques clics de souris). Notez cependant, que dans un cadre de travail, vous serez parfois amenés à devoir travailler sur des machines distantes (de haute performance) sur lesquelles l’environnement d’exécution R sera installé, mais sur lesquelles RStudio ne sera pas disponible.

Trucs et astuces

À la découverte d’igraph

Importer le paquetage dans votre environnement

library(igraph)

Savoir si un package est à jour

Connaître la version d’un package sur le dépôt distant

available.packages(repos="http://cran.biotools.fr")["igraph", ][["Version"]]

Connaître la version d’un package installé localement

Pour connaître la version d’un package donné, une fois la commande library(igraph) exécutée, vous pouvez exécuter la commande suivante :

sessionInfo()

Dans le résultat de cette commande, vous devriez trouver la version de igraph installée sur votre système.

Exécutez la commande :

names(sessionInfo())

Question 1 : Expliquez ce que produit l’exécution de la commande précédente (la commande str() vous permet de connaître le type de l’objet retourné par sessionInfo()). Quel est le rôle de la fonction names() ?

Question 1bis : sessionInfo()$otherPkgs (ou sessionInfo()[["otherPkgs"]]) permet de lister les autres packages chargés (grâce aux appels antérieurs à la fonction library()) et names(sessionInfo()$otherPkgs) permet d’obtenir leur nom.

Comment demander à R d’afficher, comme ci-dessous, seulement la version du package igraph installée sur votre système, à partir d’un appel à la fonction sessionInfo() ou grâce à un appel à une autre fonction dont le rôle est d’afficher la version d’un package donné~?

## [1] "1.2.2"
## [1] "1.2.2"
## [1] '1.2.2'

Mettre à jour un package donné

update.packages("igraph", repos='http://cran.biotools.fr')

Changer de répertoire de travail

Modifiez cette ligne pour vous placer dans votre répertoire préféré

# setwd("~/sync/Enseignement/GRIB/igraph")

Création de graphes

Création d’un graphe g1 à 10 sommets (numérotés de 1 à 10).

g1 <- graph.empty(n=10)

Création d’un graphe complet à 10 sommets

g2 <- graph.full(n=10)

Question 2 : Comment construire un graphe complet contenant également des arêtes de chaque sommet vers lui-même (boucles=arcs allant d’un sommet vers lui-même) ? Pour répondre à cette question (ainsi qu’à la grande majorité des questions de ce TP) : ?graph.full

Création d’un graphe étoilé à 10 sommets. Le mode "out" crée un graphe orienté, les arcs allant du centre vers la périphérie

g3 <- graph.star(n=10, mode="out")

Question 3 : Comment construire un graphe étoilé non orienté (i.e. les arcs n’ont pas de direction, on parle alors d’arêtes) ?

Création d’un anneau à 10 sommets

g4 <- graph.ring(n=10)

Visualisation

Pour visualiser un graphe (ici g4) :

plot(g4)

Pour exporter le dessin en PDF :

pdf("Graph.pdf")
plot(g4)
dev.off()

Question 4 : Comment exporter le graphe sous forme de fichier image (PNG par exemple) ?

Création de graphes plus intéressants

Définition d’une liste d’arcs grâce à un vecteur numérique V de longueur paire. Chaque couple d’élément d’indice 2i-1, 2i (pour i allant de 1 à length(V)/2) représente les extrémités de chaque arc

edges <- c(1,2, 3,2, 2,4, 7,9)

Création directe d’un graphe orienté à partir de cette liste d’arêtes

g <- graph(edges)

Question 5 : Le graphe obtenu est un graphe orienté. Comment le transformer en graphe non orienté ?

Question 6 : Comment construire directement une version non-orientée de ce graphe à partir du vecteur edges, sans devoir créer un graphe orienté au préalable ?

Question 7 : Au passage, quelle fonction booléenne appeler pour savoir si un graphe donné g est connexe (i.e. connecté) ?

Question 8 : Expliquez le résultat des deux instructions ci-dessous. Que retourne la fonction cohesion() ?

cohesion(g3)            # equals 0, because ?
cohesion(graph.full(5)) # equals |V|-1, because ?

Informations sur la structure du graphe

Pour connaître le nombre de sommets (vertices) et d’arêtes (edges) d’un graphe :

vcount(g)
## [1] 9
ecount(g)
## [1] 4

Pour avoir accès à la séquence des sommets et des arêtes d’un graphe g:

V(g)
## + 9/9 vertices, from 0d45d73:
## [1] 1 2 3 4 5 6 7 8 9
E(g)
## + 4/4 edges from 0d45d73:
## [1] 1->2 3->2 2->4 7->9

Question 9 : Que font les deux instructions R suivantes ? Expliquer le rôle de chacun de leurs arguments

neighbors(g, V(g)[1], mode = 1)
incident(g, V(g)[2], mode=c("all", "out", "in", "total"))

Deux sommets sont-ils connectés ?

Question 10 : Comment savoir si un graphe est orienté (dirigé) ou pas ?

Question 11 : Comment savoir si deux sommets i et j sont connectés (adjacents)

Modifier la structure d’un graphe

Pour rajouter un certain nombre de sommets à un graphe :

g5 <- add.vertices(g, 4)

Pour supprimer des sommets spécifiques :

g6 <- delete.vertices(g, c(2,5,7,9))

Pour ajouter des arêtes spécifiques :

g7 <- add.edges(g, c(4,2, 8,6, 1,3))

Pour supprimer certaines arêtes

g8 <- delete.edges(g, c(1,2))

Pour supprimer des sommets isolés :

g9 <- delete.vertices(g, V(g)[degree(g)==0])

Pour supprimer les boucles

g10 <- simplify(g, remove.loops = TRUE)

Attributs : sommets étiquettés, couleurs

Il est possible de créer un graphe avec 10 sommets rouges et 10 sommets bleus

g <- graph.empty() + vertices(letters[1:10], color="red") + vertices(letters[11:20], color="blue")

Et de tirer aléatoirement (avec remise) 15 couples de sommets à relier

g <- g + edges(sample(V(g), 30, replace=TRUE), color="green")

Modifier les attributs d’un graphe

Par défaut, un graphe ne contient pas d’informations supplémentaires en dehors de sa structure. Il est heureusement possible d’associer des attributs (des informations textuelles) aux sommets et arêtes du graphe, ainsi qu’au graphe lui-même.

Du graphe

Pour ajouter un attribut "nom" de valeur "mon graphe" à un graphe g :

g$nom <- "mon graphe"

Pour connaître la valeur de l’attribut nom de mon graphe g :

g$nom
## [1] "mon graphe"

Pour supprimer l’attribut "nom" d’un graphe g :

g <- delete_graph_attr(g, "nom")

Des sommets

L’appel à la fonction vertices() plus haut a fait en sorte que chaque sommet possède un attribut "name" et un attribut "color". Pour ajouter, par exemple, un attribut "size" de valeur 0.9 au sommet 3 du graphe g :

V(g)[3]$size <- 0.9

Pour connaître la valeur de l’attribut "size" pour chaque sommet de g :

V(g)$size
##  [1]  NA  NA 0.9  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA  NA
## [18]  NA  NA  NA

Pour connaître la valeur de l’attribut "size" pour le sommet 3 de g :

V(g)[3]$size
## [1] 0.9

Pour supprimer l’attribut "size" sur les sommets de g :

g <- delete_vertex_attr(g, "size")

Des arêtes

Question 12 : l’appel précédent à la fonction edges() a permit de donner un attribut "color" à chaque arête. Comme précédemment, quelles sont les 4 instructions R permettant de jouer avec les attributs des arêtes ?

##  [1] NA      NA      "edge1" NA      NA      NA      NA      NA     
##  [9] NA      NA      NA      NA      NA      NA      NA
## [1] "edge1"

Travailler sur des données réelles

Pour importer un graphe à partir d’un fichier :

g1 <- read.graph("http://www.dil.univ-mrs.fr/~tichit/bin/tp1/depts.txt", format="edgelist")
g2 <- read.graph("http://cneurocvs.rmki.kfki.hu/igraph/karate.net", format="pajek")
g3 <- read.graph("http://www.dil.univ-mrs.fr/~tichit/bin/tp1/depts.lgl", format="ncol")

Exporter vers un fichier CSV

Nous pouvons récupérer la liste des arêtes sous forme de data.frame et l’exporter vers un fichier texte de la façon suivante :

el <- get.edgelist(g)
write.table(el, file = "graph.out", sep=";", row.names=FALSE, col.names=FALSE)

Exporter vers un format standard

Pour exporter un graphe vers un des formats connus de igraph :

write.graph(g1, file='copy_depts.txt', format="edgelist")
write.graph(g2, file='copy_karate.net', format="pajek")
write.graph(g3, file='copy_depts.lgl', format="ncol")

Interaction avec d’autres logiciels

Cytoscape est une plate-forme logicielle open source pour la visualisation de réseaux d’interactions.

Question 13 : Citez deux formats de fichiers reconnus par igraph et Cytoscape. Ouvrez un graphe produit par igraph vers Cytoscape.

Question 14 : Sous Cytoscape, ouvrez un réseau exemple (l’un des réseaux situé dans le dossier $HOME/Cytoscape_vX.Y.Z/sampleData ou /usr/local/share/Cytoscape_vX.Y.Z/sampleData), puis exportez le dans le format le plus facilement reconnu par igraph (export CSV devrait être une bonne méthode. Il vous faudra néanmoins modifier le fichier à l’aide d’un tableur, ou ouvrir puis récupérer les bonnes colonnes grâce à read.table ou read.csv). Ouvrez-le avec igraph et affichez son nombre de sommets et d’arêtes.

Matrices d’adjacence

Récupérez, grâce à un code R classique le fichier CSV suivant et enregistrez-le sous forme de data frame, puis comme matrice d’adjacence.

df <-read.table(file="http://www.dil.univ-mrs.fr/~tichit/bin/tp1/g1.csv", header=TRUE, row.names=1, sep=";")
am <- as.matrix(df)

Il est possible maintenant d’en faire un graphe

g <- graph.adjacency(am, mode = "undirected")

L’idée de cet exercice est de déterminer si 2 graphes donnés se ressemblent, i.e. si ils possèdent des caractéristiques similaires.

Question 15 : Développer un script R (i.e. une suite d’instructions R) qui permet de mesurer un graphe non-orienté donné, c’est-à-dire, donner :

  • nombre de sommets
  • nombre d’arêtes
  • degré minimal et maximal
  • densité
  • diamètre
  • moyenne de la longueur des chemins (appelée également distance moyenne)
  • coefficient de clustering (appelé également transitivité)
  • la coreness maximale
  • la maille

En ce qui concerne les 6 dernières caractéristiques, il vous sera demandé d’expliquer (ou de réexpliquer) leur définition. Il ne vous est pas demandé d’explications très mathématiques, mais quelque chose d’assez précis et rigoureux pouvant être compris par l’average scientist.

##   name v.nb e.nb min.d max.d dens diam avg.path.len clust.coef kcore girth
## 1   g1   89  218     2     7 0.02   11          4.0       0.40     3     3
## 2   g2   34   78     1    17 0.13    5          2.4       0.25     4     3
## 3   g3   89  218     2     7 0.05   12          5.0       0.40     3     3
## 4   gf   20   15     0     7 0.03    4          1.6       0.00     4     0

Une autre mesure intéressante est la distribution des degrés :

degree.distribution(g2)
##  [1] 0.00000000 0.02941176 0.32352941 0.20588235 0.14705882 0.08823529
##  [7] 0.05882353 0.00000000 0.00000000 0.02941176 0.02941176 0.00000000
## [13] 0.00000000 0.02941176 0.00000000 0.00000000 0.02941176 0.02941176

On peut afficher la distribution correspondante pour avoir une représentation visuelle

plot(degree.distribution(g3))

Question 16 : Récupérez les deux scripts CORUM_complexes.Rmd et Utils.R, placez-les dans le même répertoire. Exécutez CORUM_complexes.Rmd. Expliquez ce que fait, pas-à-pas, ce script R. Expliquez précisement la partie du code qui a trait à BioMart. Expliquez également en deux ou trois lignes ce que fait précisément chaque fonction de Utils.R.