2017-01-25 10 views
2

dplyrからfilterまでのデータをテスト条件に基づいて使用しようとしていますが、このテスト条件は他の変数によって変わる可能性があります。テスト条件を使用してdplyrでデータをフィルタリングする

if (foo == 0) { 
    test <- speed > 15 
} else { 
    test <- dist < 50 
} 
filter(cars, test) 

これは動作しません:私はこのような何かをしたいと思います

data(cars) 

:サンプルデータセットcarsに建てを使用して

if (foo == 0) { 
    test <- 'cars$speed > 15' 
} else { 
    test <- 'cars$dist < 50' 
} 
filter(cars, eval(parse(text = test))) 

しかし

  1. cars$speedcars$distfilter機能を使用する目的を破るように見えるを入力すること:私はこのような何かにそれを変更した場合、私はそれが仕事を得ることができます。
  2. thisによると、eval(parse(text = ...))の使用はお勧めできません。

これを実現する方法はありますか?

答えて

0

これが私の作品:

library(dplyr) 

if (foo == 0) { 
    test <- cars$speed > 15 
} else { 
    test <- cars$dist < 50 
} 

filter(cars, test) 

私はあなたがfilterを使用しているという理由だけでcars$speedcars$distを使用して、問題が表示されません。また、本当にfilterを使用する必要がありますか?あなたがこれを行うことができます

cars[test,] 
+0

感謝を!私は 'cars [test、]'がこのケースのより良い解決策になることに同意します。これは質問のための最小限のコードスニペットのための単純な例でした。何らかの理由で、これは私がdf、column、およびvalueを取り込み、フィルタリングされた結果セットを返す関数にこれを埋め込もうとしたときには機能しませんでした。しかし実際には、この種のロジックを使用して実際に動作しているようです。 – Steve

3

:で、最後の行を置き換え、この使用してベースR.を行うための代替があります単純なフィルタと比較することにより、

filter(cars, if(foo==0){speed>15}else{dist<50}) 

テスト:

> foo =0 
> identical(filter(cars, speed>15), filter(cars, if(foo==0){speed>15}else{dist<50})) 
[1] TRUE 
> foo =1 
> identical(filter(cars, dist<50), filter(cars, if(foo==0){speed>15}else{dist<50})) 
[1] TRUE 

filterステートメントを中括弧の中に入れるのは簡単で簡単です:

if (foo == 0) { 
    filter(cars, speed > 15) 
} else { 
    filter(cars, dist < 50) 
} 

注意あなたがどこかにその結果を割り当てたい場合は、ifが値を返す:

> ff = if (foo == 0) { 
     filter(cars, speed > 15) 
    } else { 
     filter(cars, dist < 50) 
    } 
> identical(ff, filter(cars, speed>15)) 
[1] FALSE 
> identical(ff, filter(cars, dist<50)) 
[1] TRUE 
> foo 
[1] 1 
+0

ありがとう!これは素晴らしい解決策です – Steve

関連する問題