tidyr::fill

fill(data, ..., .by = NULL, .direction = c("down", "up", "downup", "updown"))
Returns: data.frame · Updated April 4, 2026 · Tidyverse
tidyr tidyverse missing-values data-wrangling

fill() replaces NA values in selected columns with the nearest non-NA value in a chosen direction. It’s the standard fix for data in “stacked” format where a value appears once and is left blank until it changes.

Signature

fill(data, ..., .by = NULL, .direction = c("down", "up", "downup", "updown"))

Parameters

ParameterTypeDescription
datadata.frameInput data frame or tibble
...tidy-selectColumns to fill. Accepts tidyr::ends_with(), starts_with(), everything(), etc.
.bytidy-exprGroup by columns — fill operates within each group, not crossing boundaries
.directionstringDirection: "down" (default), "up", "downup", or "updown"

Direction

The .direction argument controls which non-NA value fills the gap:

# Default: propagate the previous value downward (LOCF — last observation carried forward)
df <- tibble(
  quarter = c("Q1", "Q2", "Q3", "Q4", "Q1", "Q2"),
  year = c("2000", NA, NA, NA, "2001", NA),
  sales = c(66013, 69182, 53175, 21001, 46036, 58842)
)

df |> fill(year)
# # A tibble: 6 × 3
#   quarter year  sales
#   <chr>   <chr> <dbl>
# 1 Q1      2000  66013
# 2 Q2      2000  69182
# 3 Q3      2000  53175
# 4 Q4      2000  21001
# 5 Q1      2001  46036
# 6 Q2      2001  58842
# Fill upward — propagate the next value upward (NOCB — next observation carried backward)
df |> fill(year, .direction = "up")
# Fill down first, then fill remaining NAs upward
df |> fill(year, .direction = "downup")
# Fill up first, then fill remaining NAs downward
df |> fill(year, .direction = "updown")

Filling by Group

The .by argument fills within groups without permanently grouping the data. This is cleaner than using dplyr::group_by() because you don’t need to ungroup afterward:

library(tidyr)
library(dplyr)

df <- tibble(
  group = c("A", "A", "A", "B", "B", "B"),
  x = c(1, NA, NA, 2, NA, NA),
  y = c("p", NA, "r", "q", NA, "s")
)

df
# # A tibble: 6 × 3
#   group     x y
#   <chr> <dbl> <chr>
# 1 A         1 p
# 2 A        NA NA
# 3 A        NA r
# 4 B         2 q
# 5 B        NA NA
# 6 B        NA s

df |> fill(x, y, .by = group)
# # A tibble: 6 × 3
#   group     x y
#   <chr> <dbl> <chr>
# 1 A         1 p
# 2 A         1 p
# 3 A         1 r
# 4 B         2 q
# 5 B         2 q
# 6 B         2 s

Without .by, the fill would cross group boundaries.

Filling All Columns

Use everything() to fill every column with NAs at once:

df <- tibble(
  x = c(1, NA, 3),
  y = c("a", NA, "c"),
  z = c(TRUE, NA, FALSE)
)

df |> fill(everything(), .direction = "down")
# # A tibble: 3 × 3
#   x     y     z
#   <dbl> <chr> <lgl>
# 1     1 a     TRUE
# 2     1 a     TRUE
# 3     3 c     FALSE

Chaining Directions for Complex Patterns

If you need trailing NAs filled too, chain fill() calls:

df <- tibble(
  id = c(1, 1, 1, 1),
  value = c("a", NA, NA, NA)
)

# Chain down then up to fill both leading and trailing NAs
df |>
  fill(value, .direction = "down") |>
  fill(value, .direction = "up")
# # A tibble: 4 × 2
#   id    value
#   <dbl> <chr>
# 1     1 a
# 2     1 a
# 3     1 a
# 4     1 a       <- trailing NA also filled

This is equivalent to .direction = "downup".

See Also