如何加速R中的循环运行过程以获取巨大的文件

时间:2014-04-18 20:52:11

标签: r loops

我有一个遗传测序文件 - 4行。我试图为每个列出的独特基因的变体运行一段代码。

以下是数据如何

的示例
CHROM   POS GENE    IMPACT    HOM
1   23455   A   HIGH      HET
1   23675   A   HIGH      HET
1   23895   A   MODERATE    
1   24115   B   LOW   HET
1   24335   B   HIGH      HET
1   24555   B   LOW   HET
2   6789    C   LOW 
2   12346   C   LOW   HET
2   17903   C   MODERATE  HET
2   23460   C   MODERATE    
2   29017   D   LOW   HET
2   34574   D   HIGH    
2   40131   D   HIGH      HET
3   567890  E   HIGH      HET
3   589076  E   HIGH    
3   610262  E   LOW   HET
3   631448  F   HIGH      HET
3   652634  F   MODERATE  HET

这是我的代码:

sam <- read.csv("../sample/sample1.txt", sep="\t",header=TRUE,stringsAsFactors=FALSE)

glist <- unique(sam[,3])

for(i in glist) {

lice <- subset(sam, GENE == i)
lice$mut <- as.numeric(ifelse((lice[c(4)] == 'MODERATE' | lice[c(4)] == 'HIGH'), c(1), c(0))) 
lice$cntmut <- sum(lice$mut, na.rm=TRUE)
lice$het <- as.numeric(ifelse(lice$HOM == 'HET', c(1), c(0))) 
lice$cnthet <- sum(lice$het, na.rm=TRUE)
lice$cnthetmut <- lice$mut + lice$het
lice$lice <- ifelse(lice$mut == 1 & lice$cntmut >= 2 & lice$het == 1 & lice$cnthet >= 2 &     lice$cnthetmut == 2 , 'lice', '')

write.table(lice,paste0("../sample/list/",i,".txt"),sep="\t",quote=F,row.names=F)

}

licelist <- list.files("../sample/list/", full.names=T)   
lice2 <- do.call("rbind",lapply(licelist, FUN=function(files){read.table(files, header=TRUE, sep="\t", stringsAsFactors=FALSE)}))

lice_out <- merge(sam,lice2,by.x=c("CHROM","POS"),by.y=c("CHROM","POS"), all=T)

write.table(lice_out,"../sample/sample1_lice.txt",sep="\t",quote=F,row.names=F)

我有30,000个基因,这意味着运行此代码大约需要2周(原始文件大小约为4GB)。我想知道是否有人对如何提高速度有任何建议?我已经尝试编写一个函数来包含所有这些信息(有些是重复的),但无济于事。

只需添加:

循环中的代码基本上是在执行以下操作: 1.将每个基因中有多少变体moderatehighhet中有多少变体相加。 2.如果变体是lice,则moderate/high被赋予基因中的变体,het,并且只有当基因中存在两种以上这些类型的变体时才会被赋予

对于这个结果:

CHROM   POS GENE    IMPACT  HOM LICE
1   23455   A   HIGH    HET lice
1   23675   A   HIGH    HET lice
1   23895   A   MODERATE        
1   24115   B   LOW HET 
1   24335   B   HIGH    HET 
1   24555   B   LOW HET 
2   6789    C   LOW     
2   12346   C   LOW HET 
2   17903   C   MODERATE    HET 
2   23460   C   MODERATE        
2   29017   D   LOW HET 
2   34574   D   HIGH        
2   40131   D   HIGH    HET 
3   567890  E   HIGH    HET 
3   589076  E   HIGH        
3   610262  E   LOW HET 
3   631448  F   HIGH    HET lice
3   652634  F   MODERATE    HET lice

就像我进一步提到的那样,这些步骤并非都是必要的,但是当我在一个较小的数据帧上进行操作时就已经完成了。

1 个答案:

答案 0 :(得分:3)

当你没有解释你想要完成什么,或者提供你的样本数据集所需结果的例子时,有点难以帮助你,但这里有一些建议:

  

(1)使用数据表。它们更快,更有效地使用内存。

     

(2)除了总和(cntmut,cnthet)之外,我不明白为什么你吐了原来的桌子。还有其他方法可以在不拆分数据集的情况下获得总和。

     

(3)我最后没有真正看到合并点。

这是一个可能会更快的选项。

library(data.table)
dt <- data.table(sam)
setkey(dt,GENE)
dt[,mut:=as.numeric(IMPACT=="MODERATE"|IMPACT=="HIGH")]
dt[,cntmut:=sum(mut), by=GENE]
dt[,het:=as.numeric(HOM=="HET")]
dt[,cnthet:=sum(het),by=GENE]
dt[,cnthetmut:=mut+het]
dt[,lice:=ifelse(mut==1 & cntmut>=2 & het==1 & cnthetmut ==2,'lice',''), by=GENE]
head(dt)
#    CHROM   POS GENE   IMPACT HOM mut cntmut het cnthet cnthetmut lice
# 1:     1 23455    A     HIGH HET   1      3   1      2         2 lice
# 2:     1 23675    A     HIGH HET   1      3   1      2         2 lice
# 3:     1 23895    A MODERATE       1      3   0      2         1     
# 4:     1 24115    B      LOW HET   0      1   1      3         1     
# 5:     1 24335    B     HIGH HET   1      1   1      3         2     
# 6:     1 24555    B      LOW HET   0      1   1      3         1