r - Remove rows with NA in a group, given the group contains at-least one non NA value -


sample data

df = structure(list(class = structure(c(4l, 1l, 1l, 3l, 2l), .label = c("apple",  "berry", "grape", "orange"), class = "factor"), value = c(na,  na, 1, 1, na)), .names = c("class", "value"), row.names = c(na,  -5l), class = "data.frame") 

looks like

   class value 1 orange    na 2  apple    na 3  apple     1 4  grape     1 5  berry    na 

how remove row na in group if group has non na value

desired ouput

   class value 1 orange    na 2  apple     1 3  grape     1 4  berry    na 

this doable in 3 steps using subset , merge. interested in data.table approach

we use data.table. convert 'data.frame' 'data.table' (setdt(df)). grouped 'class', check if/else condition occurrence of 'na' elements in 'value' , subset .sd

library(data.table) setdt(df)[, if(any(!is.na(value))) .sd[!is.na(value)] else .sd , = class] #    class value #1: orange    na #2:  apple     1 #3:  grape     1 #4:  berry    na 

or can change condition any all modifying condition

setdt(df)[, if(all(is.na(value))) .sd else .sd[!is.na(value)], = class] #    class value #1: orange    na #2:  apple     1 #3:  grape     1 #4:  berry    na 

or row index (.i) , subset dataset.

indx <- setdt(df)[, if(any(!is.na(value))) .i[!is.na(value)] else .i, class]$v1 df[indx] 

Comments