パフォーマンスを向上させるために「サプライ」コマンドを書き直す方法は?

StackOverflow https://stackoverflow.com/questions/5303807

  •  24-10-2019
  •  | 
  •  

質問

〜1,300,000行と4列の「D」という名前のデータがあり、4列の4つの列と、〜12,000行と2列の「GC」という名前のフレームがあります(ただし、以下の小さな例を参照)。

d <- data.frame( gene=rep(c("a","b","c"),4), val=rnorm(12), ind=c( rep(rep("i1",3),2), rep(rep("i2",3),2) ), exp=c( rep("e1",3), rep("e2",3), rep("e1",3), rep("e2",3) ) )
gc <- data.frame( gene=c("a","b","c"), chr=c("c1","c2","c3") )

「D」がどのように見えるかは次のとおりです。

   gene         val ind exp
1     a  1.38711902  i1  e1
2     b -0.25578496  i1  e1
3     c  0.49331256  i1  e1
4     a -1.38015272  i1  e2
5     b  1.46779219  i1  e2
6     c -0.84946320  i1  e2
7     a  0.01188061  i2  e1
8     b -0.13225808  i2  e1
9     c  0.16508404  i2  e1
10    a  0.70949804  i2  e2
11    b -0.64950167  i2  e2
12    c  0.12472479  i2  e2

そして、ここに「GC」があります:

  gene chr
1    a  c1
2    b  c2
3    c  c3

「D」の最初の列と一致する「GC」からのデータを組み込むことにより、「D」に5列を追加したいと思います。今のところ私は使用しています さくらんぼ.

d$chr <- sapply( 1:nrow(d), function(x) gc[ gc$gene==d[x,1], ]$chr )

しかし、実際のデータでは、「非常に長い」時間がかかります(30分以上から「System.Time()」でコマンドを実行していますが、まだ終了していません)。

これを賢い方法で書き直す方法について何か考えがありますか?または、使用を検討する必要があります Plyr, 、たぶん「並列」オプションがあります(コンピューターに4つのコアがあります)?そのような場合、最高の構文は何ですか?

前もって感謝します。

役に立ちましたか?

解決

要因をインデックスとして使用できると思います。

gc[ d[,1], 2]
 [1] c1 c2 c3 c1 c2 c3 c1 c2 c3 c1 c2 c3
Levels: c1 c2 c3

同じことをします:

 sapply( 1:nrow(d), function(x) gc[ gc$gene==d[x,1], ]$chr )
 [1] c1 c2 c3 c1 c2 c3 c1 c2 c3 c1 c2 c3
Levels: c1 c2 c3

しかし、はるかに速いです:

> system.time(replicate(1000,sapply( 1:nrow(d), function(x) gc[ gc$gene==d[x,1], ]$chr )))
   user  system elapsed 
   5.03    0.00    5.02 
> 
> system.time(replicate(1000,gc[ d[,1], 2]))
   user  system elapsed 
   0.12    0.00    0.13 

編集:

私のコメントを少し拡大するために。 gc データフレームには、の各レベルに1つの行が必要です gene これが機能するレベルの順序で:

 d <- data.frame( gene=rep(c("a","b","c"),4), val=rnorm(12), ind=c( rep(rep("i1",3),2), rep(rep("i2",3),2) ), exp=c( rep("e1",3), rep("e2",3), rep("e1",3), rep("e2",3) ) )
gc <- data.frame( gene=c("c","a","b"), chr=c("c1","c2","c3") )

gc[ d[,1], 2]
 [1] c1 c2 c3 c1 c2 c3 c1 c2 c3 c1 c2 c3
Levels: c1 c2 c3

sapply( 1:nrow(d), function(x) gc[ gc$gene==d[x,1], ]$chr )
 [1] c2 c3 c1 c2 c3 c1 c2 c3 c1 c2 c3 c1
Levels: c1 c2 c3

しかし、それを修正するのは難しくありません:

levels(gc$gene) <- levels(d$gene) # Seems redundant as this is done right quite often automatically
gc <- gc[order(gc$gene),]


gc[ d[,1], 2]
 [1] c2 c3 c1 c2 c3 c1 c2 c3 c1 c2 c3 c1
Levels: c1 c2 c3

sapply( 1:nrow(d), function(x) gc[ gc$gene==d[x,1], ]$chr )
 [1] c2 c3 c1 c2 c3 c1 c2 c3 c1 c2 c3 c1
Levels: c1 c2 c3

他のヒント

Sashaのアプローチをタイミングで打ち負かすことはありませんが、より一般化可能で読みやすい代替ソリューションは、単に merge 2つのデータフレーム:

d <- merge(d, gc)

システムが遅いので、ここに私のタイミングがあります:

> system.time(replicate(1000,sapply( 1:nrow(d), function(x) gc[ gc$gene==d[x,1], ]$chr )))
   user  system elapsed 
  11.22    0.12   11.86 
> system.time(replicate(1000,gc[ d[,1], 2])) 
   user  system elapsed 
   0.34    0.00    0.35 
> system.time(replicate(1000, merge(d, gc, by="gene"))) 
   user  system elapsed 
   3.35    0.02    3.40 

利点は、複数のキー、一致しないアイテムを細かく制御できることなどです。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top