2013-08-08 22 views
7

を選択するための最速の方法これはR.でreturning the rows of a matrix that meet a condition上の質問への拡張であるが、私が行列を持って言う:R - 複数の条件を満たす行列の行

 one two three four 
[1,] 1 6 11 16 
[2,] 2 7 12 17 
[3,] 3 8 11 18 
[4,] 4 9 11 19 
[5,] 5 10 15 20 
[6,] 1 6 15 20 
[7,] 5 7 12 20 

私はすべての行を返すようにしたいです、できるだけ速く、matrix$two == 7およびmatrix$three == 12。これは私がそれを行うには知っている方法です:

out <- mat[mat$two == 7,] 
final_out <- out[out$three == 12, ] 

明らかワンライナーでfinal_outの内容を取得する方法、のようなものがあるはずです:の2行より速く、より簡潔であるfinal_out <- which(mat$two == 7 && mat$three == 12)上記のコード。

この複数の条件行列クエリを返す最も速いRコードは何ですか?以下のようにarr.ind=TRUE

答えて

11

ちょうどRでの絶対的な最速の方法はifと違ってベクトル化することができますifelseになります...論理比較で

# Reproducible data 
set.seed(1) 
m <- matrix(sample(12,28,repl=T) , 7 , 4) 
    [,1] [,2] [,3] [,4] 
[1,] 4 8 10 3 
[2,] 5 8 6 8 
[3,] 7 1 9 2 
[4,] 11 3 12 4 
[5,] 3 3 5 5 
[6,] 11 9 10 1 
[7,] 12 5 12 5 


# Subset according to condition 
m[ m[,2] == 3 & m[,3] == 12 , ] 
[1] 11 3 12 4 
1

使用which

> mat[which(mat[,"two"]==7 & mat[,"three"] == 12, arr.ind = TRUE),] 
    one two three four 
2 2 7 12 17 
7 5 7 12 20 
+0

または 'mat [mat"、 "two"] == 7&mat [、 "three"] == 12、] – Roland

+0

私は質問を完全に読まなかったし、OPは既に'which'を使用しました –

+0

$サブセットは行列に適していますか?私はエラーが発生します。 – dayne

-2

[サブセットを使用します条件付き。また、条件文のベクトルをキャッシュし(例:isSeven <- mat[, 'two'] == 7)、後で使用/再利用することもできます。

私はここに再現可能な例を持っていないが、私はあなたがそこに他の条件文をウンチか、順応性のベクトルになります何かを返すことができます

ifelse(mat[, 'two'] == 7 & mat[, 'three'] == 12, "both", "not both") 

ような何かをするだろう。マイクロベンチマークを使用した

+0

'ifelse'は論理的なサブセッティングより速いとは思いません。 Afterall、それはまさに 'ifelse'が内部的にするものです。 – Roland

+1

Ummm、これが最も速いという主張は間違っています! –

3

UPDATE:

ベンチマークを使用するには、反対の答えを与えます。 @ SimonO101の答えは少し速い実装を提供するようです。

require(microbenchmark) 
set.seed(1) 
m <- matrix(sample(12,100,repl=T) , 25 , 4) 
colnames(m) <- c("one","two","three","four") 

bench1 <- microbenchmark(m[which(m[,'two']==7 & m[,'three'] == 12, arr.ind = TRUE),]) 
summary(bench1$time) 
    Min. 1st Qu. Median Mean 3rd Qu. Max. 
    7700 8750 9449 9688 9800 22400 

bench2 <- microbenchmark(m[ m[,2] == 3 & m[,3] == 12 , ]) 
summary(bench2$time) 
    Min. 1st Qu. Median Mean 3rd Qu. Max. 
    6300 7350 7351 7599 8050 15400 

OLD ANSWER:@JiberでとSimonO101 @与えられた答えを組み合わせる

は、少なくとも私のコンピュータ上で、多少速く答えを与えます。

計算時間を分けるために行列をもっと大きくしました。

set.seed(1) 
m <- matrix(sample(12,1000000000,repl=T) , 1e8 , 10) 
colnames(m) <- c("one","two","three","four","five","six","seven","eight","nine","ten") 

system.time(m[which(m[,'two']==7 & m[,'three'] == 12, arr.ind = TRUE),]) 
    user system elapsed 
    6.49 1.58 8.06 
system.time(m[ m[,2] == 3 & m[,3] == 12 , ]) 
    user system elapsed 
    8.23 1.29 9.52 

これは明らかに、マトリックスの列に名前が付けられていることを前提としています。

+1

時間を計算するのに 'library(microbenchmark)'を使うべきです...もっと信頼できます。 – Thomas

+0

@Thomasはチップをありがとう。これはベンチマークでの私の最初の試みでした。私はパッケージをインストールした後、答えを更新します。 – dayne

+0

しばらく時間がかかることがありますので、周りを見て、あなたは人々がそれを使用する方法の他の例を参照してください。 – Thomas

関連する問題