如何根据列中的字符串进行循环计算函数?

时间:2016-07-22 16:10:35

标签: r loops dataframe bioinformatics

我有一个看起来像这样的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。我想从data.frame中随机抽取3个SNP,然后我想得到(FRQ_balochi_SNP1 - FRQ_Pathan_SNP1)* *(FRQ_Y_SNP1 - FRQ_Pathan_SNP1)的总和+(FRQ_balochi_SNP2 - FRQ_Pathan_SNP2)*(FRQ_Y_SNP2 - FRQ_Pathan_SNP2)+( 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      ???

我希望每个人都能做到这一点,如果可能的话,包括俾路支和帕坦。

1 个答案:

答案 0 :(得分: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

修改

使用名为parallel的内置R包可能加快速度:

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)