4

Rで行単位の処理を回避するのが最善の方法だと思っていました。行単位の処理のほとんどは、内部Cルーチンで実行されます。例:データフレームがありますa

  chromosome_name start_position end_position strand
1              15       35574797     35575181      1
2              15       35590448     35591641     -1
3              15       35688422     35688645      1
4              13       75402690     75404217      1
5              15       35692892     35693969      1

私が欲しいのは、ストランドが正か負か、startOFgeneasstart_positionまたは。に基づいていend_positionます。ループを回避する1つの方法は、fordata.frameを+1ストランドと-1ストランドで分離し、選択を実行することです。スピードアップする他の方法は何ですか?行ごとに他の複雑な処理がある場合、このメソッドはスケールアップしません。

4

2 に答える 2

5

多分これは十分に速いです...

transform(a, startOFgene = ifelse(strand == 1, start_position, end_position))


  chromosome_name start_position end_position strand startOFgene
1              15       35574797     35575181      1    35574797
2              15       35590448     35591641     -1    35591641
3              15       35688422     35688645      1    35688422
4              13       75402690     75404217      1    75402690
5              15       35692892     35693969      1    35692892
于 2012-12-14T12:46:38.243 に答える
3

まず、すべての列が整数/数値であるため、data.frameの代わりに行列を使用できます。マトリックスに対する多くの操作は、この場合はそれほど違いはありませんが、data.frameに対する同じ操作よりもはるかに高速です。次に、論理サブセットを使用してstartOFgene列を作成できます。

# Create some large-ish data
M <- do.call(rbind,replicate(1e3,as.matrix(a),simplify=FALSE))
M <- do.call(rbind,replicate(1e3,M,simplify=FALSE))
A <- as.data.frame(M)
# Create startOFgene column in a matrix
m <- function() {
  M <- cbind(M, startOFgene=M[,"start_position"])
  negStrand <- sign(M[,"strand"]) < 0
  M[negStrand,"startOFgene"] <- M[negStrand,"end_position"]
}
# Create startOFgene column in a data.frame
d <- function() {
  A$startOFgene <- A$start_position
  negStrand <- sign(A$strand) < 0
  A$startOFgene[negStrand] <- A$end_position[negStrand]
}
library(rbenchmark)
benchmark(m(), d(), replications=10)[,1:6]
#   test replications elapsed relative user.self sys.self
# 2  d()           10  18.804    1.000    16.501    2.224
# 1  m()           10  19.713    1.048    16.457    3.152
于 2012-12-14T13:52:39.660 に答える