Skip to main content
v2026.11,858 entries · CC-BY 4.0

cbind in R: Combine Columns in Vectors, Matrices and Data Frames

cbind in R combines columns by position and returns a matrix or data frame. Steps, naming, recycling warnings, and when bind_cols or a join is safer.

Written and maintained by CASRAI Editorial Board

Last updated

cbind() in R joins vectors, matrices or data frames side by side, as columns. What it returns depends on what you give it: if at least one argument is a data frame you get a data frame, otherwise you get a matrix. Whichever you use, it matches rows by position, never by a key, so the result is only correct if your inputs are already in the same row order. This guide covers the function (searched as cbind r or r cbind), the dispatch rule, recycling and naming, and when dplyr::bind_cols() or a join is the better choice.

What cbind is used for in research

cbind() takes a sequence of vector, matrix or data-frame arguments and combines them by columns. In research data work the usual jobs are putting several measured variables into one matrix for a matrix-based function, and attaching a newly computed column to an analysis data frame. The R manual for the base package describes rbind() as the same operation by rows, and the two are documented on one page.

The one thing to settle before you use it is whether row n of every input describes the same case. cbind() does not check. If your inputs carry an identifier column, a join is safer than binding; see the table of alternatives below.

Install or access

cbind() is part of base R, so there is no package to install or load. Download R from the Comprehensive R Archive Network (CRAN). For Windows, the CRAN page lists R 4.6.1 as the current release, as a 64-bit installer that requires the Universal C Runtime (UCRT), which is included in Windows 10 and Windows Server 2016 and later. Installers for other systems are linked from the CRAN home page; the Windows downloads are at cran.r-project.org/bin/windows/base.

The usage is cbind(..., deparse.level = 1). The ... are the objects to combine; deparse.level controls how column names are built (explained under step 4).

Step-by-step: combine columns with cbind in R

1. Bind vectors into a matrix

  1. Create the vectors: x <- 1:3 and y <- c(10, 20, 30).
  2. Run cbind(x, y).
     x  y
[1,] 1 10
[2,] 2 20
[3,] 3 30

When every argument is a vector, the result has as many rows as the longest vector. The result of the default method is a matrix. Because the arguments were plain variable names, the columns are labelled x and y.

2. Add a column to a data frame

  1. Create or load the data frame: df <- data.frame(id = 1:3, score = c(82, 90, 77)).
  2. Bind the new column, naming it in the call: cbind(df, group = c("a", "b", "a")).
  id score group
1  1    82     a
2  2    90     b
3  3    77     a

The R manual states that the data frame method is used if at least one argument is a data frame and the rest are vectors or matrices. That is why this call returns a data frame rather than a matrix. Assign the result (df <- cbind(df, ...)) to keep it; cbind() does not change df in place.

3. Place two data frames side by side

  1. Make sure both frames list the same cases in the same order. Sort both by the same identifier first if you are unsure.
  2. Run cbind(df1, df2).

Columns are appended in the order given. Nothing is matched by value, so two frames with the same rows in different orders produce a table whose rows quietly describe different cases.

4. Control the column names

Names come from the following places, in order of what the manual describes:

  • the column names of any matrix-like argument;
  • otherwise the argument names you supply, as in cbind(first = 1:2, second = 3:4);
  • otherwise, if deparse.level is greater than 0, the deparsed expression.

deparse.level is an integer: 0 builds no labels, the default 1 typically builds labels for symbol arguments, and 2 always builds them. To be certain of your headers, name the arguments explicitly rather than relying on deparsing.

5. Recycling a single value

Shorter vectors are recycled to the longest length. The manual’s own example is cbind(1, 1:7), where the single 1 is repeated to fill seven rows. This is a convenient way to add a constant column to a matrix.

Output and how to read it

  • Matrix output. Row labels print as [1,], [2,] and so on, and column labels are the names from step 4. A matrix holds one data type, so binding a character vector with numeric vectors gives a character matrix, and the numbers are no longer numbers. Use a data frame when columns have different types.
  • Data frame output. Row labels are the row names (1, 2, 3 by default) and each column keeps its own type.
  • Check the class. Run class(result) after binding. It tells you which method ran, which matters before you pass the object to anything that expects one form or the other.
  • Empty input. With no inputs, or with every input NULL, cbind() returns NULL.

Troubleshooting

A warning about recycling

If vectors of different lengths are bound and the longest is not a whole multiple of the shorter, R recycles with a warning “if they are recycled only fractionally”, in the manual’s words. A separate warning appears when a vector is longer than the number of rows of a matrix argument, so only part of it is used. The manual’s example is cbind(1:7, diag(3)), annotated “vector is subset”. Treat either warning as a sign your inputs are misaligned, not as noise.

Columns are mismatched but nothing failed

Because binding is positional, a wrong row order produces no error at all. Compare an identifier column from each input before you bind, or combine by key with a join instead.

Binding rows rather than columns

For stacking cases, use rbind(). Its data frame method matches columns by name rather than by position, which is the reverse of how cbind() matches rows. The R manual lists the extra arguments of that method (make.row.names, stringsAsFactors, factor.exclude).

A tidyverse bind_cols error

If you use dplyr::bind_cols() and the inputs have different sizes, it stops with an error instead of recycling. The dplyr reference shows that bind_cols(tibble(x = 1:3), tibble(y = 1:2)) fails with “Can’t recycle ..1 (size 3) to match ..2 (size 2).” Fix the lengths, or use a join.

Free alternatives and related functions

Function How it combines What the documentation says
cbind() (base R) By column position Returns a matrix by default, or a data frame if any argument is a data frame. Shorter vectors are recycled.
rbind() (base R) By row; data frame method matches columns by name Documented on the same page as cbind().
dplyr::bind_cols() By column position Inputs are recycled to the same length, then matched by position. Returns a data frame of the same type as the first input. A .name_repair argument controls duplicate names.
A join (dplyr) By matching key values The bind_cols documentation advises that, where possible, you prefer a join to combine multiple data frames.

The join advice is the practical rule: bind by position only when the inputs were built together and cannot have drifted apart. If they came from different files or have an identifier, join them. For the statistical side of the same R workflow, see the guides on the t-test in R, standard deviation in R and collapsing data in R, and the comparison R vs Stata for statistical analysis. If you report your code, see how to cite software, code and R packages.

FAQ

What does cbind do in R?

It combines vector, matrix or data-frame arguments by columns. With only vectors and matrices it returns a matrix; if any argument is a data frame, it uses the data frame method and returns a data frame.

Is cbind r the same as r cbind?

Yes. Both searches refer to the base R function cbind() documented above. It needs no package.

Does cbind match rows by a key?

No. It matches rows by position. To match on a key, use a join, which the dplyr documentation recommends over positional binding where possible.

What is the difference between cbind and bind_cols?

Both bind by position. bind_cols() comes from dplyr, always returns a data frame of the same type as its first input, and raises an error when sizes cannot be recycled to match. cbind() is in base R and returns a matrix unless a data frame is involved.

Sources

Follow CASRAI

Research-administration guidance, standards updates and independent tool reviews.

Ask CASRAI · free to try

Ask about cbind in R: Combine Columns in Vectors, Matrices and Data Frames

Ask your first 2 questions free below. Subscribers get 150 a day for $29 a month.

An AI assistant specialized in research administration. It cites the sources behind every answer, labels web answers and says when it can't answer.

Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.

Works on this site and inside Claude, Cursor and the AI tools you already use.

Everything CASRAI publishes — this page, the dictionary, the guides and the news — stays free to read, with no account and no card.

Referenced across the research world

University of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logoUniversity of Cambridge logoColumbia University logoCrossref logoUniversity of Edinburgh logoHarvard University logoUniversity of Oxford logoPrinceton University logoStanford School of Medicine logoUniversity College London logoORCID logo
  • University of Cambridge logo
  • Columbia University logo
  • Crossref logo
  • University of Edinburgh logo
  • Harvard University logo
  • University of Oxford logo
  • Princeton University logo
  • Stanford School of Medicine logo
  • University College London logo
  • ORCID logo

View CASRAI adoption →

Ask CASRAI · Regulatory Radar

Research-admin question? Get an answer that links its sources.

An AI assistant specialized in research administration. Every answer links its sources to check before you act. 2 questions free, no account. $29/month after.

  • Answers draw on CASRAI's guides and dictionary plus the federal and funder documents we index: Federal Register, Grants.gov, Regulations.gov and UKRI.
  • Every answer numbers its sources and links each one, so you can check the source yourself.