2017-08-25 7 views
2

同じ条件で異なる列を使用して行を選択したいとします。複数の列で同じ条件の行をフィルタリングする

set.seed(123) 
df <- data.frame(col.x = sample(LETTERS[1:10], 20, replace = TRUE), 
       col.y = sample(LETTERS[1:10], 20, replace = TRUE), 
       val = rnorm(20)) 

は、私は2つの列col.xcol.y渡っValsToRetainで値だけを持っている必要があります。

ValsToRetain <- c('A','D', 'F','H','J') 

私は、同じ期待される出力を与えるこれら2つのアプローチを試しました。

df %>% filter(col.x %in% ValsToRetain) %>% filter(col.y %in% ValsToRetain) 
df %>% filter(col.x %in% ValsToRetain & col.y %in% ValsToRetain) 
# col.x col.y  val 
# 1  A  H -1.6866933 
# 2  F  F 0.8377870 
# 3  J  J 0.4264642 
# 4  F  H 0.8781335 
# 5  D  D -0.3059627 

しかし、これを行うための他の優雅なやり方はありますか?

たとえば、これらの列にわたってrowSumsを計算して、naがあるかどうかを確認します。複数の価値があるので、私はrowSums(df[,1:2] == 'A')のような考えを得ることができませんでした。

答えて

3

私たちは、あなたがサブセットを使用することができますall_vars

df %>% 
    filter_at(vars(starts_with("col")), all_vars(. %in% ValsToRetain)) 
# col.x col.y  val 
#1  A  H -1.6866933 
#2  F  F 0.8377870 
#3  J  J 0.4264642 
#4  F  H 0.8781335 
#5  D  D -0.3059627 
+0

ありがとう、それは間違いなくそれを行うエレガントな方法です。 col名が 'xvar'、' yvar'だったら他の方法がありますか 、 'valvar'?それは 'filter_at(vars( 'xvar'、 'yvar')、all_vars(%は%ValsToRetain)です)' ?? Btw、 'dplyr'のどのバージョンを使用していますか? '関数を見つけることができませんでした 'というエラーが表示されます。filter_at" ' – Prradep

+2

これは、varsの否定版、すなわち 'df%>%filter_at(vars(-val)、all_vars(%in%ValsToRetain))' – Sotos

-1

filter_atを使用することができ、それはかなり短いですが、あなたの方法と同じ方法が:

filt <- subset(df,col.x %in% ValsToRetain & col.y %in% ValsToRetain) 

出力は次のようになります。

col.x col.y  val 
    A  H -1.6866933 
    F  F 0.8377870 
    J  J 0.4264642 
    F  H 0.8781335 
    D  D -0.3059627 
+0

をとります。これはOPの2番目のオプション* df%>%filterとまったく同じですあなたは 'filter'の代わりに' subset'を使用しました – Sotos

+0

@Sotosそれはまさに私があなたの方法と同じ方法を言ったことです。私が推測するdownvoteを入れなければならない –

+1

OPはこれを行う*他のエレガントな方法を求めているので、downvoteが正当であると感じます* ...私はあなたが少なくともいくつかあなたの答えに価値をもたらし、私は投票を元に戻してうれしく思います。例えば、df%>%mutate_at(vars(-val)、funs(replace(。、ValsToRetain、NA))))%>%na.omit()の行に沿って何かする必要があります – Sotos

1

Reduceとを使った基底R法です。 lapplyは、関連する列にまたがって%in%を適用し、論理ベクトルのリストを返します。 Reduceは、&を使用してこれらのベクターを1つのベクターに結合します。

df[Reduce("&", lapply(df[c("col.x", "col.y")], "%in%", ValsToRetain)),] 
    col.x col.y  val 
6  A  H -1.6866933 
7  F  F 0.8377870 
11  J  J 0.4264642 
14  F  H 0.8781335 
19  D  D -0.3059627 

あなたは比較のために多くの列を持っている場合は、c("col.x", "col.y")の代わりにgrep("^col", names(df))のようにそれらを選択するために、grepを使用することができます。

関連する問題