Search code examples
rlistdataframedata-manipulationpurrr

Mutate new column in a listed dataframes from a vector with Tidyverse


Consider this vector

names <- c("Jon", "Nancy")

And, a list of dataframes with the same length

listed_dfs <- list(tibble(X = sample(1:5),
                          Y = sample(1:5)),
                   tibble(X = sample(11:15),
                          Y = sample(11:15)))

I would like to add a new column in each of them with a name according to their position in the vector. Such that the desired output would be:

[[1]]
# A tibble: 5 x 3
      X     Y name 
  <int> <int> <chr>
1     4     1 Jon  
2     2     5 Jon  
3     5     2 Jon  
4     3     4 Jon  
5     1     3 Jon  

[[2]]
# A tibble: 5 x 3
      X     Y name 
  <int> <int> <chr>
1    14    13 Nancy
2    11    14 Nancy
3    12    12 Nancy
4    15    11 Nancy
5    13    15 Nancy

I have tried imap and map without any results.

EDIT:

Okay, I managed to find a solution

imap(listed_dfs, ~ bind_cols(.x, name = names[.y])) 

But I'm still open to other suggestions, if there are cleaner ways


Solution

  • You could use map2 from purrr:

    map2(listed_dfs, names, ~ bind_cols(name = .y, .x))
    
    [[1]]
    # A tibble: 5 × 3
      name      X     Y
      <chr> <int> <int>
    1 Jon       3     2
    2 Jon       1     3
    3 Jon       4     1
    4 Jon       5     4
    5 Jon       2     5
    
    [[2]]
    # A tibble: 5 × 3
      name      X     Y
      <chr> <int> <int>
    1 Nancy    15    12
    2 Nancy    13    14
    3 Nancy    11    11
    4 Nancy    14    13
    5 Nancy    12    15
    

    If your final goal is to bind them, you could directly use bind_rows(..., .id = 'name') from dplyr:

    bind_rows(set_names(listed_dfs, names), .id = 'name')
    
    # A tibble: 10 × 3
       name      X     Y
       <chr> <int> <int>
     1 Jon       3     2
     2 Jon       1     3
     3 Jon       4     1
     4 Jon       5     4
     5 Jon       2     5
     6 Nancy    15    12
     7 Nancy    13    14
     8 Nancy    11    11
     9 Nancy    14    13
    10 Nancy    12    15