2

BiomaRtパッケージを使用してデータベースにクエリを実行したいと思います。私はlociいくつかの関連情報を持っていて、それを取得したいと思っていますdescription

私は最初に使用しようとしましlapplyたが、タスクの実行に必要な時間に驚きました。したがって、私はより基本的なものを試し、よりfor-loop速い結果を得ました。

それは予想されたものですか、それとも私のコードまたは私の理解に何か問題がありapplyますか?*applyvsfor-loopパフォーマンスを扱った他の投稿を読んで(たとえば、ここで)、パフォーマンスの向上は期待できないことを認識していましたが、ここでのパフォーマンスが実際に低い理由がわかりません。

これが再現可能な例です。

1)ライブラリをロードしてデータベースを選択します。

library("biomaRt")
athaliana <- useMart("plants_mart_14")
athaliana <- useDataset("athaliana_eg_gene",mart=athaliana)

2)データベースのクエリ:

loci <- c("at1g01300", "at1g01800", "at1g01900", "at1g02335", "at1g02790", 
"at1g03220", "at1g03230", "at1g04040", "at1g04110", "at1g05240"
)

で使用する関数を作成しますlapply

foo <- function(loci) {
  getBM("description","tair_locus",loci,athaliana)
}

最初の要素でこの関数を使用すると:

> system.time(foo(cwp_loci[1]))
utilisateur     système      écoulé 
      0.020       0.004       1.599

lapplyすべての値のデータを取得するために使用する場合:

> system.time(lapply(loci, foo))
utilisateur     système      écoulé 
      0.220       0.000      16.376

次に、新しい関数を作成し、for-loop:を追加しました。

foo2 <- function(loci) {
  for (i in loci) {
    getBM("description","tair_locus",loci[i],athaliana)
  }
}

結果は次のとおりです。

> system.time(foo2(loci))
utilisateur     système      écoulé 
      0.204       0.004      10.919

もちろん、これはの大きなリストに適用されるlociため、最高のパフォーマンスを発揮するオプションが必要です。助けてくれてありがとう。

編集@MartinMorganの推奨に従って

ベクトルlociをgetBMに渡すだけで、クエリの効率が大幅に向上します。シンプルな方が良いです。

> system.time(lapply(loci, foo))
utilisateur     système      écoulé 
      0.236       0.024     110.512 

> system.time(foo2(loci))
utilisateur     système      écoulé 
      0.208       0.040     116.099 

> system.time(foo(loci))
utilisateur     système      écoulé 
      0.028       0.000       6.193 
4

2 に答える 2

4

これは、ラップとforループとは何の関係もないと感じています。1.6秒かかるデータベースへの呼び出しがあります。ラッププライはこれを10回、つまり合計16秒行います。forループは何も変わりません。データベースを10回呼び出します。ただし、applyループが実行したのと同じクエリを実行するため、データベースにクエリを実行する代わりに、データベースがキャッシュされた結果を返す可能性があります。これは、呼び出しの順序を逆にして、時間がlapplyに有利であるかどうかを確認することで確認できます。チャットでデータベースのキャッシュを提案してくれた@JoshuaUlrichに感謝します。データベースキャッシング(またはWebサーバーによるキャッシング)に加えて、@ MartinMorganの提案は、所要時間にかなりのランダム性を追加しgetBMます。

結論として、可能性は非常に大きく、違いはRの外側にあり、ループ、ラップ、またはforループのスタイルとは関係ありません。

于 2012-09-05T21:24:15.973 に答える
2

関数のapplyファミリーは慣用的ですが、forループの単なる構文糖衣です。彼らはしばしば遅いです。joranが指摘したように、これは以前にSOで尋ねられました。

Rのループを高速化するためのヒントが必要な場合は、「Rヘルプデスク-このループを回避または高速化するにはどうすればよいですか?」というRニュース(pdf)のこの巻の46ページを参照してください。

于 2012-09-05T21:02:07.580 に答える