How to use pivot_longer() in R

tidyr
pivot_longer()
Learn how to use pivot_longer() in R with practical examples. Step-by-step guide with code you can copy and run immediately.
Published

February 21, 2026

Introduction

The pivot_longer() function from the tidyr package transforms data from wide format to long format by gathering multiple columns into key-value pairs. This function takes columns that represent different variables or measurements and stacks them into fewer columns, creating a “taller” dataset with more rows and fewer columns. You would use pivot_longer() when you need to reshape data for visualization with ggplot2, perform grouped analyses, or prepare data that follows tidy data principles where each variable forms a column and each observation forms a row.

Getting Started

library(tidyverse)
library(palmerpenguins)

Example 1: Basic Usage

Let’s start with a simple example using the penguins dataset. Suppose we want to gather the three body measurement columns (bill_length_mm, bill_depth_mm, flipper_length_mm) into a long format:

# Basic pivot_longer example
penguins_long <- penguins |>
  select(species, island, bill_length_mm, bill_depth_mm, flipper_length_mm) |>
  pivot_longer(
    cols = c(bill_length_mm, bill_depth_mm, flipper_length_mm),
    names_to = "measurement_type",
    values_to = "measurement_value"
  )

In this example, we specify which columns to pivot using the cols argument, define the new column name for the former column names with names_to, and specify where the values should go with values_to. This transforms our wide data into a long format where each row represents one measurement for one penguin.

We can also use helper functions to select columns more efficiently:

# Using helper functions to select columns
penguins_long <- penguins |>
  pivot_longer(
    cols = ends_with("_mm"),
    names_to = "measurement",
    values_to = "value"
  )

Example 2: Practical Application

Here’s a more practical application where we prepare penguin data for visualization and analysis. We’ll reshape the data and then create a grouped summary:

# Reshape and analyze penguin measurements by species
penguin_analysis <- penguins |>
  select(species, sex, bill_length_mm, bill_depth_mm, flipper_length_mm) |>
  pivot_longer(
    cols = ends_with("_mm"),
    names_to = "measurement_type",
    values_to = "measurement_mm"
  ) |>
  filter(!is.na(measurement_mm), !is.na(sex)) |>
  group_by(species, sex, measurement_type) |>
  summarise(
    mean_measurement = mean(measurement_mm),
    sd_measurement = sd(measurement_mm),
    n = n(),
    .groups = "drop"
  )

This practical example demonstrates how pivot_longer() integrates seamlessly with other tidyverse functions. After reshaping the data, we can easily filter out missing values, group by multiple variables, and calculate summary statistics for each combination of species, sex, and measurement type.

We can also use pivot_longer() with name pattern matching for more complex column structures:

# Advanced usage with name separation
penguins |>
  select(species, bill_length_mm, bill_depth_mm) |>
  pivot_longer(
    cols = contains("bill"),
    names_to = c("body_part", "dimension", "unit"),
    names_sep = "_",
    values_to = "measurement"
  )

This approach automatically separates the column names into multiple components, which is useful when your column names contain multiple pieces of information separated by underscores or other delimiters.

Summary

pivot_longer() is essential for converting wide data to long format, making it easier to work with tidyverse functions and create effective visualizations where you need variables stacked in rows rather than spread across columns.

• The function requires three main arguments: cols (which columns to pivot), names_to (name for the new column containing old column names), and values_to (name for the new column containing the values).

• Combined with other tidyverse functions like filter(), group_by(), and summarise(), pivot_longer() becomes a powerful tool for data preprocessing and analysis workflows.