2016-07-22 56 views
1

我有一個data.frame看起來像:如何根據列中的字符串來計算函數的循環?

   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 

每個SNP位點具有與其和一定的頻率(FRQ)爲每個羣相關某些人羣。總數據中有「L」量的唯一SNP。我想從數據框中隨機抽樣3個SNP,然後我想跨越+(FRQ_balochi_SNP2-FRQ_Pathan_SNP2)*(FRQ_Y_SNP2-FRQ_Pathan_SNP2)+(FRQ_YPNP1-FRQ_Pathan_SNP1)*(FRQ_YPNP1-FRQ_Pathan_SNP1)* FRQ_balochi_SNP3-FRQ_Pathan_SNP3)*(FRQ_Y_SNP3-FRQ_Pathan_SNP3)使用「3」個隨機生成的SNP。符號看起來像Value = Sum(i to 3) of (FRQ_Bal_i - FRQ_Pat_i) * (FRQ_Y_i - FRQ_Pat_i)。 Y是給定的人口。例如:「哈扎拉」。

我希望我的輸出成爲這個計算的值列表以及它們的Y族羣。

例如,讓我們通過哈扎拉作爲我們的Y人口。我們隨機抽樣並獲得SNP1,SNP2和SNP4。第一個SNP(rs2803291)給我們(0.75 - 0.681818) * (0.772727 - 0.681818)的值爲0.006198。第二個SNP(rs12060022)給我們(0.041666 - 0.0681818) * (0.0000 - 0.061818)的值爲0.001639。第四個SNP(rs4282783)給我們(0.958333 - 0.9772727) * (0.8409090 - 0.9772727),其值爲0.002582。總結我們的價值,我們會得到0.006198+0.001639+0.002582,總數爲0.01402。因此,輸出文件的第一行是

Population Value 
Hazara  0.01402 
Makrani  ??? 

我想爲每個人口完成這項工作,如果可能的話,包括俾路支省和帕坦。

+0

爲什麼你回滾編輯清理對齊? –

+0

我不是故意的,我是中期編輯改變一些數學,使其更清潔 – Evan

+0

'Pathan'將始終爲零,因爲該函數減去Y - Pathan。只是一個fyi。 –

回答

2

我想創建一個輔助功能,然後把它變成一個循環機制,將嘗試每個標籤:

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 

編輯

可能的速度,內置R中的包叫做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

如果我的實際文件是300,000個獨特的SNP,並且有52個種羣長度超過150,000,000行,並且如果我想隨機抽取5,000個SNPs,那麼您是否有估計這需要多長時間?就像一個粗略的估計。需要20分鐘才能讀取文件本身。但是我們說一小時,幾小時還是幾天? – Evan

+1

逐漸建立起來,看看時間如何增加。嘗試10k行,然後100k,並監視時間。 –

+1

更大的問題將是內存使用量。你有足夠的工作記憶來閱讀那麼多行嗎? –

相關問題