Panos Kalatzantonakis
Panos Kalatzantonakis

Reputation: 12673

Remove rows with a factor if zero value appears on another column

My data frame looks like this:

structure(list(intype = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 
3L, 3L), .Label = c("A30", "A31", "E45"), class = "factor"), 
    inerror = c(0.54, 0.14, 0.94, 0, 2.11, 0, 1.42, 3.19, 0), 
    inmethod = structure(c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L
    ), .Label = c("A", "B", "C"), class = "factor")), row.names = c(NA, 
-9L), class = "data.frame")

+--------+---------+----------+
| intype | inerror | inmethod |
+--------+---------+----------+
| A30    |    0.54 | A        |
| A30    |    0.14 | B        |
| A30    |    0.94 | C        |
| A31    |    9.20 | A        |
| A31    |    2.11 | B        |
| A31    |   -1.55 | C        |
| E45    |    1.42 | A        |
| E45    |    3.19 | B        |
| E45    |    0.00 | C        |
+--------+---------+----------+

Intype is a factor. I would like to remove all rows from a factor if inerror<=0.

So the resulting data frame would be:

+--------+---------+----------+
| intype | inerror | inmethod |
+--------+---------+----------+
| A30    |    0.54 | A        |
| A30    |    0.14 | B        |
| A30    |    0.94 | C        |
+--------+---------+----------+

Upvotes: 3

Views: 47

Answers (2)

jay.sf
jay.sf

Reputation: 72613

This is also working.

with(dat, dat[- which(intype %in% intype[inerror <= 0]), ])

or, shorter (thx @Ronak Shah)

with(dat, dat[!intype %in% intype[inerror <= 0], ]) 

#   intype inerror inmethod
# 1    A30    0.54        A
# 2    A30    0.14        B
# 3    A30    0.94        C

To also get rid of the obsolete factor levels use droplevels onto your new data frame.

dat$intype <- droplevels(dat$intype)

Upvotes: 2

Ronak Shah
Ronak Shah

Reputation: 388817

Multiple ways to do this

library(dplyr)
df %>%
  group_by(intype) %>%
  filter(all(inerror > 0))

# intype inerror inmethod
#  <fct>    <dbl> <fct>   
#1 A30       0.54 A       
#2 A30       0.14 B       
#3 A30       0.94 C    

OR it's inverted version

df %>%
  group_by(intype) %>%
  filter(!any(inerror <= 0))

With base R ave

subset(df, ave(inerror > 0, intype, FUN = all))   
#and
subset(df, !ave(inerror <= 0, intype, FUN = any))      

Upvotes: 2

Related Questions