如何创建一个循环来计算基于列中字符串的函数?
How to make a loop to calculate a function based on strings in a column?
我有一个 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)。在总数 data.frame 中有 "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 是给定的总体。例如:"Hazara".
我希望我的输出是这个计算的值列表以及它们的 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 ???
我希望每个人都这样做,如果可能的话,包括俾路支和帕坦。
我会创建一个辅助函数,然后将其放入一个循环机制中,该机制将尝试每个标签:
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)
我有一个 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)。在总数 data.frame 中有 "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 是给定的总体。例如:"Hazara".
我希望我的输出是这个计算的值列表以及它们的 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 ???
我希望每个人都这样做,如果可能的话,包括俾路支和帕坦。
我会创建一个辅助函数,然后将其放入一个循环机制中,该机制将尝试每个标签:
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)