4 de julio de 2011

Modularidad y gráficos de independencia condicional

El concepto de modularidad es usado en biología desde las proteínas hasta los ecosistemas, así que es muy probable que, alguna vez, tengan la necesidad de aplicar algún análisis para identificar módulos a sus datos. En el caso de un fenotipo complejo, puede pensarse en forma intuitiva que aquellos rasgos provenientes del mismo módulo se encuentran más relacionados entre sí que rasgos de provenientes de módulos distintos. En términos estadísticos, los módulos podrían identificarse examinando los patrones de correlación entre caracteres. Por supuesto, solamente estamos identificando un patrón, pero luego nos gustará saber qué proceso generó ese patrón, y entraremos al frondoso mundo de las clases de módulos (el cual dejo para otro post).

Así que nuestro trabajo será, cual viejos anatomistas, cortar donde la correlación sea débil. Y aquí nuestra vida se complica, porque hay demasiadas técnicas para usar el bisturí. Recientemente, Christian Klingenberg propuso una técnica elegante: comparar todas las formas posibles de disección, y elegir aquella que asegure módulos más integrados internamente y menos relacionados entre sí. Creo que es la mejor aproximación a la “definición intuitiva”, pero pasará un tiempo hasta que sea de uso estandarizado y no sólo en el campo de la morfometría geométrica.

La mayor parte de las técnicas clásicas de identificar módulos consiste en convertir una matriz de covarianza o correlación en una red. Aquellos valores de correlación superiores a cierto “umbral” se mantendrán en la red como conexiones entre rasgos. Los valores inferiores desaparecerán ya que, se supone, corresponden a uniones débiles entre módulos. Como la técnica para encontrar ese umbral de Paul Magwene (ver el paper del 2001) parece ser “popular”, o al menos eso indica el número de citas, voy a describir como realizarla en R, Para la explicación teórica de este método, por favor consulten el paper o a su autor.

Para empezar, reproduzco los valores de la tabla con correlaciones de medidas de gallos que sale al principio del paper. Para otros datos, pueden obtener su matriz de correlación aplicando la sencilla función cor y el número de observaciones con nrow.

#Matriz de correlación (A) y número de observaciones (N)
A<-matrix(c(
1.000,0.583,0.621,0.603,0.569,0.602,
0.583,1.000,0.584,0.526,0.515,0.548,
0.621,0.584,1.000,0.937,0.877,0.874,
0.603,0.526,0.937,1.000,0.878,0.894,
0.569,0.515,0.877,0.878,1.000,0.926,
0.602,0.548,0.874,0.894,0.926,1.000),6,6)
N<-276

#Obtengo la matriz inversa (B)
B<-solve(A)

#Obtengo la matriz de correlaciones parciales (C)
C<-cov2cor(B)*(-1)

#Obtengo la matriz de edge exclusion deviance (D)
D<--N*log(1-(C^2))

#Guardo en (P) la significancia de las devianzas
P<-pchisq(D,1, lower=F)

#Obtengo la matriz con la fuerza de las “conexiones” (edge strength)
S<--0.5*log(1-(C^2))

#Matriz de adyacencia. Las correlaciones por debajo del umbral (no #significativas según P) son reemplazadas por 0,
#y aquellas superiores al umbral, por 1.

p<-c(P)
adj<-numeric(length=length(p))
for(i in 1: length(p)) if (p[i]<0.05) adj[i]<-1 else adj[i]<-0
Adj<-matrix(adj,nrow(P),ncol(P))

Finalmente el dibujo (conditional independence graphs, en cierto lunfardo). Para esto usaremos el paquete network. La función as.network permite convertir la matriz de adyacencia en una red. Modifiqué algunos parámetros de plot a mi gusto, en particular puse una presentación circular, que facilita las comparaciones entre matrices. Para ver otras opciones, revisen ?plot.network


library(network)
plot(as.network(Adj), mode="circle", usearrows=F,
vertex.col="white", edge.lwd=S*100,
label= c("L","B","H","U","F","T"))



Licencia Creative Commons
Este obra está bajo una licencia Creative Commons Atribución-NoComercial-CompartirIgual 2.5 Argentina.