2016-07-25 18 views
1

Ich habe einen Datenrahmen „dfA“ (65000 Zeilen) der Form:Wiederholte subsetting und Arithmetik-Datensatz basierend auf der zweiten Datenrahmen

Chr Pos  NCP  NCP_Ratio 
1 72  1.06 0.599 
1 371  4.26 1.331 
1 633  2.10 2.442 
1 859  1.62 1.276 
1 1032 7.62 4.563 
1 1199 6.12 4.896 
1 1340 13.22 23.607 

I die Werte von Chr und Pos in jeder Reihe von dfA verwenden möchten dfB des Formulars sequentiell eine zweite Teilmenge data.frame:

Chr Pos Watson Crick 
1 1 5  0 
1 2 5  0 
1 4 1  0 
1 6 1  0 
1 7 1  0 
1 8 2  0 
1 9 2  0 
1 12 1  0 
1 14 1  0 
1 15 2  0 
1 22 1  0 

dfB hat etwa 4 Millionen Zeilen.

Jedes Mal, wenn ich dfB Teilmenge, würde Ich mag die Werte für eine Region von Interesse auf den Bereich in Pos (dh +/- 1000 der Wert von Pos in dfA), und fügen Sie sie zu einem dritten Daten beruhen abrufen .frame dfC, das anfänglich mit Nullen gefüllt ist.

Ich habe dies durch Schleifen durch jede Zeile von dfA. Aber aufgrund der 65.000 Zeilen dauert es Stunden. Also meine Fragen sind:

  1. Gibt es einen besseren/effizienteren Weg?

  2. Welcher Teil meines Code dies so schrecklich verlangsamt „

Mein Code:

temp=NULL 
width=300 # Region upstream and downstream of centrepoint # 
padding=50 # Add some padding area to table # 
width1=width+padding 
dfC=data.frame(NULL) 
dfC[1:((width1*2)+1),"Pos"]=(1:((width1*2)+1)) # Create Pos column # 

# Prefill dfC table with zeros # 
dfC[1:((width1*2)+1),"Watson"]=0 
dfC[1:((width1*2)+1),"Crick"]=0 

for (chrom in 1:16) { # LOOP1. Specify which chromosomes to process # 

    dfB.1=subset(dfB,Chr==chrom) # Make temp copy of the dataframes for each chromosome # 
    dfA.1=subset(dfA, Chr==chrom) 

for (i in 1:nrow(dfA.1)) { # LOOP2: For each row in dfA: 

    temp=subset(dfB.1, Pos>=(dfA.1[i,"Pos"]-width1) & Pos<=(dfA.1[i,"Pos"]+width1)) # Create temp matrix with hits in this region 
    temp$Pos=temp$Pos-dfA.1[i,"Pos"]+width1+1 
    dfC[temp$Pos,"Watson"]=dfC[temp$Pos,"Watson"]+temp[,"Watson"] 
    dfC[temp$Pos,"Crick"]=dfC[temp$Pos,"Crick"]+temp[,"Crick"] 

} # End of LOOP2 # 
} # End of LOOP1 # 

Beispielausgabe ist in der folgenden Form - wo Po Wert von 1 enthält zu? 2000 (stellt die Region von -1000 bis +1000 dar, die jede zentrale Pos-Position in dfA flankiert), und die Watson/Crick-Spalten enthalten die Summe der Treffer für jede Position.

Pos Watson Crick 
1 15  34 
2 35  32 
3 11  26 
4 19  52 
5 10  23 
6 32  17 
7 21  6 
8 15  38 
9 17  68 
10 28  54 
11 27  35 
etc 
+0

Es wäre hilfreich, wenn Sie die erwartete Ausgabe für den Beispielcode einschließen. Denken Sie auch darüber nach, Daten in Form von 'dput' zu posten. – Sumedh

+0

Danke für die Hilfe beim Bearbeiten/Formatieren. Ich füge die Beispielausgabe hinzu. Ich kenne dput nicht, aber ich lese gerade Hilfe. – Matt

Antwort

0

Ich habe nur Ihren Code bereinigt, also erwarten Sie keine große Verbesserung, aber ich denke, dass diese Version marginal schneller laufen könnte.

width <- 300 
padding <- 50 
width1 <- width + padding  
dfC <- data.frame(Pos=1:((width1*2)+1), Watson=0, Crick=0) 
for (chrom in 1:16) { 
    dfB1 <- subset(dfB, Chr == chrom) 
    for (pos in dfA$Pos[dfA$Chr == chrom]) { 
     dfB2 <- dfB1[(dfB1$Pos >= pos - width1) & (dfB1$Pos <= pos + width1), ] 
     rows <- dfB2$Pos - pos + width1 + 1 
     dfC$Watson[rows] <- dfC$Watson[rows] + dfB2$Watson 
     dfC$Crick[rows] <- dfC$Crick[rows] + dfB2$Crick 
    } 
} 
Verwandte Themen