2016-07-18 10 views
1

Ich bin unerfahren mit I in R und hoffe, einen Prozess zu beschleunigen, während ich einige Analyse in einer Website einführe.kann ich den Iterationsprozess in R beschleunigen?

Ich fand ein sehr nützliches Tutorial, das mir erlaubt, durch eine Matrix zu iterieren, die Kriteriendaten über einem bestimmten Schwellenwert (> 0,01) auszuwählen und dann mit diesen Werten schließlich drei Vektoren: "source, target und corr" zu durchdringen Mache einen gut organisierten Datenrahmen.

source=c() 
target=c() 
corr<-c() 

g1<-rownames(adj_mat)[1:dim(adj_mat)[1]] 
g2<-g1 

for(gene in g1){ 
    for(gen in g2){ 
    if(adj_mat[gene,gen]>0.01){ 
     source<-c(source,gene) 
     target<-c(target,gen) 
     corr<-c(corr,adj_mat[gene,gen]) 
    } 
    } 
} 
network<-data.frame(source,target,corr) 

Während dies für kleine Matrizen der Dimensionen 1000 ist sehr gut, 500, dauert es eine frustrierende viel Zeit mit denen von Dimensionen 10000, 700 ...

Die Matrix aus einer Datei kommt, dass wird jedes Mal auf die Website hochgeladen und gelesen, so dass ich die 'Quelle usw.' nicht anpassen kann Objektgrößen auf die Größe der Matrix, da jede neu hochgeladene Datei eine andere Größe hat.

Kann mir jemand sagen, ob es eine effizientere Möglichkeit gibt, dies in R zu tun?

+0

Was ist die Variable "m"? Ich empfehle, einen Index für die Iteration zu verwenden ('für (i in 1: nrow (adj_mat))') und, wie @Paul Hiemstra darauf hinwies, vorzuordnen. Z.B.: source <- Zeichen (length = nrow (adj_mat)) '. – sebastianmm

+0

Entschuldigung, ich habe diesen Fehler –

Antwort

2

Das größte Problem, das ich jetzt sehen kann, ist, dass Sie iterativ ein paar Datenstrukturen erstellen, d. H. source, target und corr. Sie können Ihren Code enorm beschleunigen, indem Sie Ihre Objekte auf die richtige Größe vorbelegen und Indizes verwenden, um die Werte zu platzieren.

Sie können Ihren Code weiter verbessern, indem Sie Ihre Operation vektorisieren. Zum Beispiel die Bestimmung, welche Teile m sind größer als 0.01 leicht wie dies getan werden kann:

m[m > 0.01] 

und erhalten Sie Ihre Datenstrukturen source, target und corr:

matching_indices = which(m > 0.01, arr.ind = TRUE) 
source = matching_indices[,1] 
target = matching_indices[,2] 
corr = m[m > 0.01] 

Dies ist nur Beispiel-Code, Ich bin mir nicht ganz sicher, ob Sie das brauchen. Aber es ist ein guter Schritt dazu.

+0

korrigiert, der wirklich nützlich klingt. Könnten Sie bitte ein Beispiel oder einen Link zu Beispielcode geben? danke –

+0

Ich erweiterte meine Antwort. Ohne ein korrekt reproduzierbares Beispiel ist es schwierig, weiter zu gehen. –

+0

ah warten, entschuldigen Sie meinen, indem Sie die Indizes auf die angegebene Größe der Datei anpassen? Ja, die Matrix wird von einer Datei kommen, die auf die Website hochgeladen wird - jedes Mal in einer anderen Größe, also kann ich das nicht tun –

2

Die Vektorisierung ist sehr wichtig für das Schreiben von performant R. Dies ermöglicht so viel Arbeit im nativen Code wie möglich, mit minimalen Übertragungen von Werten zwischen R und nativem Code.

Zum Beispiel:

# Slow 
a <- c(1, 2, 3) 
b <- c(4, 5, 6) 

r <- c() 

for (i in 1:length(a)) { 
    r <- c(r, a[i] + b[i]); 
} 

# Fast 
r <- a + b 

Letzteres ist schneller, weil die langsam Methode + 3 Mal aufruft, eine für jede Iteration, während die schnell Methode + einmal aufruft. Sie sollten versuchen, die Dinge so viel wie möglich zu chargen. Es ist auch viel kürzerer Code!

Aber was ist mit Konditionalen? Angenommen, Sie optimieren möchten:

# Slow 
a <- c(1, 2, 3) 
b <- c(4, 5, 6) 

r <- c() 

for (i in 1:length(a)) { 
    if (a[i] > b[i]/2) { 
     r <- c(r, a[i] + b[i]); 
    } else { 
     r <- c(r, a[i] - b[i]); 
    } 
} 

Sie ifelse verwenden können:

# Fast 
a <- c(1, 2, 3) 
b <- c(4, 5, 6) 

r <- ifelse(a > b/2, a + b, a - b) 

Werfen Sie einen Blick auf @ PaulHiemstra Antwort für eine Anwendung auf Ihrem Code.