Ammar Gamal
Ammar Gamal

Reputation: 211

Subsetting Dataframe by Another logical Dataframe

I have the following two dataframes, the first is the main one, and the second is the logical one.

df <- data.frame(
      x= c(1:10),
      y= c(11:20),
      z= c(21:30))
> df
  x  y  z
1   1 11 21
2   2 12 22
3   3 13 23
4   4 14 24
5   5 15 25
6   6 16 26
7   7 17 27
8   8 18 28
9   9 19 29
10 10 20 30

logic_df <- data.frame(
  x = c(rep(TRUE,2),rep(FALSE,8)),
  y = c(rep(TRUE,3),rep(FALSE,7)),
  z = c(rep(FALSE,9),rep(TRUE,1))
)
    > logic_df
       x     y     z
1   TRUE  TRUE FALSE
2   TRUE  TRUE FALSE
3  FALSE  TRUE FALSE
4  FALSE FALSE FALSE
5  FALSE FALSE FALSE
6  FALSE FALSE FALSE
7  FALSE FALSE FALSE
8  FALSE FALSE FALSE
9  FALSE FALSE FALSE
10 FALSE FALSE  TRUE

my goal is to achieve this:

 x  y  z
1  1 11 21
2  2 12 22
3  3 13 23
4 10 20 30

I could achieve it by a long way so I appreciate if someone has a shortcut for it. thanks in advance

Upvotes: 2

Views: 60

Answers (3)

akrun
akrun

Reputation: 887118

Using if_any from dplyr

library(dplyr)
df %>%
  filter((if_any(everything(), ~ logic_df[[cur_column()]])))
   x  y  z
1  1 11 21
2  2 12 22
3  3 13 23
4 10 20 30

Upvotes: 0

PaulS
PaulS

Reputation: 25323

Another possible solution, based on dplyr:

library(dplyr)

df %>% 
  filter(do.call(pmax, logic_df) == 1)

#>    x  y  z
#> 1  1 11 21
#> 2  2 12 22
#> 3  3 13 23
#> 4 10 20 30

Upvotes: 3

Kra.P
Kra.P

Reputation: 15123

You may try

df[rowSums(logic_df) > 0,]
    x  y  z
1   1 11 21
2   2 12 22
3   3 13 23
10 10 20 30

I'm not sure where 31 came from.

Upvotes: 4

Related Questions