2013-09-21 6 views
1

대용량 data.table 객체의 각 행에 행렬을 반환하는 함수를 적용하고 싶습니다 (원본 파일은 약 30GB입니다 , 나는 80 GB RAM을 가지고있다.) 그리고 data.table 객체를 얻는다. 나는 그것을 효율적으로하고 싶다.apply 함수를 사용하여 data.table을 반환하거나 목록을 직접 data.table로 변환합니다.

my.function <- function(x){ 
    alnRanges<-cigarToIRanges(x[6]); 
    alnStarts<-start(alnRanges)+as.numeric(x[4])-1; 
    alnEnds<-end(alnRanges)+as.numeric(x[4])-1; 
    y<-x[-4]; 
    ys<-matrix(rep(y,length(alnRanges)),nrow=length(alnRanges),ncol=length(y),byrow=TRUE); 
    ys<-cbind(ys,alnStarts,alnEnds); 
    return(ys);  # ys is a matrix 
} 

    my.dt<-fread(my.file.name); 
    my.list.of.matrices<-apply(my.dt,1,my.function); 
    new.df<-do.call(rbind.data.frame,my.list.of.matrices); 
    colnames(new.df)[1:14]<-colnames(my.dt)[-4]; 
    new.dt<-as.data.table(new.df); 

주 : 나의 현재의 접근 방식은 다음과 같다 내가 그냥 매트릭스를 반환 보여주기 위해 my.function를 지정하고, 내 라인 따라서 행렬의 목록입니다 적용하는 것이.

주 2 : 내가하고있는 작업이 얼마나 느린지는 모르지만 줄 수를 줄일 수있는 것으로 보입니다. 예를 들어 대형 객체의 데이터 테이블을 데이터 테이블로 변환하는 것이 느린가요?

재현 예 : 아룬와 롤랜드가 나를 이렇게 내가 아직도 일하고 ​​문제 ... 나는이 선을 필요로하지 않는 것이있을 수 있습니다에 대해 열심히 생각하게

주 ...

I sam 파일을 가져 와서 각 읽기가 CIGAR 필드에 따라 분할되는 새로운 좌표 파일을 작성하려고합니다.

My sam file: 
qname rname pos cigar 
2218 chr1 24613476 42M2S 
2067 chr1 87221030 44M 
2129 chr1 79702717 44M 
2165 chr1 43113438 44M 
2086 chr1 52155089 4M921N40M 

code: 

library("data.table"); 
library("GenomicRanges"); 

sam2bed <- function(x){ 
    alnRanges<-cigarToIRanges(x[4]); 
    alnStarts<-start(alnRanges)+as.numeric(x[3])-1; 
    alnEnds<-end(alnRanges)+as.numeric(x[3])-1; 
    #y<-as.data.frame(x[,pos:=NULL]); 
    #ys<-y[rep(seq_len(nrow(y)),length(alnRanges)),]; 
    y<-x[-3]; 
    ys<-matrix(rep(y,length(alnRanges)),nrow=length(alnRanges),ncol=length(y),byrow=TRUE); 
    ys<-cbind(ys,alnStarts,alnEnds); 
    return(ys); 
} 


sam.chr.dt<-fread(sam.parent.chr.file); 
setnames(sam.chr.dt,old=c("V1","V2","V3","V4"),new=c("qname","rname","pos","cigar")); 
bed.chr.lom<-apply(sam.chr.dt,1,sam2bed); 
> bed.chr.lom 
[[1]] 
          alnStarts alnEnds 
[1,] "2218" "chr1" "42M2S" "24613476" "24613517" 

[[2]] 
         alnStarts alnEnds 
[1,] "2067" "chr1" "44M" "87221030" "87221073" 

[[3]] 
         alnStarts alnEnds 
[1,] "2129" "chr1" "44M" "79702717" "79702760" 

[[4]] 
         alnStarts alnEnds 
[1,] "2165" "chr1" "44M" "43113438" "43113481" 

[[5]] 
           alnStarts alnEnds 
[1,] "2086" "chr1" "4M921N40M" "52155089" "52155092" 
[2,] "2086" "chr1" "4M921N40M" "52156014" "52156053" 

bed.chr.df<-do.call(rbind.data.frame,bed.chr.lom); 

> bed.chr.df 
    V1 V2  V3 alnStarts alnEnds 
1 2218 chr1  42M2S 24613476 24613517 
2 2067 chr1  44M 87221030 87221073 
3 2129 chr1  44M 79702717 79702760 
4 2165 chr1  44M 43113438 43113481 
5 2086 chr1 4M921N40M 52155089 52155092 
6 2086 chr1 4M921N40M 52156014 52156053 

bed.chr.dt<-as.data.table(bed.chr.df); 

> bed.chr.dt 
    V1 V2  V3 alnStarts alnEnds 
1: 2218 chr1  42M2S 24613476 24613517 
2: 2067 chr1  44M 87221030 87221073 
3: 2129 chr1  44M 79702717 79702760 
4: 2165 chr1  44M 43113438 43113481 
5: 2086 chr1 4M921N40M 52155089 52155092 
6: 2086 chr1 4M921N40M 52156014 52156053 
+0

data.table에는'apply'가 필요하지 않습니다. 목표는 사본을 피해야합니다. 재현 가능한 데이터를 제공하고 실제로하려는 것을 설명하십시오. – Roland

+0

@Roland, data.table의 각 행에 함수를 적용해야합니다. 적용을 사용해서는 안되면 내가 할 수있는 것이 무엇인지 모르겠다. 데이터 테이블에 익숙하지 않지만 데이터 프레임보다 훨씬 빠르다. 예제를 만들려고 노력하는 중 ... – Dnaiel

+1

내가 말했듯이, (데이터와 필요한 패키지를 포함한) 실제 예제를 제공하고 달성하고자하는 것을 알려주십시오. data.table을'apply'와 섞어 쓰면 장점이 없습니다. – Roland

답변

3

ff 가정에서는 이것에 대해, 당신의 data.table입니까?

splits <- cigarToIRangesListByAlignment(ff$cigar, ff$pos, reduce.ranges = TRUE) 
widths <- width(attr(splits, 'partitioning')) 
cbind(data.table(qname=rep.int(ff$qname, widths), 
      rname=rep.int(ff$rname, widths)), as.data.frame(splits)) 

    qname rname space start  end width 
1: 2218 chr1  1 24613476 24613517 42 
2: 2067 chr1  2 87221030 87221073 44 
3: 2129 chr1  3 79702717 79702760 44 
4: 2165 chr1  4 43113438 43113481 44 
5: 2086 chr1  5 52155089 52155092  4 
6: 2086 chr1  5 52156014 52156053 40 
+0

고마워요! 좋은 제안. 또한 rsamtools와 iranges에 대해서도 연구 중입니다. 아마이 접근법에 모든 코드를 바꿀 수 있기 때문입니다 ... 감사합니다! – Dnaiel