This is an efficient implementation of the common pattern of do.call(rbind, dfs) or do.call(cbind, dfs) for binding many data frames into one.

bind_rows(..., .id = NULL)

bind_cols(...)

Arguments

...

Data frames to combine.

Each argument can either be a data frame, a list that could be a data frame, or a list of data frames.

When row-binding, columns are matched by name, and any missing columns will be filled with NA.

When column-binding, rows are matched by position, so all data frames must have the same number of rows. To match by value, not position, see join.

.id

Data frame identifier.

When .id is supplied, a new column of identifiers is created to link each row to its original data frame. The labels are taken from the named arguments to bind_rows(). When a list of data frames is supplied, the labels are taken from the names of the list. If no names are found a numeric sequence is used instead.

Value

bind_rows() and bind_cols() return the same type as the first input, either a data frame, tbl_df, or grouped_df.

Details

The output of bind_rows() will contain a column if that column appears in any of the inputs.

Deprecated functions

rbind_list() and rbind_all() have been deprecated. Instead use bind_rows().

Examples

one <- mtcars[1:4, ] two <- mtcars[11:14, ] # You can supply data frames as arguments: bind_rows(one, two)
#> mpg cyl disp hp drat wt qsec vs am gear carb #> 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 #> 2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 #> 3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 #> 4 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 #> 5 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4 #> 6 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3 #> 7 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3 #> 8 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
# The contents of lists are spliced automatically: bind_rows(list(one, two))
#> mpg cyl disp hp drat wt qsec vs am gear carb #> 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 #> 2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 #> 3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 #> 4 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 #> 5 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4 #> 6 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3 #> 7 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3 #> 8 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
bind_rows(split(mtcars, mtcars$cyl))
#> mpg cyl disp hp drat wt qsec vs am gear carb #> 1 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 #> 2 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2 #> 3 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2 #> 4 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1 #> 5 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2 #> 6 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1 #> 7 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1 #> 8 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1 #> 9 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2 #> 10 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2 #> 11 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2 #> 12 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 #> 13 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 #> 14 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 #> 15 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1 #> 16 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4 #> 17 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4 #> 18 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5 6 #> 19 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2 #> 20 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4 #> 21 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3 #> 22 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3 #> 23 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3 #> 24 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4 #> 25 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4 #> 26 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4 #> 27 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2 #> 28 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2 #> 29 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4 #> 30 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2 #> 31 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4 #> 32 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8
bind_rows(list(one, two), list(two, one))
#> mpg cyl disp hp drat wt qsec vs am gear carb #> 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 #> 2 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 #> 3 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 #> 4 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 #> 5 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4 #> 6 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3 #> 7 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3 #> 8 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3 #> 9 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4 #> 10 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3 #> 11 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3 #> 12 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3 #> 13 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 #> 14 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 #> 15 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 #> 16 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
# In addition to data frames, you can supply vectors. In the rows # direction, the vectors represent rows and should have inner # names: bind_rows( c(a = 1, b = 2), c(a = 3, b = 4) )
#> # A tibble: 2 x 2 #> a b #> <dbl> <dbl> #> 1 1 2 #> 2 3 4
# You can mix vectors and data frames: bind_rows( c(a = 1, b = 2), tibble(a = 3:4, b = 5:6), c(a = 7, b = 8) )
#> # A tibble: 4 x 2 #> a b #> <dbl> <dbl> #> 1 1 2 #> 2 3 5 #> 3 4 6 #> 4 7 8
# Note that for historical reasons, lists containing vectors are # always treated as data frames. Thus their vectors are treated as # columns rather than rows, and their inner names are ignored: ll <- list( a = c(A = 1, B = 2), b = c(A = 3, B = 4) ) bind_rows(ll)
#> # A tibble: 2 x 2 #> a b #> <dbl> <dbl> #> 1 1 3 #> 2 2 4
# You can circumvent that behaviour with explicit splicing: bind_rows(!!!ll)
#> # A tibble: 2 x 2 #> A B #> <dbl> <dbl> #> 1 1 2 #> 2 3 4
# When you supply a column name with the `.id` argument, a new # column is created to link each row to its original data frame bind_rows(list(one, two), .id = "id")
#> id mpg cyl disp hp drat wt qsec vs am gear carb #> 1 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 #> 2 1 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 #> 3 1 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 #> 4 1 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 #> 5 2 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4 #> 6 2 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3 #> 7 2 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3 #> 8 2 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
bind_rows(list(a = one, b = two), .id = "id")
#> id mpg cyl disp hp drat wt qsec vs am gear carb #> 1 a 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 #> 2 a 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 #> 3 a 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 #> 4 a 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 #> 5 b 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4 #> 6 b 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3 #> 7 b 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3 #> 8 b 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
bind_rows("group 1" = one, "group 2" = two, .id = "groups")
#> groups mpg cyl disp hp drat wt qsec vs am gear carb #> 1 group 1 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4 #> 2 group 1 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4 #> 3 group 1 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1 #> 4 group 1 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1 #> 5 group 2 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4 #> 6 group 2 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3 #> 7 group 2 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3 #> 8 group 2 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
# Columns don't need to match when row-binding bind_rows(data.frame(x = 1:3), data.frame(y = 1:4))
#> x y #> 1 1 NA #> 2 2 NA #> 3 3 NA #> 4 NA 1 #> 5 NA 2 #> 6 NA 3 #> 7 NA 4
if (FALSE) { # Rows do need to match when column-binding bind_cols(data.frame(x = 1), data.frame(y = 1:2)) } bind_cols(one, two)
#> mpg cyl disp hp drat wt qsec vs am gear carb mpg1 cyl1 disp1 hp1 drat1 #> 1 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 17.8 6 167.6 123 3.92 #> 2 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 16.4 8 275.8 180 3.07 #> 3 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 17.3 8 275.8 180 3.07 #> 4 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 15.2 8 275.8 180 3.07 #> wt1 qsec1 vs1 am1 gear1 carb1 #> 1 3.44 18.9 1 0 4 4 #> 2 4.07 17.4 0 0 3 3 #> 3 3.73 17.6 0 0 3 3 #> 4 3.78 18.0 0 0 3 3
bind_cols(list(one, two))
#> mpg cyl disp hp drat wt qsec vs am gear carb mpg1 cyl1 disp1 hp1 drat1 #> 1 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4 17.8 6 167.6 123 3.92 #> 2 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4 16.4 8 275.8 180 3.07 #> 3 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1 17.3 8 275.8 180 3.07 #> 4 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1 15.2 8 275.8 180 3.07 #> wt1 qsec1 vs1 am1 gear1 carb1 #> 1 3.44 18.9 1 0 4 4 #> 2 4.07 17.4 0 0 3 3 #> 3 3.73 17.6 0 0 3 3 #> 4 3.78 18.0 0 0 3 3