2011-11-14 17 views
12

Tengo un archivo de entrada con una lista de ~ 50000 clusters y presencia de varios factores en cada uno de ellos (~ 10 millones de entradas en total), consulte a ejemplo más pequeña a continuación:Diagrama de Venn de la lista de clústeres y factores concurrentes

set.seed(1) 
x = paste("cluster-",sample(c(1:100),500,replace=TRUE),sep="") 
y = c(
    paste("factor-",sample(c(letters[1:3]),300, replace=TRUE),sep=""), 
    paste("factor-",sample(c(letters[1]),100, replace=TRUE),sep=""), 
    paste("factor-",sample(c(letters[2]),50, replace=TRUE),sep=""), 
    paste("factor-",sample(c(letters[3]),50, replace=TRUE),sep="") 
) 
data = data.frame(cluster=x,factor=y) 

con un poco de ayuda de otra pregunta, lo tengo para producir un gráfico circular para la co-ocurrencia de factores como esto:

counts = with(data, table(tapply(factor, cluster, function(x) paste(as.character(sort(unique(x))), collapse='+')))) 
pie(counts[counts>1]) 

Pero ahora me gustaría tener un diagrama de venn para la concurrencia de factores. Idealmente, también de una manera que puede tomar un umbral para el conteo mínimo para cada factor. Por ejemplo, un diagrama de venn para los diferentes factores para que cada uno de ellos tenga que estar presente n> 10 en cada grupo a tener en cuenta.

He intentado encontrar una manera de producir los recuentos de tablas con agregado, pero no pude hacerlo funcionar.

+2

¿Has mirado en cualquiera de los paquetes de R para los diagramas de Venn? Ver [este ejemplo reciente] (http://stats.stackexchange.com/questions/16802/derive-pc-ab-from-coxs-two-rules/18209#18209) por G. Jay Kerns utilizando la biblioteca 'venneuler' , o este breve artículo en el Journal of Stat Software que usa la biblioteca 'venn' ([Murdoch, 2004] (http://www.jstatsoft.org/v11/c01)). Si esto es puramente sobre la programación R, debería migrarse a SO. –

+1

Avilella, esta pregunta podría no obtener ninguna respuesta porque está marginalmente fuera del tema. Puede que le vaya mejor en SO, que tiene una comunidad de usuarios R activa. Pero, por favor, no publique mensajes cruzados: simplemente marque la pregunta para la atención del moderador si desea que se migre. – whuber

+0

Lo he marcado, pero no puedo ver que se haya movido a SO aún ... – 719016

Respuesta

20

He proporcionado dos soluciones, utilizando dos paquetes diferentes con capacidades de diagrama de Venn. Como esperaba, ambos implican un paso inicial utilizando la función aggregate().

Tiendo a preferir los resultados del paquete venneuler. Las posiciones predeterminadas de la etiqueta no son ideales, pero puede ajustarlas consultando el método asociado plot (posiblemente usando locator() para seleccionar las coordenadas).

solución de la primera:

Una posibilidad es utilizar venneuler() en el paquete venneuler llamar su diagrama de Venn.

library(venneuler) 

## Modify the "factor" column, by renaming it and converting 
## it to a character vector. 
levels(data$factor) <- c("a", "b", "c") 
data$factor <- as.character(data$factor) 

## FUN is an anonymous function that determines which letters are present 
## 2 or more times in the cluster and then pastes them together into 
## strings of a form that venneuler() expects. 
## 
inter <- aggregate(factor ~ cluster, data=data, 
        FUN = function(X) { 
         tab <- table(X) 
         names <- names(tab[tab>=2]) 
         paste(sort(names), collapse="&") 
        })    
## Count how many clusters contain each combination of letters 
counts <- table(inter$factor) 
counts <- counts[names(counts)!=""] # To remove groups with <2 of any letter 
# a a&b a&b&c a&c  b b&c  c 
# 19 13 12 14 13  9 12 

## Convert to proportions for venneuler() 
ps <- counts/sum(counts) 

## Calculate the Venn diagram 
vd <- venneuler(c(a=ps[["a"]], b = ps[["b"]], c = ps[["c"]], 
        "a&b" = ps[["a&b"]], 
        "a&c" = ps[["a&c"]], 
        "b&c" = ps[["b&c"]], 
        "a&b&c" = ps[["a&b&c"]])) 
## Plot it! 
plot(vd) 

Algunas notas acerca de elecciones que hice al escribir este código:

  • he cambiado los nombres de los factores "factor-a"-"a". Obviamente puedes cambiar eso de vuelta.

  • Solo he requerido que cada factor esté presente> = 2 veces (en lugar de> 10) para contar dentro de cada grupo. (Eso fue para demostrar el código con este pequeño subconjunto de sus datos).

  • Si mira el objeto intermedio counts, verá que contiene un elemento inicial sin nombre. Ese elemento es la cantidad de clústeres que contiene menos de 2 letras. Puede decidir mejor que yo si desea o no incluirlos en el cálculo del objeto ps ('proporciones') posterior.

enter image description here

solución del segundo:

Otra posibilidad es emplear vennCounts()vennDiagram() y en el paquete Bioconductor limma. Para descargar el paquete, follow the instructions here. A diferencia de la solución anterior venneuler, la superposición en el diagrama resultante no es proporcional al grado real de intersección. En cambio, anota el diagrama con las frecuencias reales.(Tenga en cuenta que esta solución no implica ninguna de las modificaciones a la columna de la data$factor.)

library(limma) 

out <- aggregate(factor ~ cluster, data=data, FUN=table) 
out <- cbind(out[1], data.frame(out[2][[1]])) 

counts <- vennCounts(out[, -1] >= 2) 
vennDiagram(counts, names = c("Factor A", "Factor B", "Factor C"), 
      cex = 1, counts.col = "red") 

enter image description here

Cuestiones relacionadas