2015-02-16 9 views
21

Ich habe eine Frage über die Reduce-Funktion in R. Ich lese die Dokumentation, aber ich bin immer noch ein wenig verwirrt. Also, ich habe 5 Vektoren mit Genamen. Zum Beispiel:Verstehen Sie die Reduce-Funktion

v1 <- c("geneA","geneB",""...) 
v2 <- c("geneA","geneC",""...) 
v3 <- c("geneD","geneE",""...) 
v4 <- c("geneA","geneE",""...) 
v5 <- c("geneB","geneC",""...) 

Und ich würde gerne herausfinden, welche Gene in mindestens zwei Vektoren vorhanden sind. Einige Leute haben vorgeschlagen:

Reduce(intersect,list(a,b,c,d,e)) 

ich sehr schätzen, wenn jemand mir bitte erklären, wie diese Aussage funktioniert, weil ich in anderen Szenarien verwendet Reduce gesehen haben. Vielen Dank!

+3

Ist deine Frage wirklich " Wie kann ich herausfinden, welche Gene/Elemente in mindestens zwei Vektoren vorhanden sind? " Wenn dies der Fall ist, wird 'Reduce()' * * nicht * hilfreich sein, obwohl es die Antwort auf die Frage "Welche Gene sind in ** all ** der Vektoren vorhanden?" –

Antwort

23

Reduce nimmt eine binäre Funktion und eine Liste von Datenelementen und wendet die Funktion nacheinander rekursiv auf die Listenelemente an. Zum Beispiel:

Reduce(intersect,list(a,b,c)) 

ist die gleiche wie

intersect((intersect(a,b),c) 

Aber ich glaube nicht, dass Konstrukt Ihnen dabei helfen wird, da es nur die Elemente angezeigt werden können, die alle Vektoren gemeinsam sind.

Um die Anzahl der Vektoren zu zählen, die ein Gen in Ihnen wird die folgende tun könnte:

vlist <- list(v1,v2,v3,v4,v5) 
addmargins(table(gene=unlist(vlist), vec=rep(paste0("v",1:5),times=sapply(vlist,length))),2,list(Count=function(x) sum(x[x>0]))) 
     vec 
gene v1 v2 v3 v4 v5 Count 
    geneA 1 1 0 1 0  3 
    geneB 1 0 0 0 1  2 
    geneC 0 1 0 0 1  2 
    geneD 0 0 1 0 0  1 
    geneE 0 0 1 1 0  2 
+0

Vielen Dank für Ihre Eingabe. Ich habe die Tabellen- und addmargins Funktionen vorher nie benutzt. Wenn es dir nichts ausmacht, würde ich dich gerne danach fragen. – Johnathan

+0

Tabelle: Gen ist das Objekt, das als Faktor verwendet werden kann (d. H. Kategoriale Daten), und vec sind die Namen der Dimensionen (d. H. "V1", "v2"), richtig? Ich bin verwirrt darüber, was Zeiten bedeuten.Es gibt Vektoren der Länge zurück. Wie für addmargins ist es eine Funktion, die eine Tabelle erweitert, um die Grenzsummen (d. H. Gesamtzählungen der Fälle über die interessierenden Kategorien) hinzuzufügen, richtig? "2" bedeutet, dass eine Spalte hinzugefügt wird, die die Zeilengrenzwerte enthält, oder? Schließlich ist das letzte Argument eine Liste, die die Funktion enthält. Danke für deine Zeit und Hilfe! – Johnathan

+1

@ Johnathan Ja, du hast Recht. 'mal' ist ein Argument für' rep', das bestimmt, wie oft jedes Element wiederholt wird - das soll sicherstellen, dass die Gene auf die richtige Variable abgebildet werden. – James

23

Ein schöner Weg, um sehen was Reduce() tun wird, ist es mit dem Argument accumulate=TRUE zu laufen. Wenn accumulate=TRUE zurückgegeben wird, wird ein Vektor oder eine Liste zurückgegeben, in der jedes Element seinen Zustand nach der Verarbeitung der ersten n Elemente der Liste in x zeigt. Hier sind ein paar Beispiele:

Reduce(`*`, x=list(5,4,3,2), accumulate=TRUE) 
# [1] 5 20 60 120 

i2 <- seq(0,100,by=2) 
i3 <- seq(0,100,by=3) 
i5 <- seq(0,100,by=5) 
Reduce(intersect, x=list(i2,i3,i5), accumulate=TRUE) 
# [[1]] 
# [1] 0 2 4 6 8 10 12 14 16 18 20 22 24 26 28 30 32 34 36 
# [20] 38 40 42 44 46 48 50 52 54 56 58 60 62 64 66 68 70 72 74 
# [39] 76 78 80 82 84 86 88 90 92 94 96 98 100 
# 
# [[2]] 
# [1] 0 6 12 18 24 30 36 42 48 54 60 66 72 78 84 90 96 
# 
# [[3]] 
# [1] 0 30 60 90 
+0

Kann es mit mehr als Vergleiche verwendet werden, offensichtlich habe ich es versucht und ich habe die erste Zahl in der Reihenfolge gefolgt von entweder 11111 oder 00000. Meine erwarteten Werte für etwas wie Reduzieren ('<', c (3,4,7, 2,6,8,9), akkumulieren = T) wäre 3 3 2 2 2 2 gewesen. Ist das mit Reduce erreichbar? Ein bisschen erklären, ich nehme an, dass Reduce die Elemente eines Vektors 2 zu einer Zeit von links beginnend nimmt. Da meine Funktion "kleiner als" ist, würde sie die ersten beiden vergleichen, indem sie die kleinere Zahl zurückgibt, dann vergleiche sie mit der dritten, die kleinere zurücksendet ... – user3507767

+0

nur um klarzustellen, ich weiß, dass ich meine gewünschten Ergebnisse mit cummin() bekommen kann versuchen, Reduce() hier zu verstehen. – user3507767

6

die Eingangswerte am Ende dieser Antwort gegeben Unter der Annahme, der Ausdruck

Reduce(intersect,list(a,b,c,d,e)) 
## character(0) 

gibt die Gene, die in allen Vektoren vorhanden sind, nicht die Gene, die sind in mindestens zwei Vektoren vorhanden. Es bedeutet:

intersect(intersect(intersect(intersect(a, b), c), d), e) 
## character(0) 

Wenn wir die Gene wollen, die in mindestens zwei Vektoren sind:

L <- list(a, b, c, d, e) 
u <- unlist(lapply(L, unique)) # or: Reduce(c, lapply(L, unique)) 

tab <- table(u) 
names(tab[tab > 1]) 
## [1] "geneA" "geneB" "geneC" "geneE" 

oder

sort(unique(u[duplicated(u)])) 
## [1] "geneA" "geneB" "geneC" "geneE" 

Hinweis: Wir benutzten:

a <- c("geneA","geneB") 
b <- c("geneA","geneC") 
c <- c("geneD","geneE") 
d <- c("geneA","geneE") 
e <- c("geneB","geneC") 
Verwandte Themen