jzadra
jzadra

Reputation: 4304

How to rename columns in a table by using a table of old and new names in R (tidyverse)?

I have a table with column names that I want to change based on a table with a column of the current names and a column of the replacement names.

As an example:

library(tidyverse)
name_tbl <- enframe(names(mtcars), value = "old_names") %>% 
  rowwise() %>% 
  mutate(new_names = paste0(old_names, sample(50:100, 1)))

name_tbl
#> # A tibble: 11 x 3
#> # Rowwise: 
#>     name old_names new_names
#>    <int> <chr>     <chr>    
#>  1     1 mpg       mpg79    
#>  2     2 cyl       cyl57    
#>  3     3 disp      disp70   
#>  4     4 hp        hp57     
#>  5     5 drat      drat72   
#>  6     6 wt        wt88     
#>  7     7 qsec      qsec86   
#>  8     8 vs        vs66     
#>  9     9 am        am91     
#> 10    10 gear      gear71   
#> 11    11 carb      carb50

At this point, I would like to be able to do something like:

mtcars %>% rename(name_tbl$old_names = name_tbl$new_names)

however it of course does not work because rename expects named arguments.

I've looked all over and have not found a tidyverse method of doing this operation. Is there some way to rename columns using a lookup table like this?

Currently I'm pivoting longer on everything and then left_joining the key table, however this is problematic because all columns have to be converted to the same type first, which is not easily undone.

Upvotes: 2

Views: 654

Answers (2)

tmfmnk
tmfmnk

Reputation: 40081

One option with the addition of stringr could be:

mtcars %>%
 rename_with(~ str_replace_all(., setNames(name_tbl$new_names, name_tbl$old_names)), everything())

                    mpg81 cyl61 disp61 hp69 drat98  wt99 qsec87 vs87 am77 gear50 carb81
Mazda RX4            21.0     6  160.0  110   3.90 2.620  16.46    0    1      4      4
Mazda RX4 Wag        21.0     6  160.0  110   3.90 2.875  17.02    0    1      4      4
Datsun 710           22.8     4  108.0   93   3.85 2.320  18.61    1    1      4      1
Hornet 4 Drive       21.4     6  258.0  110   3.08 3.215  19.44    1    0      3      1
Hornet Sportabout    18.7     8  360.0  175   3.15 3.440  17.02    0    0      3      2

Upvotes: 1

akrun
akrun

Reputation: 887501

We ungroup, the 'name_tbl' and create a named vector or list and use !!! within rename to change the column names

library(dplyr)
library(tibble)
v1 <- name_tbl %>% 
       ungroup %>%
       select(new_names, old_names) %>%
       deframe
mtcars %>% 
  rename(!!! v1)

-output

#                   mpg82 cyl96 disp93 hp94 drat74  wt58 qsec53 vs70 am79 gear81 carb83
#Mazda RX4          21.0     6    160  110   3.90 2.620  16.46    0    1      4      4
#Mazda RX4 Wag      21.0     6    160  110   3.90 2.875  17.02    0    1      4      4
#Datsun 710         22.8     4    108   93   3.85 2.320  18.61    1    1      4      1
#Hornet 4 Drive     21.4     6    258  110   3.08 3.215  19.44    1    0      3      1
#Hornet Sportabout  18.7     8    360  175   3.15 3.440  17.02    0    0      3      2
#Valiant            18.1     6    225  105   2.76 3.460  20.22    1    0      3      1
# ...

Upvotes: 3

Related Questions