Dongchul Park
Dongchul Park

Reputation: 175

How to remove an entire row if it contains zero in a specific range of columns in R?

If my data frame is:

        A1  A2  B1  B2  C1  C2
row1    67  8   0   99  67  84 
row2    8   22  25  5   72  0 
row3    0   83  35  68  17  13 
row4    69  37  52  93  67  78 
row5    68  64  68  90  61  38 
row6    16  30  2   19  40  1 
row7    49  86  87  87  62  64 
row8    28  97  42  0   54  83 
row9    43  68  26  8   64  35 

I want to remove rows that contain zero between column B1 and B2. A1 and C2 have zero, but I want to keep them. So my final output should be:

        A1  A2  B1  B2  C1  C2
row2    8   22  25  5   72  0 
row3    0   83  35  68  17  13 
row4    69  37  52  93  67  78 
row5    68  64  68  90  61  38 
row6    16  30  2   19  40  1 
row7    49  86  87  87  62  64 
row9    43  68  26  8   64  35 

Upvotes: 0

Views: 86

Answers (3)

akrun
akrun

Reputation: 887951

In base R, we can use lapply with Reduce

cols <- c('B1', 'B2')
df[!Reduce(`!`, lapply(df[cols], `==`, 0)),]
#      A1 A2 B1 B2 C1 C2
#row2  8 22 25  5 72  0
#row3  0 83 35 68 17 13
#row4 69 37 52 93 67 78
#row5 68 64 68 90 61 38
#row6 16 30  2 19 40  1
#row7 49 86 87 87 62 64
#row9 43 68 26  8 64 35

Or use

df[Reduce(`&`, lapply(df[cols], `!=`, 0)),]

data

df <- structure(list(A1 = c(67L, 8L, 0L, 69L, 68L, 16L, 49L, 28L, 43L
), A2 = c(8L, 22L, 83L, 37L, 64L, 30L, 86L, 97L, 68L), B1 = c(0L, 
25L, 35L, 52L, 68L, 2L, 87L, 42L, 26L), B2 = c(99L, 5L, 68L, 
93L, 90L, 19L, 87L, 0L, 8L), C1 = c(67L, 72L, 17L, 67L, 61L, 
40L, 62L, 54L, 64L), C2 = c(84L, 0L, 13L, 78L, 38L, 1L, 64L, 
83L, 35L)), class = "data.frame", row.names = c("row1", "row2", 
"row3", "row4", "row5", "row6", "row7", "row8", "row9"))

Upvotes: 0

Ronak Shah
Ronak Shah

Reputation: 389325

You can use rowSums in base R :

cols <- c('B1', 'B2')
df[rowSums(df[cols] == 0) == 0, ]

#     A1 A2 B1 B2 C1 C2
#row2  8 22 25  5 72  0
#row3  0 83 35 68 17 13
#row4 69 37 52 93 67 78
#row5 68 64 68 90 61 38
#row6 16 30  2 19 40  1
#row7 49 86 87 87 62 64
#row9 43 68 26  8 64 35

Or using dplyr

library(dplyr)
df %>% filter_at(vars(B1:B2), all_vars(. != 0))

Upvotes: 3

Bruno
Bruno

Reputation: 4150

Simple dplyr code

library(tidyverse)

data_example <- data.table::fread("row        A1  A2  B1  B2  C1  C2
row1    67  8   0   99  67  84 
row2    8   22  25  5   72  0 
row3    0   83  35  68  17  13 
row4    69  37  52  93  67  78 
row5    68  64  68  90  61  38 
row6    16  30  2   19  40  1 
row7    49  86  87  87  62  64 
row8    28  97  42  0   54  83 
row9    43  68  26  8   64  35 ")

data_example %>% 
  filter(across(c(B1:B2),.fns = ~ .x != 0))
#>     row A1 A2 B1 B2 C1 C2
#> 1: row2  8 22 25  5 72  0
#> 2: row3  0 83 35 68 17 13
#> 3: row4 69 37 52 93 67 78
#> 4: row5 68 64 68 90 61 38
#> 5: row6 16 30  2 19 40  1
#> 6: row7 49 86 87 87 62 64
#> 7: row9 43 68 26  8 64 35

Created on 2020-06-06 by the reprex package (v0.3.0)

Upvotes: 0

Related Questions