[英]Searching for specific genes within a large matrix, loop needs optimization
对于我的代码的每次迭代,我首先从基因来源的PPI网络中找到值,并在每次运行结束时重新计算。 如果在A或B类别中找到了该基因,我会将其完成度的得分和基因都存储在另一个位置,以进行分类和连接以进行进一步测试。 搜索过程需要时间,无论如何我都在寻找优化方法。 问题是我已经开始分批处理300多个基因,而花三天时间进行演算是很长的。 额外的信息矩阵是PPI网络内所有相互作用的矩阵,总计约176,000X3。
慢速代码:
#CREATE THE DNS LIST
DNSList = FALSE
DNSListNameHolder = NA
DNSListValueHolder = NA
DNSListHolder = 0
CN = 0
Prev = 0
while(!DNSList)
{
CN = CN + 1
IDNSList = FALSE
CNN = Prev
while(!IDNSList)
{
CNN = CNN + 1
if(as.character(ForDNSList$Gene.A[CNN]) == as.character(Candidate[CN]))
{
DNSListHolder = DNSListHolder + 1
DNSListValueHolder[DNSListHolder] = as.character(ForDNSList$Score[CNN])
DNSListValueHolder[DNSListHolder] = as.numeric(DNSListValueHolder[DNSListHolder])
DNSListNameHolder [DNSListHolder] = as.character(ForDNSList$Gene.B[CNN])
}
if(as.character(ForDNSList$Gene.B[CNN]) == as.character(Candidate[CN]))
{
DNSListHolder = DNSListHolder + 1
DNSListValueHolder[DNSListHolder] = as.character(ForDNSList$Score[CNN])
DNSListValueHolder[DNSListHolder] = as.numeric(DNSListValueHolder[DNSListHolder])
DNSListNameHolder [DNSListHolder] = as.character(ForDNSList$Gene.A[CNN])
}
if(CNN == length(ForDNSList$Gene.A))
IDNSList = TRUE
}
if(CN == length(Candidate))
DNSList = TRUE
print(paste("Pre-DNS List in Progress",CN/length(Candidate), sep = " "))
}
print("Pre-DNS List Completed")
出于示例目的,可以将候选列表设置为此
Candidate = c("BRCA1", "BRCA2", "ATK1", "FYN")
ForDNSList很长,因此这里有一个小节选,以了解如何列出外观。 如果我要搜索的基因在基因列A或B中,则它的随机性或多或少。
> ForDNSList[1:50, 1:3]
Gene.A Gene.B Score
1 Q96BE0 POLR3A 0.126
2 Q96BE0 PDPK1 0.126
3 Q96BE0 MGEA5 0.126
4 Q96BE0 DNAJA2 0.126
5 Q96BE0 DNAJB6 0.126
6 Q96BE0 BAG4 0.126
7 Q96BE0 HSPA4L 0.126
8 THAP1 A0A024RA76 0.332
9 Q96BE0 BAG2 0.236
10 Q96BE0 BAG3 0.236
11 Q96BE0 EGFR 0.236
12 Q96BE0 MOS 0.126
13 Q96BE0 RAF1 0.126
14 Q96BE0 GABRB1 0.126
15 Q96BE0 GNAZ 0.126
16 MS4A7 HMGCL 0.286
17 Q96BE0 ATP5A1 0.126
18 Q96BE0 DNAJA1 0.126
19 DVL3 PPM1A 0.210
20 Q96BE0 MCM5 0.126
21 Q96BE0 MCM7 0.126
22 Q96BE0 HSPA4 0.126
23 Q96BE0 PSMC2 0.126
24 Q96BE0 GNAL 0.126
25 Q96BE0 AMT 0.126
26 MECP2 SOX18 0.286
27 Q96BE0 CSNK1E 0.126
28 Q96BE0 ST13 0.126
29 CSNK2A1 MYH9 0.454
30 Q96BE0 CDK9 0.126
31 Q96BE0 SEC24C 0.126
32 TUBA4A MYH9 0.081
33 Q96BE0 HSPA2 0.236
34 Q96BE0 PRAME 0.126
35 Q96BE0 FANCC 0.126
36 Q96BE0 HSF2 0.126
37 KDR MYO1C 0.126
38 Q96BE0 HCFC1 0.126
39 Q96BE0 RAD51 0.126
40 KDR FYN 0.210
41 Q96BE0 PSMD2 0.126
42 Q96BE0 SKP2 0.126
43 KDR MET 0.376
44 Q96BE0 IKBKE 0.126
45 Q96BE0 ENDOG 0.126
46 Q96BE0 GNA13 0.126
47 TSG101 EIF3L 0.183
48 Q96BE0 SETDB1 0.126
49 Q96BE0 CDK10 0.126
50 HSP90AB1 TNNI3K 0.126
由于以上建议,我删除了一个循环,并用两个match()争论代替了它。 原始代码执行第一次迭代大约需要196秒,而仅花费20.4秒
Nx = 0
DNSList = FALSE
DNSListNameHolder = NA
DNSListValueHolder = NA
DNSListHolder = 0
CN = 0
Prev = 0
system.time(while(Nx < length(ForDNSList$Gene.A))
{
Nx = Nx + 1
#Check if Gene A is a candidate disease gene
if(is.element("TRUE",!is.na(match(Candidate,ForDNSList$Gene.A[Nx]))))
{
#if so push the holder one furter and fill the secondary varaibles with the complement and score info
DNSListHolder = DNSListHolder + 1
DNSListValueHolder[DNSListHolder] = as.character(ForDNSList$Score[CNN])
DNSListValueHolder[DNSListHolder] = as.numeric(DNSListValueHolder[DNSListHolder])
DNSListNameHolder [DNSListHolder] = as.character(ForDNSList$Gene.B[CNN])
}
#Check if Gene B is a candidate disease gene
if(is.element("TRUE",!is.na(match(Candidate,ForDNSList$Gene.B[Nx]))))
{
#if so push the holder one furter and fill the secondary varaibles with the complement and score info
DNSListHolder = DNSListHolder + 1
DNSListValueHolder[DNSListHolder] = as.character(ForDNSList$Score[CNN])
DNSListValueHolder[DNSListHolder] = as.numeric(DNSListValueHolder[DNSListHolder])
DNSListNameHolder [DNSListHolder] = as.character(ForDNSList$Gene.A[CNN])
}
print(Nx)
})
最好使用apply
函数之一-我认为它们已经过优化,可以使用多处理,因此有了更多的内核,您使用apply的操作可能会更快。 此外,使用函数可能比使用循环更好,因为它更具模块化且易于编码。
这是我自己的代码中的示例,显示了“离群值” Z分数算法的部分实现:
rw <- assays(sum_exp)$fpkm
#remove genes that have zero counts
rw <- rw[apply(rw, 1, function(x){return (sum(x)>0)}),]
#
sample_means <- apply(rw, 2, function(x){median(x[x>0])})
z_median <- median(sample_means)
z_mad <- mad(sample_means)
z_scores <- unlist(lapply(sample_means, function(x) {return ((x - z_median)/(z_mad))}))
如果要对其进行概念化,请考虑可能要在for循环的一次迭代中修改多个元素,例如实现Fibonacci的循环。 R无法并行优化循环,因为它无法隔离每个行/列/元素。 使用apply
, sapply
和lapply
,您可以假设每行/每一列/每个元素都是独立计算的,因此可以安全地将工作划分到不同的核心之间。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.