Using map() to add columns to list elements

Hello coders ,

I have a list of tibbles. For each tibble I wish to add a new column with a character variable. The column/variable name should be the same across tibbles, but the value is different for each tibble.

To approach this I created a list of character names to read in. Using map2() I can add the columns OK, but I can't work out how to set the column name. The below gives a simple reprex of the problem.

This problem has been bugging me for a couple of days, I've tried various approaches with no luck so any help would be appreciated.
p.s. this is my first go at making a reprex so I hope it works! Thanks to Jenny Bryan for the reprex pkg.

library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union
library(lubridate)
#> 
#> Attaching package: 'lubridate'
#> The following objects are masked from 'package:base':
#> 
#>     date, intersect, setdiff, union
library(purrr)

# setting up a list of two tibbles
some_table <- tibble(
  admit_date = seq.Date(from = as_date("2020-02-01"), by = "day", length.out = 7),
  somedata = c(rnorm(7, 30))
  )

list_a <- list(some_table, some_table)

# attempt to add columns from a list
mynames <-  list("firstname", "secondname")

map2(list_a, mynames, mutate)
#> [[1]]
#> # A tibble: 7 x 3
#>   admit_date somedata `"firstname"`
#>   <date>        <dbl> <chr>        
#> 1 2020-02-01     28.4 firstname    
#> 2 2020-02-02     29.2 firstname    
#> 3 2020-02-03     29.6 firstname    
#> 4 2020-02-04     31.0 firstname    
#> 5 2020-02-05     30.2 firstname    
#> 6 2020-02-06     29.3 firstname    
#> 7 2020-02-07     29.8 firstname    
#> 
#> [[2]]
#> # A tibble: 7 x 3
#>   admit_date somedata `"secondname"`
#>   <date>        <dbl> <chr>         
#> 1 2020-02-01     28.4 secondname    
#> 2 2020-02-02     29.2 secondname    
#> 3 2020-02-03     29.6 secondname    
#> 4 2020-02-04     31.0 secondname    
#> 5 2020-02-05     30.2 secondname    
#> 6 2020-02-06     29.3 secondname    
#> 7 2020-02-07     29.8 secondname

map2(list_a, new = mynames, mutate)
#> Error in as_mapper(.f, ...): argument ".f" is missing, with no default

Created on 2022-06-28 by the reprex package (v0.3.0)

How about this?

map2(list_a, mynames, ~.x %>% mutate(new_col = .y))

#[[1]]
## A tibble: 7 × 3
#admit_date somedata new_col  
#<date>        <dbl> <chr>    
#1 2020-02-01     31.9 firstname
#2 2020-02-02     30.8 firstname
#3 2020-02-03     29.9 firstname
#4 2020-02-04     29.6 firstname
#5 2020-02-05     29.2 firstname
#6 2020-02-06     30.7 firstname
#7 2020-02-07     29.2 firstname
#
#[[2]]
## A tibble: 7 × 3
#admit_date somedata new_col   
#<date>        <dbl> <chr>     
#1 2020-02-01     31.9 secondname
#2 2020-02-02     30.8 secondname
#3 2020-02-03     29.9 secondname
#4 2020-02-04     29.6 secondname
#5 2020-02-05     29.2 secondname
#6 2020-02-06     30.7 secondname
#7 2020-02-07     29.2 secondname
1 Like

This seems like a good place to observe that piercing the veil of a list (or list column) to perform dplyr operations on the elements of the lists within is super frustrating for me. I know the family of map functions holds the key but the syntax is at the arcane end of the normally readable tidyverse. Has anyone seen a good tutorial on this subject? Thanks.

2 Likes

This one by Rebecca Barter helped me out a lot when getting started. {purrr} has given me confidence to work more with lists and encourages me to write functions for everything. Two thumbs up!

3 Likes

Thank you @williaml - that's a great solution.

From all of my attempts to use the ~.x and .y syntax I just didn't get the sequence correct and I've now learnt that it is possible to use a pipe inside the map function.

On my original post I forgot to tag @jennybryan - the reprex pkg really helped here.
I appreciate the pointer from @michaelbgarcia too.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.