Impacto de la Lista Roja de Ecosistemas de la IUCN (II)

En contribuciones anteriores (aquí y aquí) he revisado diferentes formas de medir el impacto de las publicaciones científicas, ya sea utilizando el número de citas bibliográficas o usando indicadores de atención recibida en redes sociales y otros medios.

Un aspecto diferente de las publicaciones son las redes de colaboración que se forman por la coautoría de los artículos. Si nos fijamos quienes publican juntos y con que frecuencia podemos inferir sobre los procesos de formación de grupos de trabajo y las interacciones entre ellos.

Hoy voy a explorar estos aspectos usando dos colecciones de artículos científicos para comparar las redes de colaboración de cada uno de ellos.

Los datos

Ya les he hablado de la Lista Roja de Ecosistemas (LRE) de la Unión Internacional para la Conservación de la Naturaleza (UICN) en reiteradas ocasiones.

Para el ejercicio de hoy tomé un grupo de publicaciones relacionada con la LRE y lo comparé con un grupo similar de publicaciones de otros productos de conocimiento de la UICN. Específicamente tome los datos de las publicaciones destacadas reportadas en las páginas web oficiales de la Lista Roja de Ecosistemas, Lista Roja de Especies Amenazadas y la Base de datos de Áreas Importantes para la Biodiversidad. En estas páginas se mencionan más de cien publicaciones en total, pero solo incluí en el análisis las que pude consultar a través del sistema de información de CrossRef. A pesar de que este filtro, la mayoría de los artículos pudieron incluirse y trabajo bajo el supuesto de que no hay un sesgo sistemático en este procedimiento.

Primero cargo los datos guardados en un repositorio con dos matrices de datos. Cada matriz representa los autores (columnas) de una serie de publicaciones identificadas por su DOI (filas).

if (!exists("mtz.LRE")) {
   con <- url("https://github.com/jrfep/CEBA.LEE/raw/master/Rdata/20190324_pubsLRE.rda")
   load(con)
   close(con)
}

dim(mtz.LRE)
## [1]  53 286
dim(mtz.OTR)
## [1]  58 893

Vemos que ambos objetos tienen un número similar de trabajos, pero muy diferente número de autores totales. En mtz.LRE, las 53 publicaciones sobre Lista Roja de Ecosistemas fueron escritas por 286 co-autores, mientras que en mtz.OTR, las 58 publicaciones sobre Lista Roja de Especies y Áreas Importantes para la Biodiversidad fueron escritas por 893 co-autores.

Cargar paquetes estadísticos

Usamos el paquete igraph en el entorno de R.

require(igraph)

Grafos de coautoría

Convertimos la matriz de autores por publicaciones en una matriz de co-ocurrencia de autores (también llamada matriz de adyacencia) y luego la convertimos en un grafo con las funciones del paquete igraph:

co.LRE <- t(mtz.LRE) %*% mtz.LRE
g.LRE <- graph.adjacency(co.LRE,
                         weighted=TRUE,
                         mode="undirected",
                         diag=FALSE)

Como punto de comparación vamos a usar la matriz de coautores de los otros productos de conocimiento de UICN:

co.OTR <- t(mtz.OTR) %*% mtz.OTR
g.OTR <- graph.adjacency(co.OTR,
                         weighted=TRUE,
                         mode="undirected",
                         diag=FALSE)

Con estos objetos podemos empezar a explorar y comparar las propiedades de ambos grafos (red de coautores) y de sus vértices o nodos (autores dentro de la red).

Propiedades del grafo

Existen varios indicadores que permiten calcular las propiedades fundamentales de la red de colaboración como un todo.

Primero podemos ver las funciones que resumen información de los vértices del grafo y calculan el índice de centralización o centralidad por grados, autovalores o intermediación. En este caso el valor es dividido por el máximo teórico para un grafo con las mismas dimensiones, de tal forma que se obtiene una medida relativa de la centralidad.

centr_degree(g.LRE, mode="all", normalized=T)$centralization
## [1] 0.3559073
centr_degree(g.OTR, mode="all", normalized=T)$centralization
## [1] 0.5245432

Estos valores describen que tan bien conectados están los nodos en terminos del número de sus enlaces. En este caso la segunda matriz tienen más de la mitad del valor esperado para un grafo de dicho tamaño, pero la red de autores de LRE solo llega a un tercio.

centr_eigen(g.LRE, normalized=T)$centralization
## [1] 0.8258968
centr_eigen(g.OTR, normalized=T)$centralization
## [1] 0.7184867

En este indicador se miden la centralidad por influencia de los enlaces (enlaces hacia nodos con más enlaces). En este caso el grafo de LRE tienen un valor superior que se puede interpretar como una tendencia a mayor aglomeración de los enlaces o mayor dominancia de un grupo reducido de nodos.

centr_betw(g.LRE, normalized=T)$centralization
## [1] 0.1917151
centr_betw(g.OTR, normalized=T)$centralization
## [1] 0.0673502

Estos indicadores miden la interconección de un nodo entre grupos de nodos, y en este caso se obtiene un valor mayor para el grafo de LRE. Esto indica que hay menos caminos alternativos entre grupos de nodos, y por tanto mayor división en grupos o compartimientos en el grafo.

Existen otros indicadores igualmente informativos. Por ejemplo, la siguiente función calcula el promedio de la distancia mínima entre nodos.

mean_distance(g.LRE)
## [1] 2.394621
mean_distance(g.OTR)
## [1] 2.023558

En este caso la distancia promedio es mayor entre nodos del grafo de coautores de LRE.

Por otro lado la densidad se obtiene al dividir las conecciones o aristas del grafo entre el máximo número de aristas posibles según la cantidad de nodos existentes.

graph.density(g.LRE)
## [1] 0.08970678
graph.density(g.OTR)
## [1] 0.1458604

En este caso, el grafo basado en la matriz de LRE es menos denso que el otro conjunto.

Tomando estos resultados podemos decir que el grafo de LRE es en su conjunto menos denso, más compartimentalizado y tiene mayor dominancia de un menor número de nodos influyentes.

Visualización del grafo

Estas diferencias se hacen evidentes al comparar visualmente ambos grafos. En primer lugar utilizamos el algoritmo de Kamada-Kawai para calcular la ubicación óptima de los vértices de cada grafo, y luego procedemos a graficar el resultado.

l1 <- layout_with_kk(g.LRE)
l2 <- layout_with_kk(g.OTR)

## método alternativo para calcular ubicación de nodos
##l1 <- layout_with_graphopt(g.LRE)
##l2 <- layout_with_graphopt(g.OTR)

layout(matrix(c(1,2),byrow=T,ncol=2))

plot(g.LRE, layout=l1,vertex.color=rgb(.4,.6,.8,.5), vertex.size=4,vertex.label=NA) 
plot(g.OTR, layout=l2,vertex.color=rgb(.8,.4,.6,.5), vertex.size=4,vertex.label=NA)

plot of chunk plot grafo

Propiedades de los vértices

Las medidas anteriores representan los valores promedios o totales para un grafo, pero los valores calculados para cada vértice son muy variables.

layout(matrix(1:6,byrow=T,ncol=2))

hist(centr_degree(g.LRE)$res,col=rgb(.4,.6,.8,.5),
    main="Centralidad de grado",xlab="")
hist(centr_degree(g.OTR)$res,col=rgb(.8,.4,.6,.5),
    main="Centralidad de grado",xlab="")

hist(centr_eigen(g.LRE)$vector,col=rgb(.4,.6,.8,.5),
        main="Centralidad de auto-valor",xlab="")
hist(centr_eigen(g.OTR)$vector,col=rgb(.8,.4,.6,.5),
        main="Centralidad de auto-valor",xlab="")

hist(sqrt(centr_betw(g.LRE)$res),col=rgb(.4,.6,.8,.5),
        main="Intermediación (raíz cuadrada)",xlab="")
hist(sqrt(centr_betw(g.OTR)$res),col=rgb(.8,.4,.6,.5),
        main="Intermediación (raíz cuadrada)",xlab="")

plot of chunk indicadores

Aquellos nodos con valores altos de alguna de estas medidas tienen una importancia excepcional dentro del grafo, y por ellos podemos inferir algunas propiedades de los autores representados en estos nodos. Por ejemplo, podemos calcular grado e intermediación de cada nodo, y mostrar una selección de nodos con altos valores en ambos indicadores:

vert.info <-data.frame(deg=degree(g.LRE, mode="all"),
      bet=betweenness(g.LRE))

tail(vert.info[order(rank(vert.info[,1])+rank(vert.info[,2])),])
##                     deg       bet
## miller rm            61 1010.6307
## nicholson e          78  769.7448
## zambrana-torrelio c  57 7842.4092
## oliveira-miranda ma  82 1392.3485
## rodriguez jp         98 1925.5357
## keith da            127 6822.7393

Entre estos seis autores David A. Keith es el que tiene mayor número de colaboraciones, mientras que Carlos Zambrana-Torrelio es el que tiene mayor conección entre grupos.

Visualización de nodos en el grafo

Podemos utilizar esta información para mejorar la visualización del grafo y sus elementos. Por ejemplo, podemos usar estas variables para generar un gradiente de colores que indiquen el balance entre centralidad de grados e intermediación.

En este caso usamos el color rojo para indicar grado y el verde para indicar intermediación, la mezcla de ambos genera valores amarillos. Los tonos claros indican valores altos de uno u otro indicador y los oscuros indican valores bajos.

clrs <- rgb(rank(vert.info[,1])/nrow(vert.info),
     rank(vert.info[,2])/nrow(vert.info),0)

plot(g.LRE, layout=l1, vertex.color=clrs, vertex.size=8,vertex.label=NA)

plot of chunk plot grafo3

Una alternativa para mejorar la visualización (sobretodo pensando en personas con daltonismo) es combinar tonalidad y tamaño en la visualización. En este caso, los tonos más brillantes indica mayores valores de intermediación, y el tamaño indica la centralidad de grado.

clrs <- rgb(0,rank(vert.info[,2])/nrow(vert.info),0,.75)
tmñs <- sqrt(vert.info[,1])
plot(g.LRE, layout=l1, vertex.color=clrs, vertex.size=tmñs,vertex.label=NA)

plot of chunk plot grafo4

También podemos seleccionar y etiquetar vértices específicos para ubicarlos en el grafo:

slc <- rev(rownames(tail(vert.info[order(rank(vert.info[,1])+rank(vert.info[,2])),])))

nmbrs <- V(g.LRE)$name
##nmbrs <- ifelse(nmbrs %in% slc,nmbrs,NA)
nmbrs <- match(nmbrs,slc)
clrs <- ifelse(is.na(nmbrs),"grey","white")
tmñs <- ifelse(is.na(nmbrs),2,10)

plot(g.LRE, layout=l1, vertex.color=clrs, vertex.size=tmñs,
        vertex.label=nmbrs,vertex.label.cex=1.2,
        vertex.label.color="black",vertex.label.font=2)

legend("bottomright",slc,pch=as.character(1:6),ncol=1)

plot of chunk plot grafo5

En este último gráfico destaca la ubicación de CZT como el autor que conecta un grupo grande de coautores con el resto del grafo. Esta posición es la que se refleja en su alto índice de intermediación.

Componentes y grupos

Como hemos visto un grafo puede contener varios subconjuntos de autores que están completamente aislados del resto (las “islas” de nodos separadas del resto), o que están atados al grafo por un número reducido de conección (como en el caso de los coautores de CZT).

Para calcular el número de componentes desconectados usamos la función clusters

sizes(clusters(g.LRE))
## Community sizes
##   1   2   3   4   5   6   7   8   9  10  11  12  13  14 
## 210  16   3  11  10   5   3   2   5   2   6   6   5   2

Vemos un componente grande y el resto mucho más pequeños. Es posible descomponer el grafo y analizarlos estos subconjuntos por separado. En este caso nos vamos a fijar en el componente que aglutina la mayoría de los co-autores y repetimos algunos pasos anteriores, pero esta vez usamos un algoritmo diferente para ubicar los vértices.

c.LRE <- decompose(g.LRE, min.vertices=2)

vert.info <-data.frame(deg=degree(c.LRE[[1]], mode="all"),
      bet=betweenness(c.LRE[[1]]))

clrs <- rgb(0,rank(vert.info[,2])/nrow(vert.info),0,.75)
tmñs <- sqrt(vert.info[,1])*1.2
nmbrs <- V(c.LRE[[1]])$name
nmbrs <- match(nmbrs,slc)

l3 <- layout_with_graphopt(c.LRE[[1]])


plot(c.LRE[[1]], layout=l3, vertex.color=clrs, vertex.size=tmñs,
        vertex.label=nmbrs,vertex.label.cex=1.2,
        vertex.label.color="black",vertex.label.font=2)