dplyr::bind_rows() / dplyr::bind_cols()
bind_rows(..., .id = NULL) Returns:
data.frame · Updated March 13, 2026 · Tidyverse dplyr data-wrangling combine bind
bind_rows() and bind_cols() are dplyr functions for combining data frames. bind_rows() stacks data frames vertically (adding rows), while bind_cols() joins them horizontally (adding columns). These functions are faster than base R alternatives like rbind() and cbind().
Syntax
bind_rows(..., .id = NULL)
bind_cols(...)
Parameters
bind_rows()
| Parameter | Type | Default | Description |
|---|---|---|---|
... | data frames | — | Data frames to combine. Can also be a list of data frames. |
.id | string | NULL | Optional column name to identify the source of each row |
bind_cols()
| Parameter | Type | Default | Description |
|---|---|---|---|
... | data frames | — | Data frames to combine side by side. Must have same number of rows. |
Examples
Basic bind_rows
Stack two data frames:
library(dplyr)
df1 <- data.frame(name = c("Alice", "Bob"), score = c(85, 92))
df2 <- data.frame(name = c("Charlie", "Diana"), score = c(78, 88))
bind_rows(df1, df2)
# name score
# 1 Alice 85
# 2 Bob 92
# 3 Charlie 78
# 4 Diana 88
Using .id to track source
Identify which data frame each row came from:
df1 <- data.frame(name = "Alice", score = 85)
df2 <- data.frame(name = "Bob", score = 92)
bind_rows(a = df1, b = df2, .id = "source")
# source name score
# 1 a Alice 85
# 2 b Bob 92
Combining data with different columns
bind_rows() handles mismatched columns gracefully:
df1 <- data.frame(name = "Alice", score = 85)
df2 <- data.frame(name = "Bob", score = 92, grade = "A")
bind_rows(df1, df2)
# name score grade
# 1 Alice 85 NA
# 2 Bob 92 A
Basic bind_cols
Join columns side by side:
df1 <- data.frame(name = c("Alice", "Bob"))
df2 <- data.frame(score = c(85, 92), grade = c("B", "A"))
bind_cols(df1, df2)
# name score grade
# 1 Alice 85 B
# 2 Bob 92 A
Common Patterns
Efficiently combining many data frames from a list
# Combine all data frames in a list
df_list <- list(df1, df2, df3, df4)
combined <- bind_rows(df_list)
Appending new data
# Add new observations to existing dataset
existing_data <- data.frame(name = c("Alice", "Bob"), score = c(85, 92))
new_data <- data.frame(name = "Charlie", score = 78)
updated <- bind_rows(existing_data, new_data)
Combining summary statistics
df <- data.frame(
group = c("A", "A", "B", "B"),
value = c(10, 15, 20, 25)
)
summary_a <- df |> filter(group == "A") |> summarise(mean = mean(value))
summary_b <- df |> filter(group == "B") |> summarise(mean = mean(value))
bind_rows(a = summary_a, b = summary_b, .id = "group")
# group mean
# 1 a 12.5
# 2 b 22.5