2016-07-22 23 views
1

Ich habe eine data.frame, die wie folgt aussieht: für jede PopulationWie erstellt man eine Schleife, um eine Funktion basierend auf Strings in einer Spalte zu berechnen?

   SNP    CLST A1 A2  FRQ IMP  POS CHR BVAL 
    1 rs2803291   Brahui C T 0.660000 0 1882185 1 878 
    2 rs2803291   Balochi C T 0.750000 0 1882185 1 878 
    3 rs2803291   Hazara C T 0.772727 0 1882185 1 878 
    4 rs2803291   Makrani C T 0.620000 0 1882185 1 878 
    5 rs2803291   Sindhi C T 0.770833 0 1882185 1 878 
    6 rs2803291   Pathan C T 0.681818 0 1882185 1 878 
    53 rs12060022   Brahui T C 0.0600000 1 3108186 1 982 
    54 rs12060022   Balochi T C 0.0416667 1 3108186 1 982 
    55 rs12060022   Hazara T C 0.0000000 1 3108186 1 982 
    56 rs12060022   Makrani T C 0.0200000 1 3108186 1 982 
    57 rs12060022   Sindhi T C 0.0625000 1 3108186 1 982 
    58 rs12060022   Pathan T C 0.0681818 1 3108186 1 982 
    105 rs870171   Brahui T G 0.2200000 0 3332664 1 976 
    106 rs870171   Balochi T G 0.3333330 0 3332664 1 976 
    107 rs870171   Hazara T G 0.3636360 0 3332664 1 976 
    108 rs870171   Makrani T G 0.1800000 0 3332664 1 976 
    109 rs870171   Sindhi T G 0.2083330 0 3332664 1 976 
    110 rs870171   Pathan T G 0.1590910 0 3332664 1 976 
    157 rs4282783   Brahui G T 0.8400000 1 4090545 1 992 
    158 rs4282783   Balochi G T 0.9583333 1 4090545 1 992 
    159 rs4282783   Hazara G T 0.8409090 1 4090545 1 992 
    160 rs4282783   Makrani G T 0.9000000 1 4090545 1 992 
    161 rs4282783   Sindhi G T 0.8958330 1 4090545 1 992 
    162 rs4282783   Pathan G T 0.9772727 1 4090545 1 992 

Jeder SNP-Locus hat bestimmte Populationen mit ihr verbundenen und einer bestimmten Frequenz (FRQ). Es gibt eine "L" Menge von eindeutigen SNPs in dem gesamten Datenrahmen. Ich möchte 3 SNPs zufällig aus dem data.frame abtasten und dann würde ich gerne die Summe von (FRQ_balochi_SNP1 - FRQ_Pathan_SNP1) * * (FRQ_Y_SNP1 - FRQ_Pathan_SNP1) über + (FRQ_balochi_SNP2 - FRQ_Pathan_SNP2) * (FRQ_Y_SNP2 - FRQ_Pathan_SNP2) + (FRQ_balochi_SNP3 - FRQ_Pathan_SNP3) * (FRQ_Y_SNP3 - FRQ_Pathan_SNP3) unter Verwendung der "3" zufällig erzeugten SNPs. Die Notation sieht ungefähr wie Value = Sum(i to 3) of (FRQ_Bal_i - FRQ_Pat_i) * (FRQ_Y_i - FRQ_Pat_i) aus. Y ist eine gegebene Bevölkerung. Zum Beispiel: "Hazara".

Ich möchte meine Ausgabe eine Liste von Werten aus dieser Berechnung zusammen mit ihren Y-Populationen sein.

Zum Beispiel gehen wir durch Hazara als unsere Y-Bevölkerung. Wir stichprobenartig und erhalten SNP1, SNP2 und SNP4. Der erste SNP (rs2803291) gibt uns (0.75 - 0.681818) * (0.772727 - 0.681818) für einen Wert von 0.006198. Der zweite SNP (rs12060022) gibt uns (0.041666 - 0.0681818) * (0.0000 - 0.061818) für einen Wert von 0.001639. Der vierte SNP (rs4282783) gibt uns (0.958333 - 0.9772727) * (0.8409090 - 0.9772727) für einen Wert von 0.002582. Summieren wir unsere Werte zusammen erhalten wir 0.006198+0.001639+0.002582 für eine Gesamtsumme von 0.01402. So ist die erste Zeile der Ausgabedatei

Population Value 
Hazara  0.01402 
Makrani  ??? 

ich dies getan für jede Bevölkerung, einschließlich Balochi und Pathan möchte, wenn möglich wäre.

+0

Warum haben Sie die Bearbeitung zurückgesetzt, um die Ausrichtung zu bereinigen? –

+0

Ich wollte nicht, ich war Mid-Edit Änderung einiger Mathe, um es sauberer zu machen – Evan

+0

'Pathan' wird immer Null sein, weil die Funktion Y - Pathan subtrahiert. Nur ein Fyi. –

Antwort

2

würde ich eine Hilfsfunktion erstellen Sie dann legen Sie sie in einen Looping Mechanismus, der jedes Etikett ausprobieren wird:

library(dplyr) 

snp_sum <- function(SNP, FRQ, CLST) { 
    (FRQ[CLST == "Balochi"] - FRQ[CLST == "Pathan"]) * (FRQ[CLST == SNP] - FRQ[CLST == "Pathan"]) 
} 

sum_df <- function(mydf, clst_list) { 
    lst <- lapply(clst_list, function(x) { 
      mydf %>% group_by(SNP) %>% 
      summarise(FRQ_SUM=snp_sum(x, FRQ, CLST)) %>% 
      summarise(Value=sum(FRQ_SUM[sample(n(), 3)])) 
     }) 
    cbind.data.frame(Population=clst_list, do.call("rbind", lst)) 
} 

sum_df(df1, unique(df1$CLST)) 
# Population  Value 
# 1  Brahui 0.0134297098 
# 2 Balochi 0.0353677606 
# 3  Hazara 0.0400308238 
# 4 Makrani 0.0008918497 
# 5  Sindhi 0.0161916643 
# 6  Pathan 0.0000000000 

bearbeiten

Mögliche beschleunigen mit einem eingebauten in R-Paket namens parallel :

library(parallel) 
no_cores <- detectCores() - 1L 
cl <- makeCluster(no_cores) 
clusterExport(cl, c("df1", "snp_sum")) 
clusterEvalQ(cl, library(dplyr)) 

sum_parallel <- parLapply(cl, unique(df1$CLST), function(x) { 

    df1 %>% group_by(SNP) %>% 
    summarise(FRQ_SUM = snp_sum(x, FRQ, CLST)) %>% 
    summarise(Value=sum(FRQ_SUM[sample(n(), 3)])) 
}) 

cbind.data.frame(Population=unique(df1$CLST), do.call("rbind", sum_parallel)) 

stopCluster(cl) 
+0

haben Sie irgendwelche Schätzungen darüber, wie lange dies dauern würde, wenn meine tatsächliche Datei 3.000.000 eindeutige SNPs mit 52 Populationen wäre, also 150.000.000 Zeilen lang, und wenn ich eine Stichprobe von 5.000 SNPs machen wollte? Genau wie eine grobe Schätzung. Es dauert 20 Minuten, um die Datei selbst einzulesen. Aber reden wir eine Stunde, einige Stunden oder ein paar Tage? – Evan

+1

Allmählich aufbauen, um zu sehen, wie die Zeit zunimmt. Versuchen Sie 10k Zeilen, dann 100k und überwachen Sie das Timing. –

+1

Das größere Problem wird die Speichernutzung sein. Haben Sie genug Arbeitsspeicher, um so viele Zeilen zu lesen? –