How to remove columns with all NAs

apply()
dplyr select()
Learn how to remove columns with all nas with this comprehensive R tutorial. Includes practical examples and code snippets.
Published

October 14, 2022

Introduction

When working with datasets, you’ll often encounter columns that contain only missing values (NAs). These empty columns provide no useful information and can slow down your analysis. Learning to identify and remove these columns efficiently will help you clean your data and improve performance.

Getting Started

library(tidyverse)
library(palmerpenguins)

Example 1: Basic Usage

The Problem

We need to identify and remove columns that contain only NA values from our dataset. This is a common data cleaning task that helps reduce dataset size and complexity.

Step 1: Create sample data with NA columns

Let’s start by creating a dataset with some columns that contain only missing values.

# Create sample data with NA columns
sample_data <- penguins |> 
  select(species, bill_length_mm, body_mass_g) |> 
  slice_head(n = 5) |> 
  mutate(empty_col1 = NA,
         empty_col2 = NA_character_)

We now have a dataset with two columns (empty_col1 and empty_col2) that contain only NA values.

Step 2: Check which columns are all NAs

Before removing columns, let’s identify which ones contain only missing values.

# Check which columns have all NAs
na_columns <- sample_data |> 
  summarise(across(everything(), ~all(is.na(.)))) |> 
  pivot_longer(everything(), 
               names_to = "column", 
               values_to = "all_na")
print(na_columns)

This shows us exactly which columns contain only NA values (TRUE means all NAs).

Step 3: Remove columns with all NAs

Now we’ll remove the columns that contain only missing values using select() and where().

# Remove columns with all NAs
cleaned_data <- sample_data |> 
  select(where(~!all(is.na(.))))

print(cleaned_data)

The cleaned dataset now only contains columns with actual data, removing the empty columns.

Example 2: Practical Application

The Problem

In real-world scenarios, you might receive datasets from external sources with many empty columns. Let’s simulate a more realistic example using the mtcars dataset and practice removing multiple NA columns efficiently.

Step 1: Create a realistic messy dataset

We’ll simulate a dataset that might come from a data export with several empty columns.

# Create messy dataset with multiple NA columns
messy_cars <- mtcars |> 
  slice_head(n = 8) |> 
  mutate(survey_q1 = NA,
         survey_q2 = NA,
         future_col = NA_real_,
         notes = NA_character_)

This simulates a common scenario where survey questions or planned columns end up empty in your dataset.

Step 2: Count NA columns before cleaning

Let’s see how many columns contain only NAs before we clean the data.

# Count columns with all NAs
na_count_before <- messy_cars |> 
  summarise(across(everything(), ~all(is.na(.)))) |> 
  pivot_longer(everything()) |> 
  filter(value == TRUE) |> 
  nrow()

cat("Columns with all NAs:", na_count_before)

This helps us understand the scope of our cleaning task.

Step 3: Clean and verify results

Now we’ll remove the empty columns and verify our cleaning was successful.

# Remove NA columns and verify
final_cars <- messy_cars |> 
  select(where(~!all(is.na(.)))) 

# Verify no NA-only columns remain
na_count_after <- final_cars |> 
  summarise(across(everything(), ~all(is.na(.)))) |> 
  pivot_longer(everything()) |> 
  filter(value == TRUE) |> 
  nrow()

cat("Remaining columns:", ncol(final_cars))

The cleaned dataset should have no columns with all NAs, and we can see the reduction in total columns.

Summary

  • Use select(where(~!all(is.na(.)))) to remove columns containing only NA values
  • The where() function applies a condition to select columns based on their content
  • Always verify your results by checking column counts before and after cleaning
  • This technique works with any dataset size and automatically adapts to your data structure
  • Consider checking for columns with mostly NAs (not just all NAs) for more thorough cleaning