1

Consider the two dataframe df1, df2 that have different column names. I need to systematically change the column naming scheme to obtain the same as in df_target

df1 <- data.frame(
  a = 0,
  b = 0
)

df2 <- data.frame(
  A = 0,
  B = 0
)

df_target <- data.frame(
  one = 0,
  two = 0
)

My thought would be create a dictionary (or any other approach would be fine) similar to the df_mapping

df_mapping <- data.frame(
  first = c("a", "A", "one"),
  second = c("b", "B", "two")
)

that contains a mapping so that I can systematically change the names. I am looking for some way to obtain this.

Note that the columns in each dataframe might be in arbitrary order. There might be some names that are unique to df1 and df2 and are not in the mapping and should stay the same.

3 Answers3

3

You can use this function:

change_name <-
  function(data, nms){
  tmp <- nms[nms %in% names(data)]
  colnames(data)[colnames(data) %in% tmp] <- names(tmp)
  data
}

And apply to your list of dataframes. This will work even if you have other columns in your dataframe, but you should create first a named vector with the new and old names:

nms <- c(one = "a", one = "A", two = "b", two = "B")
lapply(list(df1, df2), change_name, nms = nms)

[[1]]
  one two c
1   0   0 0

[[2]]
  one two
1   0   0
Maël
  • 45,206
  • 3
  • 29
  • 67
2

A dplyr approach with rename_with + case_match:

library(dplyr)

# create a formula-list lookup table
lookup <- c(
  c("a", "A") ~ "one",
  c("b", "B") ~ "two"
)

list(df1 = df1, df2 = df2) %>%
  lapply(\(df) rename_with(df, ~ case_match(.x, !!!lookup, .default = .x), everything()))

# $df1
#   one two  c
# 1   0   0  0
# 
# $df2
#   one two
# 1   0   0
Darren Tsai
  • 32,117
  • 5
  • 21
  • 51
1

We can use

library(dplyr)
 v1 <- list("one" = "A", "two" = "B")
df1 %>%
  setNames(toupper(names(.))) %>% 
  rename(!!! v1)

-output

   one two
1   0   0

For two datasets

library(purrr)
map(list(df1, df2), ~ .x %>%
       setNames(toupper(names(.))) %>% 
  rename(!!! v1))

-output

[[1]]
  one two
1   0   0

[[2]]
  one two
1   0   0
akrun
  • 874,273
  • 37
  • 540
  • 662