41

One can rename a field:

mtcars %>% rename(bla = mpg)

But if the field doesn't exist, an error:

    mtcars %>% rename(MPG = mpg, CYL = cyl, bla = uyhgfrtgf)
Error: Can't rename columns that don't exist.
x Column `uyhgfrtgf` doesn't exist

I looked at ?rename_if and it says this is now superseded by rename_with().

What's the 'right' way to attempt to rename fields but with a possibility they don't exist (e.g. in this case a ShinyApp with filter selectors).

Doug Fir
  • 19,971
  • 47
  • 169
  • 299
  • Also see [Avoiding error when using rename in dplyr and column doesn't exist](https://stackoverflow.com/q/34275576/1082435) – wibeasley May 17 '23 at 23:41

5 Answers5

71

Use any_of() with a named vector. any_of() doesn't error if a variable isn't found.

library(dplyr)

lookup <- c(MPG = "mpg", CYL = "cyl", bla = "uyhgfrtgf")

mtcars %>%
   rename(any_of(lookup))

                   MPG CYL disp  hp drat    wt  qsec vs am gear carb
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
...
Ritchie Sacramento
  • 29,890
  • 4
  • 48
  • 56
11

I'm pretty sure you can do this with NSE but I can't handle this (yet?).

So you could define a lookup variable first:

lookup <- c("mpg" = "MPG", "cyl" = "CYL", "uyhgfrtgf" = "bla")

Attention: it's the other way round as in your rename function.

Now you could use

library(dplyr)

df %>% 
  rename_with(.fn = ~lookup[.x], .cols = intersect(names(.), names(lookup)))

which returns

                     MPG CYL  disp  hp drat    wt  qsec vs am gear carb
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
Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
Martin Gal
  • 16,640
  • 5
  • 21
  • 39
7

We may use

library(dplyr)
lookup <-c("MPG" = "mpg", "CYL" = "cyl", "bla" = "uyhgfrtgf")
mtcars %>% 
    rename(!!! lookup[names(.) %in% lookup])
                     MPG CYL  disp  hp drat    wt  qsec vs am gear carb
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
Valiant             18.1   6 225.0 105 2.76 3.460 20.22  1  0    3    1
Duster 360          14.3   8 360.0 245 3.21 3.570 15.84  0  0    3    4
Merc 240D           24.4   4 146.7  62 3.69 3.190 20.00  1  0    4    2
Merc 230            22.8   4 140.8  95 3.92 3.150 22.90  1  0    4    2
Merc 280            19.2   6 167.6 123 3.92 3.440 18.30  1  0    4    4
...
akrun
  • 874,273
  • 37
  • 540
  • 662
7

We could use rename_with from dplyr package and wrap it in a ~case_when function:

library(dplyr)

mtcars %>% 
    rename_with(
        ~ case_when(
        . == "mpg" ~ "MPG",
        . == "cyl" ~ "CYL",
        . == "bla" ~ "uyhgfrtgf",
        TRUE ~ .))

                     MPG CYL  disp  hp drat    wt  qsec vs am gear carb
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
TarJae
  • 72,363
  • 6
  • 19
  • 66
3

You could use the following solution:

library(dplyr)
library(stringr)

names <- c("mpg", "cyl", "sdad")
reps <- c("MPG", "CYL", "BLA")

mtcars %>%
  rename_with(~ str_replace_all(.x, "\\w+", reps[names(mtcars) %in% names]), matches(names))

                   MPG CYL disp  hp drat    wt  qsec vs am gear carb
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
Anoushiravan R
  • 21,622
  • 3
  • 18
  • 41