Home > Back-end >  Rename variables (columns) in datasets that are in a list - R
Rename variables (columns) in datasets that are in a list - R

Time:07-22

I have a list of datasets with different variables. I need to rename them according to the naming convention in the name dataframe below.

df1 <- data.frame(x1= c(1,2,3), x2=c(1,2,3))
df2 <- data.frame(x1= c(1,2,3), x3=c(1,2,3))
df3 <- data.frame(x4= c(1,2,3), x5=c(1,2,3))

mylist <- list(df1,df2,df3)

name <- data.frame(old= c("x1","x2","x3","x4","x5"), new=c("A","B","A","A","C"))

I can do this one by one, but I am wondering how to be more efficient and rename them all at once

newdf <- map_if(mylist, ~ "x1" %in% colnames(.x),
                .f = list(. %>% rename("A"="x1")))

I was hoping something like this would work, but it doesn't:

for (i in nrow(name)){

newdf <- map_if(mylist, ~ name[i,1] %in% colnames(.x),
                .f = list(. %>% rename(name[2]=name[1])))

}

CodePudding user response:

You can use setnames from data.table, which can take a list of old and new names.

library(data.table)
library(purrr)

map(mylist, ~ setnames(.x, name$old, name$new, skip_absent=TRUE))

Output

[[1]]
  A B
1 1 1
2 2 2
3 3 3

[[2]]
  A A
1 1 1
2 2 2
3 3 3

[[3]]
  A C
1 1 1
2 2 2
3 3 3

CodePudding user response:

Column names must be unique, so there is a typo (?) in your example (as "x1" and "x3" would both be re-labelled as "A").

If we fix the typo, here is an option using map and rename_with.

name <- data.frame(old= c("x1","x2","x3","x4","x5"), new=c("A","B","C","D","E"))

library(tidyverse)
mylist %>%
  map(function(df) df %>% rename_with(~ name$new[match(.x, name$old)]))
#[[1]]
#  A B
#1 1 1
#2 2 2
#3 3 3
#
#[[2]]
#  A C
#1 1 1
#2 2 2
#3 3 3
#
#[[3]]
#  D E
#1 1 1
#2 2 2
#3 3 3

CodePudding user response:

You could use set_names recode:

library(tidyverse)

map(mylist, set_names, ~ recode(.x, !!!deframe(name)))

[[1]]
  A B
1 1 1
2 2 2
3 3 3

[[2]]
  A A
1 1 1
2 2 2
3 3 3

[[3]]
  A C
1 1 1
2 2 2
3 3 3
  • Related