[1] "Tom Hanks" "Gary Sinise" "Bill Paxton" "Kevin Bacon" "Ed Harris"
[6] "Sean Connery" "Robin Wright" "Nicolas Cage"
6 Análisis de Redes Sociales
Disciplina con base sólida de Matemática Aplicada: Teoría de Grafos y Matemática Discreta.
Unida con Álgebra Lineal: las bases de Pagerank (algoritmo de Google) The Mathematics of Google Search.
Describir las relaciones entre los elementos de una red y extraer conocimiento acerca de las estructuras sociales que existen en esa red. Tópico de enorme interés para extraer conocimiento de redes sociales en cualquier área.
en una red los actores no intervienen aislados
decribir todos los actores intervinientes en las redes
redes de alta complejidad
Existen muy destacadas aplicaciones para SNA:
Gephi
Exploratory Data Analysis: intuition-oriented analysis by networks manipulations in real time.
Link Analysis: revealing the underlying structures of associations between objects.
Social Network Analysis: easy creation of social data connectors to map community organizations and small-world networks.
Biological Network analysis: representing patterns of biological data.
Cytoscape
-
Cytoscape is an open source software platform for visualizing molecular interaction networks and biological pathways and integrating these networks with annotations, gene expression profiles and other state data.
Library for visualization
6.1 R for SNA
Usaremos el paquete igraph. Nos servirá para analizar más adelante datos extraído de Twiter.
Ventajas de usar R:
Reproducible research no es posible con las aplicaciones GUI.
Herramientas sólidas para manipular los datos.
Cada vez más paquetes diseñados para hacer de R una herramienta completa de análisis de redes.
Paquetes statnet y igraph.
Thomas Lin Pedersen ha publicado los paquetes tidygraph y ggraph, que aprovechan la potencia de igraph de forma coherente con el flujo de trabajo de tidyverse.
Crear gráficos de red interactivos con el marco htmlwidgets que traduce el código de R a JavaScript.
6.1.1 Elementos de una red
- nodos o vértices de grafo (nodes, vertices)
- arcos o enlaces (edges, links)
[,1] [,2]
[1,] "Tom Hanks" "Gary Sinise"
[2,] "Tom Hanks" "Robin Wright"
[3,] "Gary Sinise" "Robin Wright"
[4,] "Tom Hanks" "Gary Sinise"
[5,] "Tom Hanks" "Bill Paxton"
[6,] "Tom Hanks" "Kevin Bacon"
[7,] "Tom Hanks" "Ed Harris"
[8,] "Gary Sinise" "Bill Paxton"
[9,] "Gary Sinise" "Kevin Bacon"
[10,] "Gary Sinise" "Ed Harris"
[11,] "Bill Paxton" "Kevin Bacon"
[12,] "Bill Paxton" "Ed Harris"
[13,] "Kevin Bacon" "Ed Harris"
[14,] "Ed Harris" "Sean Connery"
[15,] "Ed Harris" "Nicolas Cage"
[16,] "Sean Connery" "Nicolas Cage"
Nodos y arcos pueden contender atributos adicionales con importante información:
Warning: `graph.edgelist()` was deprecated in igraph 2.0.0.
ℹ Please use `graph_from_edgelist()` instead.
[1] "Forest Gump" "Forest Gump" "Forest Gump" "Apollo 13" "Apollo 13"
[6] "Apollo 13" "Apollo 13" "Apollo 13" "Apollo 13" "Apollo 13"
[11] "Apollo 13" "Apollo 13" "Apollo 13" "The Rock" "The Rock"
[16] "The Rock"

6.1.2 Representación de redes
6.1.2.1 Grafos como listas de arcos
data.frame o matriz (si los datos del mismo tipo) que contiene dos columnas:
- primera columna: nodos que son el origen de una conexión
- segunda columna: nodos que son el destino de la conexión
Si el sentido es importante, la red se denomina dirigida, en otro caso, no dirigida.
alumnos1 <- c("Luis", "Ana", "Fran", "Pedro", "Laura", "Susana")
alumnos2 <- c("Juan", "Jose", "Amalia", "Lucía", "Maite", "Eduardo")
grupos <- data.frame(integrante1 = alumnos1, integrante2 = alumnos2, stringsAsFactors = F)
print(grupos) integrante1 integrante2
1 Luis Juan
2 Ana Jose
3 Fran Amalia
4 Pedro Lucía
5 Laura Maite
6 Susana Eduardo
str(grupos)'data.frame': 6 obs. of 2 variables:
$ integrante1: chr "Luis" "Ana" "Fran" "Pedro" ...
$ integrante2: chr "Juan" "Jose" "Amalia" "Lucía" ...
6.1.2.2 Grafos como matrices
# Se pueden usar matrices 'sparse'
A <- rbind(c(0,1,0), c(1,0,1), c(1,0,0))
nodeNames <- c("A","B","C")
dimnames(A) <- list(nodeNames, nodeNames)
A A B C
A 0 1 0
B 1 0 1
C 1 0 0
str(A) num [1:3, 1:3] 0 1 1 1 0 0 0 1 0
- attr(*, "dimnames")=List of 2
..$ : chr [1:3] "A" "B" "C"
..$ : chr [1:3] "A" "B" "C"
Caminos de longitud dos, tres, etc:
# Multiplicación matricial
A2 <- A %*% A
A2 A B C
A 1 0 1
B 1 1 0
C 0 1 0
A3 <- A %*% A %*% A
A3 A B C
A 1 1 0
B 1 1 1
C 1 0 1
Representado arcos:
Arcos <- rbind(c("A","B"), c("B","A"), c("B","C"), c("C","A"))
Arcos [,1] [,2]
[1,] "A" "B"
[2,] "B" "A"
[3,] "B" "C"
[4,] "C" "A"
Usando tidverse:
library(tidyr)
Attaching package: 'tidyr'
The following object is masked from 'package:igraph':
crossing
alumnos1 <- c("Luis", "Ana", "Fran", "Pedro", "Laura", "Susana")
alumnos2 <- c("Juan", "Jose", "Amalia", "Lucía", "Maite", "Eduardo")
node_list_alumnos <- tibble(id = unique(c(alumnos1,alumnos2)))
node_list_alumnos# A tibble: 12 × 1
id
<chr>
1 Luis
2 Ana
3 Fran
4 Pedro
5 Laura
6 Susana
7 Juan
8 Jose
9 Amalia
10 Lucía
11 Maite
12 Eduardo
edge_list_alumnos <- tibble(from = alumnos1, to = alumnos2)
edge_list_alumnos# A tibble: 6 × 2
from to
<chr> <chr>
1 Luis Juan
2 Ana Jose
3 Fran Amalia
4 Pedro Lucía
5 Laura Maite
6 Susana Eduardo
6.2 igraph
# Instalar la primera vez - descomentar
#install.packages("igraph")
#install.packages("igraphdata")
library(igraph)
library(igraphdata)
# Importar la red de datasets ya establecidos: igraphdata
# Limpia la memoria - Cuidado - borra todas las variables
rm(list=ls())
#Lista de datasets de redes de nodos en igraph
# data(package="igraphdata")
# El paquete tiene un conjunto de datasets
# Carga data set y vemos que contiene
#Red social entre miembros de club de karate de universidad
data(karate,package="igraphdata")
plot(karate)This graph was created by an old(er) igraph version.
Call upgrade_graph() on it to use with the current igraph version
For now we convert it on the fly...

6.2.1 Acceder a elementos de grado
# UKfaculty: Friendship network of a UK university faculty
data(UKfaculty)
plot(UKfaculty)This graph was created by an old(er) igraph version.
Call upgrade_graph() on it to use with the current igraph version
For now we convert it on the fly...

UKfacultyIGRAPH 6f42903 D-W- 81 817 --
+ attr: Type (g/c), Date (g/c), Citation (g/c), Author (g/c), Group
| (v/n), weight (e/n)
+ edges from 6f42903:
[1] 57->52 76->42 12->69 43->34 28->47 58->51 7->29 40->71 5->37 48->55
[11] 6->58 21-> 8 28->69 43->21 67->58 65->42 5->67 52->75 37->64 4->36
[21] 12->49 19->46 37-> 9 74->36 62-> 1 15-> 2 72->49 46->62 2->29 40->12
[31] 22->29 71->69 4-> 3 37->69 5-> 6 77->13 23->49 52->35 20->14 62->70
[41] 34->35 76->72 7->42 37->42 51->80 38->45 62->64 36->53 62->77 17->61
[51] 7->68 46->29 44->53 18->58 12->16 72->42 52->32 58->21 38->17 15->51
[61] 22-> 7 22->69 5->13 29-> 2 77->12 37->35 18->46 10->71 22->47 20->19
+ ... omitted several edges
V(UKfaculty)+ 81/81 vertices, from 6f42903:
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
[26] 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
[51] 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
[76] 76 77 78 79 80 81
E(UKfaculty)+ 817/817 edges from 6f42903:
[1] 57->52 76->42 12->69 43->34 28->47 58->51 7->29 40->71 5->37 48->55
[11] 6->58 21-> 8 28->69 43->21 67->58 65->42 5->67 52->75 37->64 4->36
[21] 12->49 19->46 37-> 9 74->36 62-> 1 15-> 2 72->49 46->62 2->29 40->12
[31] 22->29 71->69 4-> 3 37->69 5-> 6 77->13 23->49 52->35 20->14 62->70
[41] 34->35 76->72 7->42 37->42 51->80 38->45 62->64 36->53 62->77 17->61
[51] 7->68 46->29 44->53 18->58 12->16 72->42 52->32 58->21 38->17 15->51
[61] 22-> 7 22->69 5->13 29-> 2 77->12 37->35 18->46 10->71 22->47 20->19
[71] 19->31 68->13 49->69 30->63 5->49 53->75 62->57 73->81 29->69 71->40
[81] 19->58 49->42 37-> 5 18-> 2 20->80 75->53 15->54 76->58 40->23 5->12
[91] 20->54 6->47 51->14 78-> 4 52->49 29->55 27->35 66-> 6 21->29 4->61
+ ... omitted several edges
V(UKfaculty)+ 81/81 vertices, from 6f42903:
[1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
[26] 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
[51] 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
[76] 76 77 78 79 80 81
str(UKfaculty)Class 'igraph' hidden list of 10
$ : num 81
$ : logi TRUE
$ : num [1:817] 56 75 11 42 27 57 6 39 4 47 ...
$ : num [1:817] 51 41 68 33 46 50 28 70 36 54 ...
$ : num [1:817] 580 411 719 376 569 215 533 620 527 592 ...
$ : num [1:817] 241 433 238 352 258 274 115 24 263 25 ...
$ : num [1:82] 0 6 23 27 37 65 74 91 93 101 ...
$ : num [1:82] 0 9 28 32 40 50 58 76 82 87 ...
$ :List of 4
..$ : num [1:3] 1 0 1
..$ :List of 4
.. ..$ Type : chr "TSPE"
.. ..$ Date : chr "Mon Mar 19 21:56:02 2007"
.. ..$ Citation: chr "Nepusz T., Petroczi A., Negyessy L., Bazso F.: Fuzzy communities and the concept of bridgeness in complex netwo"| __truncated__
.. ..$ Author : chr "Nepusz T., Petroczi A., Negyessy L., Bazso F."
..$ :List of 1
.. ..$ Group: num [1:81] 3 1 3 3 2 2 2 1 3 2 ...
..$ :List of 1
.. ..$ weight: num [1:817] 4 14 4 4 10 2 6 2 4 4 ...
$ :<environment: 0x10d2945c0>
head(E(UKfaculty)$weight)[1] 4 14 4 4 10 2
head(V(UKfaculty)$Group)[1] 3 1 3 3 2 2
6.2.2 Construir/Modificar un grafo
Añadir arcos a un grafo vacío:
# Un grafo dirigido vacío
g <- make_empty_graph(n = 0, directed = TRUE)
gIGRAPH 46cb55c D--- 0 0 --
+ edges from 46cb55c:
g <- g + vertices(c("A","B","C"))
gIGRAPH a4d512a DN-- 3 0 --
+ attr: name (v/c)
+ edges from a4d512a (vertex names):
# Arcos: A to C , B to C
g <- g + edges(c("A","C", "B","C"))
gIGRAPH 1f35f8b DN-- 3 2 --
+ attr: name (v/c)
+ edges from 1f35f8b (vertex names):
[1] A->C B->C
# Eliminar arco A
g <- g - V(g)["A"]
gIGRAPH 587042d DN-- 2 1 --
+ attr: name (v/c)
+ edge from 587042d (vertex names):
[1] B->C
# Eliminará todos los arcos conectados con ALista de arcos: graph() and get.edgelist():
# Un grafo dirigido vacío
# graph() id desde 1.
g1 <- graph( c(1,2, 1,3, 2,3, 3,4 ));g1IGRAPH 8dd89bc D--- 4 4 --
+ edges from 8dd89bc:
[1] 1->2 1->3 2->3 3->4
summary(g1)IGRAPH 8dd89bc D--- 4 4 --
plot(g1)
# El parámetro "directed" a FALSE para
# grafos no dirigidos.
g2 <- graph( c(1,2, 1,3, 2,3, 3,4 , 3, 5, 1, 3), directed=FALSE); g2 IGRAPH 4bc3f24 U--- 5 6 --
+ edges from 4bc3f24:
[1] 1--2 1--3 2--3 3--4 3--5 1--3
summary(g2)IGRAPH 4bc3f24 U--- 5 6 --
plot(g2)
#Obtener la lista de arcos a partir de un grafo
edgelist<-get.edgelist(g2) ; edgelistWarning: `get.edgelist()` was deprecated in igraph 2.0.0.
ℹ Please use `as_edgelist()` instead.
[,1] [,2]
[1,] 1 2
[2,] 1 3
[3,] 2 3
[4,] 3 4
[5,] 3 5
[6,] 1 3
edgelist <- as_edgelist(g2) ; edgelist [,1] [,2]
[1,] 1 2
[2,] 1 3
[3,] 2 3
[4,] 3 4
[5,] 3 5
[6,] 1 3
# Obtener el grafo a partir de la lista de arcos
g3<-graph( t(edgelist)); g3; plot(g3)IGRAPH e29f9d2 D--- 5 6 --
+ edges from e29f9d2:
[1] 1->2 1->3 2->3 3->4 3->5 1->3

g3<-graph( edgelist); g3; plot(g3)IGRAPH d0a7d53 D--- 5 6 --
+ edges from d0a7d53:
[1] 1->1 2->3 3->1 2->3 3->4 5->3

# algunos parámetros de plot
plot(g3,
vertex.color="green",
edge.arrow.size=0.5,
vertex.size=25,
edge.curved=0.5,
layout_as_star=TRUE)
Matrices de adyacencia: graph.adjacency(), get.adjacency()
adjm_u<-matrix(
c(0, 1, 0, 0, 1, 0,
1, 0, 1, 0, 1, 0,
0, 1, 0, 1, 0, 0,
0, 0, 1, 0, 1, 1,
1, 1, 0, 1, 0, 0,
0, 0, 0, 1, 0, 0),
nrow=6,
ncol=6,
byrow = TRUE)
#grafo a partir de matriz de adyacencia
g_adj_u <- graph.adjacency(adjm_u, mode="undirected") Warning: `graph.adjacency()` was deprecated in igraph 2.0.0.
ℹ Please use `graph_from_adjacency_matrix()` instead.
plot(g_adj_u)
# Matriz de adyacencia a partir de grafo
A <- get.adjacency(g_adj_u); AWarning: `get.adjacency()` was deprecated in igraph 2.0.0.
ℹ Please use `as_adjacency_matrix()` instead.

6 x 6 sparse Matrix of class "dgCMatrix"
[1,] . 1 . . 1 .
[2,] 1 . 1 . 1 .
[3,] . 1 . 1 . .
[4,] . . 1 . 1 1
[5,] 1 1 . 1 . .
[6,] . . . 1 . .
A <- as_adjacency_matrix(g_adj_u, sparse = FALSE)
A [,1] [,2] [,3] [,4] [,5] [,6]
[1,] 0 1 0 0 1 0
[2,] 1 0 1 0 1 0
[3,] 0 1 0 1 0 0
[4,] 0 0 1 0 1 1
[5,] 1 1 0 1 0 0
[6,] 0 0 0 1 0 0
Grafo a partir de data frame
# Primero, crear el data frame
node1 = c("Ella", "Tu", "El"); node2 = c("El", "Ella", "Tu")
weight = c(10, -2, 3)
df = data.frame(node1, node2, weight); df node1 node2 weight
1 Ella El 10
2 Tu Ella -2
3 El Tu 3
# Crear el grafo
g <- graph.data.frame(df, directed=FALSE); gWarning: `graph.data.frame()` was deprecated in igraph 2.0.0.
ℹ Please use `graph_from_data_frame()` instead.
IGRAPH e5aee7e UNW- 3 3 --
+ attr: name (v/c), weight (e/n)
+ edges from e5aee7e (vertex names):
[1] Ella--El Ella--Tu Tu --El
plot(g)Warning in v(graph): Non-positive edge weight found, ignoring all weights
during graph layout.

# Si se conocen los vértices
# g <- graph.data.frame(df, vertices=listvertices, directed=FALSE);g
# Obtener los nombres de los nodos
V(g)$name [1] "Ella" "Tu" "El"
# Obtener los pesos de los arcos
E(g)$weight [1] 10 -2 3
Grafo a partir de literales
#?graph_from_literal
g <- graph_from_literal(A--C, A-+D, C-+A, , D-+C)
gIGRAPH 057dd89 DN-- 4 3 --
+ attr: name (v/c)
+ edges from 057dd89 (vertex names):
[1] A->D C->A D->C
plot(g)
#IGRAPH DN-- 4 4 --
#+ attr: name (v/c)
#+ edges (vertex names):
#[1] A->D D->C D->B B->A
G3 <-graph_from_literal(A-B, B -+C)
plot(G3)
G3 <-graph_from_literal(A-B, B -C)
plot(G3)
grafo aleatorio
g_random <- sample_gnp(10, 0.2, directed = FALSE, loops = FALSE)
plot(g_random)
6.2.3 Visualización
Buscar ayuda de los comandos plot.igraph, igraph.plotting.
A continuación dibujamos algunos grafos interesantes:
#library(igraph)
# Trees
g <- make_tree(27, children=3)
g; plot(g)IGRAPH d7a4a52 D--- 27 26 -- Tree
+ attr: name (g/c), children (g/n), mode (g/c)
+ edges from d7a4a52:
[1] 1-> 2 1-> 3 1-> 4 2-> 5 2-> 6 2-> 7 3-> 8 3-> 9 3->10 4->11 4->12 4->13
[13] 5->14 5->15 5->16 6->17 6->18 6->19 7->20 7->21 7->22 8->23 8->24 8->25
[25] 9->26 9->27

# Cliques
g <- make_full_graph(n=6)
g; plot(g)IGRAPH bcbb405 U--- 6 15 -- Full graph
+ attr: name (g/c), loops (g/l)
+ edges from bcbb405:
[1] 1--2 1--3 1--4 1--5 1--6 2--3 2--4 2--5 2--6 3--4 3--5 3--6 4--5 4--6 5--6

# Lattices
g <- make_lattice(dimvector = c(5,5), circular = FALSE)
V(g)$label <- NA
g; plot(g)IGRAPH 3088078 U--- 25 40 -- Lattice graph
+ attr: name (g/c), dimvector (g/n), nei (g/n), mutual (g/l), circular
| (g/l), label (v/l)
+ edges from 3088078:
[1] 1-- 2 1-- 6 2-- 3 2-- 7 3-- 4 3-- 8 4-- 5 4-- 9 5--10 6-- 7
[11] 6--11 7-- 8 7--12 8-- 9 8--13 9--10 9--14 10--15 11--12 11--16
[21] 12--13 12--17 13--14 13--18 14--15 14--19 15--20 16--17 16--21 17--18
[31] 17--22 18--19 18--23 19--20 19--24 20--25 21--22 22--23 23--24 24--25

#Stars
g <- make_star(n=10,mode = "undirected")
g; plot(g)IGRAPH 28977ee U--- 10 9 -- Star
+ attr: name (g/c), mode (g/c), center (g/n)
+ edges from 28977ee:
[1] 1-- 2 1-- 3 1-- 4 1-- 5 1-- 6 1-- 7 1-- 8 1-- 9 1--10

Anillo con conexiones cruzadas:
g <- make_ring(10, directed=TRUE, mutual=TRUE)
V(g)$name <- LETTERS[1:10]
g <- g + edges(9,5, 7,1, 1,5)
plot(g)
6.2.4 Layout
Un layout es un conjunto de coordenadas x,y preestablecidas. Se pueden especificar manualmente o usando layout_functions
Determina la posición de los nodos en la red. Hay layouts ya diseñados o puedes diseñarlo desde 0.
Intentar minimizar cruces de arcos.
Algoritmos que lo consiguen: por ejemplo - Kamada Kawai algorithm, the Fruchterman Reingold algorithm, etc.
Lykamada <- layout.kamada.kawai(g)
plot(g, layout=Lykamada)
Lyfruchtermant <- layout.fruchterman.reingold(g)
plot(g, layout=Lyfruchtermant)
lo <- layout_in_circle(g)
head(lo, n=4) [,1] [,2]
[1,] 1.000000 0.0000000
[2,] 0.809017 0.5877853
[3,] 0.309017 0.9510565
[4,] -0.309017 0.9510565
# lo es una matriz de coordenadas
lo [,1] [,2]
[1,] 1.000000 0.000000e+00
[2,] 0.809017 5.877853e-01
[3,] 0.309017 9.510565e-01
[4,] -0.309017 9.510565e-01
[5,] -0.809017 5.877853e-01
[6,] -1.000000 1.224647e-16
[7,] -0.809017 -5.877853e-01
[8,] -0.309017 -9.510565e-01
[9,] 0.309017 -9.510565e-01
[10,] 0.809017 -5.877853e-01
plot(g, layout=lo)
# See ?layout_ for a full list
# Para redes tipo árbol: layout_as_tree
gTree <- make_tree(15)
plot(gTree, layout=layout_as_tree(gTree, root = 1))
# layout como un grid
plot(g, layout=layout_on_grid(g))
Mallas:
library(igraph)
#Buscar en ayuda
#?igraph::layout
g <- make_tree(15)
set.seed(3952)
layout1 <- layout.fruchterman.reingold(g)
plot(g, layout=layout1)
# Otra malla diferente
plot(g, layout=layout.kamada.kawai)
# Malla interactiva - Ejecutar en consola
# tkplot(g, layout=layout.kamada.kawai)6.2.5 Dibujar grafos ponderados
V(g)$label.cex <- ...
V(g)$label.color <- ...
V(g)$frame.color <- ...
E(g)$color <- rgb(....
E(g)$width <- 6.2.6 Cambiar aspecto y propiedades de un grafo
V(g)$shape
V(g)$size
V(g)$color
- vertex.shape
- vertex.color
- vertex.size
- set_edge_attr
- set_vertex_attr
- set_graph_attr
plot(g, vertex.size = 20)
plot(g, vertex.size = 10, vertex.color = "blue", vertex.frame.color = NA, vertex.label = NA)
plot(g, vertex.size = 10, vertex.color = "blue", vertex.frame.color = NA, vertex.label.cex = .7, vertex.label = NA, edge.curved = .5, edge.arrow.size = .3, edge.width = .7)
Note: colores en R http://www.stat.columbia.edu/~tzheng/files/Rcolor.pdf
library(tidyverse)── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
✔ dplyr 1.1.4 ✔ purrr 1.0.2
✔ forcats 1.0.0 ✔ readr 2.1.5
✔ ggplot2 3.5.1 ✔ stringr 1.5.1
✔ lubridate 1.9.3 ✔ tibble 3.2.1
── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
✖ lubridate::%--%() masks igraph::%--%()
✖ dplyr::as_data_frame() masks tibble::as_data_frame(), igraph::as_data_frame()
✖ purrr::compose() masks igraph::compose()
✖ tidyr::crossing() masks igraph::crossing()
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag() masks stats::lag()
✖ purrr::simplify() masks igraph::simplify()
ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
g1random <- sample_gnp(10, p=0.4)
V(g1random)[1]$color <- "yellow"
g1random %>%
set_edge_attr("color",value = "blue") %>%
plot()
6.2.7 Ejemplos - plantillas
Plot vocales como rectángulos
g <- make_ring(10, directed=TRUE, mutual=TRUE)
V(g)$name <- LETTERS[1:10]
g <- g + edges(9,5, 7,1, 1,5)
plot(g)
vowel <- V(g)$name %in% c("A","E","I","O","U") + 1 # gives 1 or 2
plot(g, layout=lo, vertex.shape=c("circle", "square")[vowel])
#colores
plot(g, layout=lo, vertex.color=c("tomato2", "royalblue")[vowel])
#tamaño
plot(g, layout=lo, vertex.size=c(15,30)[vowel])
#Propiedades usando atributos
V(g)$shape <- "circle" # Aplicado a todos los vértices
V(g)$size <- 15
V(g)$color <- "orange"
isVowel <- V(g)$name %in% c("A","E","I","O","U")
# Sobreescribir los nodos vocales
V(g)[isVowel]$shape <- "square"
V(g)[isVowel]$color <- "royalblue"
V(g)[isVowel]$size <- 25
plot(g, layout=lo)
Propiedades de los arcos
E(g)$width <- 1
v1 <-V(g)[isVowel]
v1+ 3/10 vertices, named, from b3a2f90:
[1] A E I
E(g)[v1 %--% v1]$width <- 4
# Ver http://igraph.org/r/doc/igraph-es-indexing.html
plot(g, layout=lo)
#Arcos curvados
plot(g, layout=lo, edge.curved=0.3*which_mutual(g))
Agrupaciones por índices:
groupList <- list(vowelGroup = which(isVowel),
constGroup1 = c(2,3,4),
constGroup2 = c(6,7,8))
groupColours <- c(rgb(0,0.3,1,0.5),
rgb(0.8,0.4,0.1,0.5),
rgb(0.8,0.4,0.1,0.5))
plot(g, layout=layout_with_fr, # Fruchterman?Reingold layout
mark.groups=groupList, # Mark the groups
mark.col= groupColours,
# Eliminar el borde
mark.border = NA,
edge.curved=0.1*which_mutual(g))
text(0.45,0.1,"Vocales", cex=1.5)
text(0.5,0.9,"Grupo consonantes 1", cex=1.5)
text(-0.8,-1,"Grupo consonantes 2", cex=1.5)
6.3 Exportar grafos
igraph permite importar y exportar de/desde un considerable número de formatos. Se usan los comandos read_graph y write_graph. Un formato abierto (open) es graphml.
write_graph(g, "gr1.graphml", format="graphml")Otros formatos:
edgelist: Fichero de texto con arcos en cada línea.
pajek: Pajek es un programa popular en Windows para análisis de redes.
gml: Graph Modelling Language es uno de los formatos abiertos más populares.
graphml: Graph Markup Language es un formato abierto basado en XML.
dot: Formato usado por GraphViz.
** Gephi: Para exportar al formato nativo GEXF de Gephise usa el paquete rgexf al que puede convertirse desde un objeto igraph **
Referencias:
6.4 De Twitter
- El primer paso será extraer los términos usando las técnicas de text mining y crear una matriz de términos (DTM - Document Term Matrix:).
- Los documentos serían los tweets y los términos serían las palabras o grupos de palabras destacadas en los datos extraidos.
- Objetivo: Construir una red de términos (personas) basada en sus co-ocurrencias en los mismos tweets (pertenencia a los mismos grupos).
6.5 Medidas de bondad, calidad
Analysis of the Networks to extract knowledge.
<http://snap.stanford.edu/class/cs224w-2015/slides/06-applicationsI.pdf%5D
Locate people in the network for…
higher compensation
positive performance evaluations
more promotions
more good ideas
Ego network is a special type of network consisting of one central node and all other nodes directly connected to it. The central node is known as ego, while the other surrounding nodes directly connected to it are known as alters.
<https://medium.com/applied-data-science/the-google-vs-trick-618c8fd5359f%5D
<http://olizardo.bol.ucla.edu/classes/soc-111/lessons-winter-2022/5-lesson-egonet-metrics.html%5D
Vamos a usar este grafo como ejemplo de las medidas de bondad del grafo.
library(igraph)
g1 <- graph( c(1, 2, 1, 3, 2, 3,
3, 4, 3, 5, 1, 5,
4, 2, 3, 6, 4, 8,
8, 1, 9, 1, 10, 2,
7, 6, 5,10))
g1IGRAPH 0ac30aa D--- 10 14 --
+ edges from 0ac30aa:
[1] 1-> 2 1-> 3 2-> 3 3-> 4 3-> 5 1-> 5 4-> 2 3-> 6 4-> 8 8-> 1
[11] 9-> 1 10-> 2 7-> 6 5->10
summary(g1)IGRAPH 0ac30aa D--- 10 14 --
plot(g1)
Vértices, arcos
class(g1)[1] "igraph"
V(g1)+ 10/10 vertices, from 0ac30aa:
[1] 1 2 3 4 5 6 7 8 9 10
V(g1)[1]+ 1/10 vertex, from 0ac30aa:
[1] 1
E(g1)+ 14/14 edges from 0ac30aa:
[1] 1-> 2 1-> 3 2-> 3 3-> 4 3-> 5 1-> 5 4-> 2 3-> 6 4-> 8 8-> 1
[11] 9-> 1 10-> 2 7-> 6 5->10
E(g1)[1]+ 1/14 edge from 0ac30aa:
[1] 1->2
class(V(g1))[1] "igraph.vs"
class(E(g1))[1] "igraph.es"
6.5.1 Centrality
Es una propiedad de la posicion del nodo en la red, de la importancia de los nodos en un grafo.
Contribución del nodo a la estructura de la red.
Un nodo puede ser importante por ejemplo, porque:
si lo eliminamos, la red podría desconectarse
gran número de arcos de entrada-salida
Redes con alta centralidad tienen pocos nodos con muchas conexiones.
Redes con baja centralidad tienen muchos nodos con similar o menos conexiones.
Hay diferentes medidas de centralidad.
Sociológicamente nodos centrales identifican líderes, de prestigio, con gran autonomía, que influencian a los que les siguen.
Ver https://en.wikipedia.org/wiki/Centrality#PageRank_centrality
6.5.2 Degree
Número de arcos conectados a un vértice. Señala la importancia de un vértice o el nivel de actividad del vértice en la red.
Cómo de central es un nodo en la red
Cuántos arcos de entrada-salida tiene o con cuántos nodos se conecta directamente via un arco.
centr_degree, igraph::degree
g1IGRAPH 0ac30aa D--- 10 14 --
+ edges from 0ac30aa:
[1] 1-> 2 1-> 3 2-> 3 3-> 4 3-> 5 1-> 5 4-> 2 3-> 6 4-> 8 8-> 1
[11] 9-> 1 10-> 2 7-> 6 5->10
plot(g1)
igraph::degree(g1) [1] 5 4 5 3 3 2 1 2 1 2
igraph::degree(g1, mode="in") [1] 2 3 2 1 2 2 0 1 0 1
igraph::degree(g1, mode="out") [1] 3 1 3 2 1 0 1 1 1 1
deg <- centr_degree(g1)
deg$res
[1] 5 4 5 3 3 2 1 2 1 2
$centralization
[1] 0.1358025
$theoretical_max
[1] 162
6.5.3 Betweenness
Mide el grado en el que la información fluye a través de un vértice particular y su importancia relativa como un intermediario en la red.
Un ejemplo claro, en una estrella el nodo central se encuentra en los caminos más cortos entre cualesquiera nodos de la red.
Describe el potencial de controlar flujos a través de la red. Nodos con alto “betweenness” tienen gran poder porque pueden parar los flujos de información.
Describe nodos que son conexiones clave o puentes entre grupos de nodos.
- El número de caminos más cortos que pasan por un nodo dado (medida relativa) - la suma de las longitudes de los caminos más cortos entre otros nodos pasando por el nodo, dividida por las longitudes de camino más cortas (no necesariamente a través del nodo) entre los otros nodos.
igraph::betweenness(g1) [1] 14 14 25 11 6 0 0 6 0 6
Por el vértice 6 no pasa ningún *camino más corto* entre dos vértices.
Por el vértice 3 pasan 25 *caminos más cortos* entre dos vértices.
6.5.4 Edge_betweenness
Similar al anterior pero teniendo en cuenta cada arco.
g1 <- set.edge.attribute(g1, "weight", value= 1)Warning: `set.edge.attribute()` was deprecated in igraph 2.0.0.
ℹ Please use `set_edge_attr()` instead.
bg <- edge_betweenness(g1)
plot(g1, edge.label = bg)
6.5.5 Closeness
Distancia a otros nodos. Un nodo con valor alto de este estimador es más central y puede difundir la información a muchos otros nodos.
Se obtiene como 1 divido por la suma de las distancias geodésicas desde un vértice al resto. Alcanzará su valor máximo cuando un vértice esté conectado a todos los demás. Longitud media de los caminos más cortos (geodésicos).
Mide cuantos pasos se requieren desde un vértice para alcanzar el resto de vértices de la red.
Caminos cortos entre vértices señalan que estos están cercanos unos a otros.
igraph::closeness(g1) [1] 0.08333333 0.05882353 0.08333333 0.06250000 0.04000000 NaN
[7] 1.00000000 0.06250000 0.05000000 0.04761905
6.5.6 Eigenvector
No todas las conexiones tienen la misma importancia - medida de la importancia de un nodo.
La medida Eigenvector Centrality se calcula como el autovalor de mayor módulo de la matriz de adyacencia que contiene los pesos.
a high score to vertices that either have a lot of connections, or are connected to someone with a lot of connections
eigen_centrality(g1)$vector
[1] 0.94446858 0.87756472 1.00000000 0.67054129 0.68544140 0.31214483
[7] 0.08943566 0.46273222 0.27060890 0.44783212
$value
[1] 3.490161
$options
$options$bmat
[1] "I"
$options$n
[1] 10
$options$which
[1] "LA"
$options$nev
[1] 1
$options$tol
[1] 0
$options$ncv
[1] 0
$options$ldv
[1] 0
$options$ishift
[1] 1
$options$maxiter
[1] 3000
$options$nb
[1] 1
$options$mode
[1] 1
$options$start
[1] 1
$options$sigma
[1] 0
$options$sigmai
[1] 0
$options$info
[1] 0
$options$iter
[1] 6
$options$nconv
[1] 1
$options$numop
[1] 20
$options$numopb
[1] 0
$options$numreo
[1] 15
6.5.7 Pagerank
Algoritmo de Google para realizar un ranking con la importancia de los resultados de la búsqueda.
Nodos son más importantes si tienen muchos enlaces de entrada.
page.rank(g1)Warning: `page.rank()` was deprecated in igraph 2.0.0.
ℹ Please use `page_rank()` instead.
$vector
[1] 0.09371203 0.18396681 0.20662720 0.08224805 0.10879979 0.10239617
[7] 0.02370367 0.05865910 0.02370367 0.11618350
$value
[1] 1
$options
NULL
6.5.8 Diameter
El máximo camino más corto entre cualquier par de nodos. En grafos muy grandes indica la posibilidad de que la información se difunda más o menos fácilmente. El algoritmo tiene costo $O(n^3)$. En Twitter hay cientos de millones de usuarios,…
diameter - el camino más largo entre dos nodos.
plot(g1)
diameter(g1)[1] 6
6.5.9 Caminos y distancias
Caminos de un vértice a otro o de grupos de vértices a otros.
Distancia geodésica: El menor número de arcos a atravesar para conectar dos nodos.
sp <- shortest_paths(g1, from="1", to="10")
sp$vpath[[1]]
+ 3/10 vertices, from 0ac30aa:
[1] 1 5 10
sp1 <- shortest_paths(g1, from="1", to="9")Warning in shortest_paths(g1, from = "1", to = "9"): At
vendor/cigraph/src/paths/dijkstra.c:534 : Couldn't reach some vertices.
sp1$vpath[[1]]
+ 0/10 vertices, from 0ac30aa:
distances(g1) [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,] 0 1 1 2 1 2 3 1 1 2
[2,] 1 0 1 1 2 2 3 2 2 1
[3,] 1 1 0 1 1 1 2 2 2 2
[4,] 2 1 1 0 2 2 3 1 3 2
[5,] 1 2 1 2 0 2 3 2 2 1
[6,] 2 2 1 2 2 0 1 3 3 3
[7,] 3 3 2 3 3 1 0 4 4 4
[8,] 1 2 2 1 2 3 4 0 2 3
[9,] 1 2 2 3 2 3 4 2 0 3
[10,] 2 1 2 2 1 3 4 3 3 0
Relacionado con distancias:
distance_table, mean_distance
6.5.10 Clustering
Whether your friends are likely to be friends.
Grupos: Subconjunto de vértices que comparten características en común.
- Una primera forma es buscar los triángulos en el grafo. La medida de clustering (transitividad) es la frecuencia relativa de triángulos cerrados.
\[C=\\frac{3\*\\mbox{ número de triángulos }}{\\mbox{número de triples conectados}}\]
6.5.11 Transitivity
friends of friends to be friends and enemies of enemies to be enemies
Probabilidad de que vértices adyacentes de un vértice estén conectados - se denomina también coeficiente de agrupación o clustering.
transitivity, shortest_paths
6.5.11.1 Global clustering:
transitivity(g1, type = "global")[1] 0.2571429
6.5.11.2 Local clustering
Fracción de triples conectados a través de cada vértice que son cerrados.
transitivity(g1, type = "local") [1] 0.2000000 0.3333333 0.3000000 0.3333333 0.3333333 0.0000000 NaN
[8] 0.0000000 NaN 0.0000000
7 Otras medidas y definiciones
Densidad: Número de conexiones respecto al total de conexiones posibles. Un grafo completo tiene una densidad igual a 1 -
edge_density.Popularidad: nodos que son centrales tienden a ser más populares.
Cliques: todos con todos -
clique_num(g, min=k)encuenta cliques con un mínimo de k vértices.Componentes: Una componente es el conjunto de vértices de la que tienen conexiones entre ellos. Una red puede tener varias componentes -
componentsNodos a distancia k -
random_walk.Hub, Authorities -
hub_score, authority.scoreun nodo se denomina hub tiene muchos enlaces de salida y se denomina authorities si tiene muchos de entrada.detección de comunidades:
cluster_edge_betweenness