How can I use map2 and rename_with to modify nested column names?

Viewed 384

I am trying to rename a set of columns in nested dataframes based on the values of an unnested column. Here is a simplified example of the dataset:

library(tidyverse)

df_pre <- tribble(
  ~year, ~data,
  1970, tibble(GEOID_1970 = 1, TOTPOP_1970 = 2),
  1980, tibble(GEOID_1980 = 3, TOTPOP_1980 = 4)
)  

Using purrr, I would like to rename the nested columns so that I have the following:

df_post <- tribble(
  ~year, ~data,
  1970, tibble(GEOID = 1, TOTPOP = 2),
  1980, tibble(GEOID = 3, TOTPOP = 4)
)  

I've tried a variety of approaches, all of which throw some kind of error, e.g.:

library(purrr)
df_post <- df_pre %>% map2(.x = data, .y = year, 
                           ~ rename_with(str_replace,  
                                        pattern = paste0("_", .y), 
                                        replacement = ""))
#> Error: Can't convert a `tbl_df/tbl/data.frame` object to function

How can I use map2 plus rename_with to modify the nested column names? In addition to solving this particular problem, I am also trying to gain more insight about how to pass arguments such as year to map2 anonymous functions.

1 Answers

We loop over the list column 'data' with map and use rename_with selecting all the columns (everything()) while removing the suffix part from the column name with str_remove)

library(dplyr)
library(purrr)
library(stringr)
df_new <- df_pre  %>%
    mutate(data = map(data, ~ .x %>%
          rename_with(~ str_remove(., "_\\d+$"), everything())))

-checking

identical(df_new, df_post)
#[1] TRUE

If we want to make use of 'year' column with map2

df_new <- df_pre %>%
      mutate(data = map2(data, year, ~  {
              yr <- .y
              .x %>% rename_with(~ str_remove(., str_c("_", yr)), everything())
              }))

-checking

identical(df_new, df_post)
#[1] TRUE
Related