Konrad
Konrad

Reputation: 18595

How to correctly use all in dplyr's filter?

Given simple code:

mtcars %>% 
  filter(am == 1 & cyl == 4)

the use of & returns:

   mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
2 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
3 30.4   4  75.7  52 4.93 1.615 18.52  1  1    4    2
4 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
5 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1
6 26.0   4 120.3  91 4.43 2.140 16.70  0  1    5    2
7 30.4   4  95.1 113 3.77 1.513 16.90  1  1    5    2
8 21.4   4 121.0 109 4.11 2.780 18.60  1  1    4    2

I would like to arrive at the same result using base::all, but the code:

mtcars %>% 
  filter(all(am == 1, cyl == 4))

does not produce desired results:

 [1] mpg  cyl  disp hp   drat wt   qsec vs   am   gear carb
<0 rows> (or 0-length row.names)

Hence my question, how to correctly use all within dplyr's filter?


Notes:

Upvotes: 3

Views: 75

Answers (2)

Roman
Roman

Reputation: 17648

As an addon to the nice explanation of @rosscova you can try

mtcars %>% rowwise() %>% filter(all(am == 1, cyl == 4))

Upvotes: 3

rosscova
rosscova

Reputation: 5590

all is slightly different from &, which is why it doesn't work as expected here. From the docs for all:

Let ‘x’ denote the concatenation of all the logical vectors in ‘...’ (after coercion), after removing ‘NA’s if requested by ‘na.rm = TRUE’.

The value returned is ‘TRUE’ if all of the values in ‘x’ are ‘TRUE’ (including if there are no values), and ‘FALSE’ if at least one of the values in ‘x’ is ‘FALSE’. Otherwise the value is ‘NA’ (which can only occur if ‘na.rm = FALSE’ and ‘...’ contains no ‘FALSE’ values and at least one ‘NA’ value).

Both & and all will take multiple logical vectors as input, but where & will return a new logical vector the same length as each of the inputs, all will always return a single logical value (TRUE if all values match the conditions, and FALSE if they don't).

filter needs a logical vector: TRUE to keep a row, or FALSE to discard it. A single logical value doesn't help. filter is then only able to either keep or discard all rows based on the single logical value returned by all.

Upvotes: 1

Related Questions