mhovd
mhovd

Reputation: 4087

Filter dataframe by rowwise condition

I would like to filter a dataframe by the rowwise conditions of another dataframe.

For example,

library(dplyr)

# This is the dataframe containing the conditions that we want to filter by.
# In this case it is the first three rows, but note that other rows also satisfy the conditions
conds <- data.frame(cyl = c(6,6,4), carb = c(4,4,1))

# This is too inclusive
mtcars %>% filter(cyl %in% conds$cyl, carb %in% conds$carb)
#>                 mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#> Mazda RX4      21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#> Mazda RX4 Wag  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#> Datsun 710     22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#> Hornet 4 Drive 21.4   6 258.0 110 3.08 3.215 19.44  1  0    3    1
#> Valiant        18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
#> Merc 280       19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
#> Merc 280C      17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
#> Fiat 128       32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
#> Toyota Corolla 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
#> Toyota Corona  21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
#> Fiat X1-9      27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1

# And this fails due to object length
mtcars %>% filter(cyl == conds$cyl, carb == conds$carb)
#> Warning in cyl == conds$cyl: longer object length is not a multiple of shorter
#> object length
#> Warning in carb == conds$carb: longer object length is not a multiple of shorter
#> object length

To clarify, my desired output only contains the rows of mtcars where the row of conditions in conds are met.

Upvotes: 0

Views: 76

Answers (2)

Edo
Edo

Reputation: 7858

How about semi_join:

mtcars %>% semi_join(conds, by = c("cyl", "carb"))
#>                 mpg cyl  disp  hp drat    wt  qsec vs am gear carb
#> Mazda RX4      21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
#> Mazda RX4 Wag  21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
#> Datsun 710     22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
#> Merc 280       19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
#> Merc 280C      17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
#> Fiat 128       32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
#> Toyota Corolla 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
#> Toyota Corona  21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
#> Fiat X1-9      27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1

semi_join keep only the rows in mtcars that are also in conds

Upvotes: 3

ekoam
ekoam

Reputation: 8844

Is this what you want?

mtcars %>% tibble::rownames_to_column("model") %>% inner_join(conds %>% distinct())

Output

Joining, by = c("cyl", "carb")
           model  mpg cyl  disp  hp drat    wt  qsec vs am gear carb
1      Mazda RX4 21.0   6 160.0 110 3.90 2.620 16.46  0  1    4    4
2  Mazda RX4 Wag 21.0   6 160.0 110 3.90 2.875 17.02  0  1    4    4
3     Datsun 710 22.8   4 108.0  93 3.85 2.320 18.61  1  1    4    1
4       Merc 280 19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
5      Merc 280C 17.8   6 167.6 123 3.92 3.440 18.90  1  0    4    4
6       Fiat 128 32.4   4  78.7  66 4.08 2.200 19.47  1  1    4    1
7 Toyota Corolla 33.9   4  71.1  65 4.22 1.835 19.90  1  1    4    1
8  Toyota Corona 21.5   4 120.1  97 3.70 2.465 20.01  1  0    3    1
9      Fiat X1-9 27.3   4  79.0  66 4.08 1.935 18.90  1  1    4    1

Upvotes: 0

Related Questions