Q:

Is there a more robust rename alternative than select with triple exclamation mark?

I have the following simplified use-case and it fails, stating that a column isn't there, which is correct. In my real use-case, this tibble comes from parsing an XML, which may not include all the expected columns but a subset in a few cases, i.e., missing values:
library(tidyverse)
mapping <- c('a', 'b', 'c')
names(mapping) <- c('x', 'y', 'z')

tibble(a=c(1, 2, 3), b=c('m', 'm', 'm')) %>%
  select(!!! mapping)
Error: Unknown column `c` 
  Run `rlang::last_error()` to see where the error occurred.

The error is correct. However, is there a way to robustify this so that c would be created with NAs automatically when missing?
UPDATE: I worked out the following simple solution outside tidyverse:
# create a data frame instead of a tibble
df <- data.frame(a=c(1, 2, 3), b=c('m', 'm', 'm'), stringsAsFactors = FALSE)
# fill in missing columns with NAs
df[,setdiff(mapping, colnames(df))] <- NA
# reorder columns to match the mapping
df <- df[, mapping]
df
# now is safe to rename using the mapping
as_tibble(df) %>%
   select(!!! mapping)

I'm still interested in a modern solution using tidyverse and tibble.

A:

An extension to your solution could be
library(tidyverse)

df[,setdiff(mapping, colnames(df))] <- NA

df %>% rename_all(~names(mapping))

#  x y  z
#1 1 m NA
#2 2 m NA
#3 3 m NA

Or another approach
map_dfc(setdiff(mapping, colnames(df)), ~df %>% mutate(!!.x := NA)) %>%
    arrange(mapping) %>%
    rename_all(~names(mapping))

