EN VI

Combining (binding columns of) tibbles with identical names by name in a named list in R?

2024-03-14 21:00:08
How to Combining (binding columns of) tibbles with identical names by name in a named list in R?

I have a named list containing tibbles as elements. I would like to bind_cols of those tibbles whose names are the same within that list. For example:

list(A = tibble(alpha = 1:5, beta = 2:6), B = tibble(delta = 1:8), A = tibble(gamma = 3:7))

> list(A = tibble(alpha = 1:5, beta = 2:6), B = tibble(delta = 1:8), A = tibble(gamma = 3:7))
$A
# A tibble: 5 × 2
  alpha  beta
  <int> <int>
1     1     2
2     2     3
3     3     4
4     4     5
5     5     6

$B
# A tibble: 8 × 1
  delta
  <int>
1     1
2     2
3     3
4     4
5     5
6     6
7     7
8     8

$A
# A tibble: 5 × 1
  gamma
  <int>
1     3
2     4
3     5
4     6
5     7


I would like to transform this into, i.e. this is my desired output:

list(A = tibble(alpha = 1:5, beta = 2:6, gamma = 3:7), B = tibble(delta = 1:8))

$A
# A tibble: 5 × 3
  alpha  beta gamma
  <int> <int> <int>
1     1     2     3
2     2     3     4
3     3     4     5
4     4     5     6
5     5     6     7

$B
# A tibble: 8 × 1
  delta
  <int>
1     1
2     2
3     3
4     4
5     5
6     6
7     7
8     8

How this could be achieved?

Solution:

We can split on the names of L, then use bind_cols:

library(dplyr)
split(L, names(L)) |>
  lapply(bind_cols)
# $A
# # A tibble: 5 × 3
#   alpha  beta gamma
#   <int> <int> <int>
# 1     1     2     3
# 2     2     3     4
# 3     3     4     5
# 4     4     5     6
# 5     5     6     7
# $B
# # A tibble: 8 × 1
#   delta
#   <int>
# 1     1
# 2     2
# 3     3
# 4     4
# 5     5
# 6     6
# 7     7
# 8     8

Note: in this case, bind_cols works well because they have the same number of rows. If the row-counts are different or if there is another condition on which they should be combined (aka "merged" or "joined"), then you will need another function such as *_join or merge.

Also, I inferred dplyr from your use of tibble(..), though this can be done with base R as well:

split(L, names(L)) |>
  lapply(\(x) do.call(cbind, unname(x)))
Answer

Login


Forgot Your Password?

Create Account


Lost your password? Please enter your email address. You will receive a link to create a new password.

Reset Password

Back to login