Renaming dataframe columns based on values of list

Viewed 49

I want to write a function that checks if the colnames of a dataframe exist in a list. If they do, I want to replace the names with those found in the list.

df <- data.frame(a = 1, b = 2, c = 3, d = 4)
replacements <- list(a = "a1", b = "b1", c = "c1")

I have written a function to do this, but it contains loops, which I would like to avoid.

rename_cols <- function(df) {
  for(i in 1:length(df)) {
    for(j in 1:length(replacements)) {
      if(names(df)[i] == names(replacements)[j]) {
        names(df)[i] <- replacements[[j]]
      }
    }
  }
  return(df)
}

I feel like I'm overthinking this. Please help.

4 Answers

We could use rename. The key/value pair should be inversed

library(dplyr)
rename(df, !!! setNames(names(replacements), unlist(replacements)))
  a1 b1 c1 d
1  1  2  3 4

You could also use the following solution:

fn <- function(data, replacement) {
  nms <- which(names(replacement) %in% names(data))
  
  names(data)[nms] <- sapply(nms, function(x) replacement[[x]])
  names(data)
}

fn(DF, replacements)
[1] "a1" "b1" "c1" "d"

Another dplyr-solution for you,

library(dplyr)

df %>% 
        rename_with(
                .fn = ~ unlist(replacements),
                .cols = contains(names(replacements))
        )
  a1 b1 c1 d
1  1  2  3 4

In base R to change specific column names you can use match.

names(df)[match(names(replacements), names(df))] <- unlist(replacements)
df

#  a1 b1 c1 d
#1  1  2  3 4
Related