全部版块 我的主页
论坛 数据科学与人工智能 数据分析与数据科学 R语言论坛
1581 3
2020-05-26
使用R语言的多线程进行ParLapply的循环计算时,我的电脑CPU是6核12线程的配置,我分配了12个线程进行运算,按理来说CPU占用率应该很高才是,之前使用12线程的时候CPU占用率都能达到100%,但是这次打开任务管理器看了下CPU的占用情况发现才达到30%左右,这种占用率和普通单线程的lapply应该是差不多的,所以我怀疑虽然我分配了多线程,但是实际上并没有进行多线程的运算。我想知道这是什么原因
以下是我的程序:
stable_pair<-read.table("E:\\con_pairs.txt",header=T,fill=T,sep="\t",stringsAsFactors = F,check.names = F)
GSE9348<-read.table("E:\\GSE9348RMA.txt",head=T,sep="\t",stringsAsFactors=F,check.names=F,fill=T)
GO_path_gene<-read.table("E:\\goID_geneID.txt",head=T,sep="\t",quote="'\"",fill=T,check.names=F,stringsAsFactors=F)
#phyper(q-1,m,n,k,lower.tail=F)中q为通路基因参与的逆转对,m为所有稳定对在GSE9348中逆转的逆转对,n为稳定对中没有逆转的基因对,k为通路基因参与的稳定对,计算的是通路中至少出现q对稳定对的概率
GSE9348<-cbind(as.integer(rownames(GSE9348)),GSE9348)#第一列改为整数形的geneID,减少后边循环里的计算量
GSE9348_num_patients<-length(GSE9348[1,])
stable_pair<-as.matrix(stable_pair)
GSE9348<-as.matrix(GSE9348)
reverse_pair<-read.table("E:\\reverse_pair_method2_GSE9348.txt",sep="\t",head=T,check.names=F,stringsAsFactors=F)
reverse_pair<-reverse_pair[,c(1,2)]
reverse_pair<-as.matrix(reverse_pair)
GO_path_gene_list<-list()
for (i in 1:length(GO_path_gene[1,])) {
  GO_path_gene_list<-list(na.omit(GO_path_gene[,i]))
  names(GO_path_gene_list)<-colnames(GO_path_gene)
}
#通路基因过滤掉在数据集中不存在的gene
for(i in 1:length(GO_path_gene_list)){
  if(length(intersect(GSE9348[,1],GO_path_gene_list[]))!=length(GO_path_gene_list[])){
    GO_path_gene_list[]<-intersect(GSE9348[,1],GO_path_gene_list[])
  }
}

library(data.table)
#@!!  得到一个通路中每个gene参与的稳定对(没排除通路内部的稳定对)
#@!!  gene:参与稳定对的一个基因
#@!!  stable.pair:稳定对集,第一列为higher,第二列为lower
onegene.stable.pair<-function(gene,stable.pair){
  gene_stable_pair<-rbind(stable.pair[stable.pair[,1]==gene,],stable.pair[stable.pair[,2]==gene,])
  return(gene_stable_pair)
}
#@!!  得到一个通路中每个gene参与的逆转对
#@!!  gene:参与逆转对的一个基因
#@!!  stable.pair:逆转对集,第一列为higher,第二列为lower
onegene.reverse.pair<-function(gene,reverse.pair){
  gene_reverse_pair<-rbind(reverse.pair[reverse.pair[,1]==gene,],reverse.pair[reverse.pair[,2]==gene,])
  return(gene_reverse_pair)
}
#@!!  对每行查重,并且添加一列为每行出现的次数,最后取不重复的行
#@!!  DF:一个数据框/矩阵之类的
count.dups <- function(DF){
  DT <- data.table(DF)
  DT<-DT[,.N, by = names(DT)]
  as.data.frame(DT[N==1][,c(1,2)])
}
#@!!  
#@!!  path.gene:一条通路中包含的所有gene,integer型向量
#@!!  stable.pair:稳定对集,第一列为higher,第二列为lower
#@!!  reverse.pair:一个数据集中的逆转对集,第一列为higher,第二列为lower
#pathgene_all_stable_pair:将所有通路中基因参与的稳定对合并,去除通路内部基因之间的稳定对,去重思想:统计通路中每个基因参与的稳定对,如果某一稳定对出现两次,则说明通路中两个基因互成稳定对并且均被计数,抛出这种稳定对
#pathgene_reverse_pair:将所有通路中基因参与的逆转对合并,去除通路内部基因之间的逆转对,去重思想同上
#ps:函数中不能包含太长的中文的注释,否则会报错
path.dyregulated.in.entirety<-function(path.gene,stable.pair,reverse.pair){
  pathgene_stable_pair<-apply(as.data.frame(path.gene), 1, onegene.stable.pair,stable.pair=stable_pair)
  if(class(pathgene_stable_pair)=="list"){
    pathgene_all_stable_pair<-count.dups(do.call(rbind,pathgene_stable_pair))
    a<-length(na.omit(match(pathgene_all_stable_pair[,1],path.gene)))
    b<-length(na.omit(match(pathgene_all_stable_pair[,2],path.gene)))
    pathgene_reverse_pair<-apply(as.data.frame(path.gene), 1, onegene.reverse.pair,reverse.pair=reverse_pair)
    if(class(pathgene_reverse_pair)=="list"){
      pathgene_all_reverse_pair<-count.dups(do.call(rbind,pathgene_reverse_pair))
      c1<-length(na.omit(match(pathgene_all_reverse_pair[,1],path.gene)))
      d1<-length(na.omit(match(pathgene_all_reverse_pair[,2],path.gene)))
      c<-a-c1+d1
      d<-b-d1+c1
      if(a>0 & b>0 & c>0 & d>0){
        p_value<-tryCatch(chisq.test(matrix(c(a,b,c,d),nrow = 2),correct=T)$p.value,warning=function(w){fisher.test(matrix(c(a,b,c,d),nrow = 2))$p.value})
        ifelse((a/b)<(c/d),return(c(p_value,"upregulation")),return(c(p_value,"downregulation")))
        #极致向量化计算
      }else(return(c("negative value in a b c d",a,b,c,d)))
    }else{return("no reverse pair in this path")}
  }else{
    return("no stable pair in this path")
  }
}


library(parallel)
library(iterators)
c1<-makeCluster(12)
#声明全局变量
clusterExport(c1,c("onegene.stable.pair","stable_pair","count.dups","data.table","onegene.reverse.pair","reverse_pair"),envir = environment())
aa<-parLapply(c1,GO_path_gene_list, path.dyregulated.in.entirety,stable.pair=stable_pair,reverse.pair=reverse_pair)
stopCluster(c1)

以下是我的猜想:之前我使用parallel多线程的时候,并没有进行过全局变量的声明,然后分配多线程时CPU会出现高占用的情况,但是此次由于我的“path.dyregulated.in.entirety”方法中涉及到了我自己写入的三个function,不声明全局变量就会报错。所以就对全局变量进行了声明,反而出现了分配12线程而CPU占用率只有30%的情况。而且R语言让我声明全局变量的时候,将我的"onegene.stable.pair","onegene.reverse.pair"两个function当作了变量进行识别,而"count.dups"却正确的当作了function进行的识别(这是我分别不将他们放入声明全局变量中时报的错所知)。
因此,我觉得问题可能是出现在我嵌套的function中(当时记得嵌套function要写...以证明两个function共享参数还是什么的,我了解的不是很透彻,但是没写...也能成功运行我就没写),或者是全局变量的参数上。希望有大神能够帮我解答
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

全部回复
2020-6-6 15:01:09
问题已解决,运用多线程的ParLapply前替必须有多个list才能进行多CPU运算。
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2021-2-20 14:31:31
黑白纯 发表于 2020-6-6 15:01
问题已解决,运用多线程的ParLapply前替必须有多个list才能进行多CPU运算。
谢谢楼主分享!请问多个list是指函数返回值是多个list的意思吗?
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

2021-3-19 10:24:05
耿子豆 发表于 2021-2-20 14:31
谢谢楼主分享!请问多个list是指函数返回值是多个list的意思吗?
输入的list变量包含多个list
举个例子
a<-list(a=1,b=2,c=3,d=4)
list a中包含了a,b,c,d四个list
二维码

扫码加我 拉你入群

请注明:姓名-公司-职位

以便审核进群资格,未注明则拒绝

相关推荐
栏目导航
热门文章
推荐文章

分享

扫码加好友,拉您进群