2011-11-14 11 views
12

Mam plik wejściowy z listą ~ 50000 klastrów i obecnością wielu czynników w każdym z nich (~ 10 milionów wpisów ogółem), zobacz mniejszy przykład poniżej:Schemat Venna z listy klastrów i współwystępujących czynników

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) 

przy odrobinie pomocy z innym pytaniem, mam go do produkcji PieChart dla współwystępowania czynników takich jak to:

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

Ale teraz chciałbym mieć diagram venna dla współwystępowania czynników. Idealnie, również w sposób, który może przyjąć próg dla minimalnej liczby dla każdego czynnika. Na przykład diagram venna dla różnych czynników, tak aby każdy z nich musiał być obecny n> 10 w każdym skupieniu, które należy wziąć pod uwagę.

Próbowałem znaleźć sposób na zliczanie stołów z agregatem, ale nie mogłem go uruchomić.

+2

Pan spojrzał na każdy z pakietów R dla diagramów Venna? Zobacz [ten ostatni przykład] (http://stats.stackexchange.com/questions/16802/derive-pc-ab-from-coxs- two-rules/18209 # 18209) autorstwa G. Jay Kerns przy użyciu biblioteki 'venneuler' lub ten krótki artykuł w Journal of Stat Software korzystający z biblioteki 'venn' ([Murdoch, 2004] (http://www.jstatsoft.org/v11/c01)). Jeśli chodzi wyłącznie o programowanie w języku R, należy je zmigrować do SO. –

+1

Avilella, to pytanie może nie uzyskać żadnych odpowiedzi, ponieważ jest marginalnie wyłączone. Możesz zrobić lepiej na SO, który ma aktywną społeczność użytkowników R. Ale nie przesyłaj dalej: po prostu oznacz to pytanie moderatorem, jeśli chcesz je przenieść. – whuber

+0

Oznacziłem to flagą, ale nie widzę jeszcze przeniesienia do SO ... – 719016

Odpowiedz

20

Dostarczyłem dwa rozwiązania, używając dwóch różnych pakietów z możliwościami diagramu Venna. Zgodnie z oczekiwaniami obie wymagają wstępnego kroku przy użyciu funkcji aggregate().

Ja preferuję wyniki z pakietu venneuler. Domyślne pozycje etykiet nie są idealne, ale można je skorygować, analizując powiązaną metodę plot (ewentualnie używając locator(), aby wybrać współrzędne).

Rozwiązanie 1st:

Jedną z możliwości jest użycie venneuler() w pakiecie venneuler narysować diagram Venna.

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) 

Kilka uwag na temat wyborów ja dokonane na piśmie ten kod:

  • Zmieniłem nazwy czynników z "factor-a" do "a". Oczywiście możesz to zmienić.

  • Wymagałem tylko, aby każdy czynnik był obecny> = 2 razy (zamiast> 10), aby był liczony w obrębie każdego skupienia. (To miało pokazać kod z tym małym podzestawem twoich danych.)

  • Jeśli spojrzysz na obiekt pośredni counts, zobaczysz, że zawiera on początkowy element bez nazwy. Ten element to liczba klastrów, które zawierają mniej niż 2 dowolnej litery. Możesz zdecydować lepiej niż ja, czy chcesz je uwzględnić przy obliczaniu kolejnego obiektu ps ("proporcje").

enter image description here

Rozwiązanie 2.:

Inną możliwością jest zastosowanie vennCounts() i vennDiagram() w opakowaniu BioConductor limma. Aby pobrać pakiet, follow the instructions here. W przeciwieństwie do powyższego rozwiązania venneuler, nakładanie się na wynikowym diagramie nie jest proporcjonalne do rzeczywistego stopnia przecięcia. Zamiast tego adnotuje diagram z rzeczywistymi częstotliwościami.(Zauważ, że to rozwiązanie nie wymaga żadnych zmian do kolumny 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

Powiązane problemy