2012-02-13 23 views
34

を使用してベクトルをフィルタ:R - 私はこの1と同様の機能を持っている機能

isGoodNumber <- function(X) 
{ 
if (X==5) return(TRUE) else return(FALSE) 
} 

I have a vector: 
v<-c(1,2,3,4,5,5,5,5) 

私はisGoodNumber(v) == TRUE

私はどのように行うのですvの要素を含む新しいベクタを取得したいですこの ?

v [ isGoodNumber(v) == TRUE ]を試みたが、それは

感謝:-)動作しません!

+0

この機能を書き換えることはできますか?または関数が定義されていて、それを変更できませんか? – Dason

+2

あなたの実際のアプリケーションはこの例より複雑だと思っていますが、 'v [v == 5]'はあなたの例のトリックを行います。 – Chase

+0

こんにちは@Dason、はい私は関数を書き直すことができます:-) – MadSeb

答えて

20

あなたはベクトルにそれを呼び出すためにVectorizeに機能が必要になります:

isGoodNumber = Vectorize(isGoodNumber) 
v[isGoodNumber(v)] 
+0

はい、これは動作します!ありがとう! – MadSeb

7

使用mapply()

> v <- c(1,2,3,4,5,5,5,5) 
> newV <- mapply(function(X) { if (X==5) return(TRUE) else return(FALSE) }, v) 
> newV 
[1] FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE 
> v[newV == TRUE] 
[1] 5 5 5 5 
43

正確に何をあなたに尽くします「Filter」という名前の関数があります欲しい:

Filter(isGoodNumber, v) 
#[1] 5 5 5 5 

optio既に説明したVectorize関数を使用してベクトル化された関数を作成するか、またはifelse(これも同様)を記述することによってベクトル化された関数を作成し、「フィルタ」のような関数のオプションがあります。

isGoodNumber3 <- function(X) 
    { X[ ifelse(X==5, TRUE,FALSE)] 
    } 

isGoodNumber3(v) 
#[1] 5 5 5 5 
+2

これは、 'v'が計算された式であれば、**良い事**である' v'の繰り返しを必要としない唯一の答えです。 – krlmlr

20

私はあなたが可能な限りベクトル化関数を書くのが習慣に取得する必要があり、最も簡単な方法

> v<-c(1,2,3,4,5,5,5,5) 
> v[v==5] 
[1] 5 5 5 5 
4

で、ここだと思います。たとえば、関数f(x)を作成する場合は、xが単一の数値ではなくベクトルである場合に機能することを確認してください。非常に大きなベクトルでは遅くなるので、Vectorizeには依存しないでください。

有用な手法は、if ... then ... elseifelseに置き換えることです。例:あなたはもちろんの事合理化することができ、この特定のケースで

isGoodNumber <- function(X) 
{ 
    ifelse(X==5, TRUE, FALSE) 
} 
v<-c(1,2,3,4,5,5,5,5) 
v [ isGoodNumber(v) == TRUE ] 

:ちょうど

v[v==5] 

isGoodNumber <- function(X) return(X==5) 

たりしますがifelse技術は、より一般的に有用であろう。

関連する問題