1

Does anyone know how one would go about removing columns that consist of entirely either NAs or zeros?

For example, given a dataframe like this:

  rv    X1   X2    X3  X4 
1 M     0    110   0   1
2 J     70   200   0   3
3 J     NA   115   NA  4
4 M     65   110   0   9
5 J     70   200   NA  3
6 J     64   115   NA  8

I would want just rv, X1, X2 and X4 columns.

Amoroso
  • 945
  • 2
  • 10
  • 21
  • Hint: 1. Run a test on the columns, to see if ‘all’ entries are 0 or NA, 2. Remove these columns. Answers to both of these steps can be found on Stack. – Hector Haffenden May 11 '19 at 13:44

3 Answers3

7

With base R, we can do

Filter(function(x) !all(is.na(x)|x == 0), df)
#  rv X1  X2 X4
#1  M  0 110  1
#2  J 70 200  3
#3  J NA 115  4
#4  M 65 110  9
#5  J 70 200  3
#6  J 64 115  8

Or using colSums

df[!!colSums(replace(df, is.na(df), 0)!= 0)]

Or using sapply to create a logical vector

df[!sapply(df, function(x) all(is.na(x)|x == 0))]
akrun
  • 874,273
  • 37
  • 540
  • 662
5

Multiple ways to do this

df[colSums(is.na(df) | df == 0) != nrow(df)]

#  rv X1  X2 X4
#1  M  0 110  1
#2  J 70 200  3
#3  J NA 115  4
#4  M 65 110  9
#5  J 70 200  3
#6  J 64 115  8

Using apply

df[!apply(is.na(df) | df == 0, 2, all)]

Or using dplyr

library(dplyr)
df %>%  select_if(~!all(is.na(.) | . == 0))
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
0

A way to test one column is :

(sum(is.na(df$X1)) + sum(df$X1 == 0))  == nrow(df)

X1 is the column name.

Rémi Coulaud
  • 1,684
  • 1
  • 8
  • 19