Search code examples
rlistdataframesequencerename

Rename columns in list of dataframes in R


I have list of dataframes and I want to change column name in each dataframe

my_list <- list(one = data.frame(a = 1:5, lag_a = 1:5, lag_a = 1:5, lag_a = 1:5, lag_a = 1:5), 
                wo = data.frame(a= 1:5, lag_a = 1:5, lag_a = 1:5, lag_a = 1:5, lag_a = 1:5),
                three = data.frame(a = 1:5, lag_a = 1:5, lag_a = 1:5, lag_a = 1:5, lag_a = 1:5))

my_list <- map(my_list, ~ rename_with(., ~ ifelse(
    grepl("lag_", .), paste0("a", 4:1), . 
  )))
my_list[1]
> my_list[1]
$one
   a a3 a2 a1 a4
1  1  1  1  1  1
2  2  2  2  2  2
3  3  3  3  3  3
4  4  4  4  4  4
5  5  5  5  5  5

But I want the colnames in each data frames a, a1, a2, a3, a4 in order. But it cant because automatic the first one in R be tagged as one(?). Maybe.

Actually in real my data i want to rename be a, a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12. But I try still cant

Thank you for helping


Solution

  • Using starts_with instead of an ifelse you could do:

    library(dplyr)
    library(purrr)
    
    my_list <- map(my_list, ~ rename_with(., ~ paste0("a", 1:4), starts_with("lag_")))
    
    my_list[[1]]
    #>   a a1 a2 a3 a4
    #> 1 1  1  1  1  1
    #> 2 2  2  2  2  2
    #> 3 3  3  3  3  3
    #> 4 4  4  4  4  4
    #> 5 5  5  5  5  5
    

    Or using base R you could do:

    base <- lapply(my_list, function(x) { 
      is_lag <- grepl("^lag_", names(x)) 
      names(x)[is_lag] <- paste0("a", seq(sum(is_lag))); 
      x 
    })
    
    base[[1]]
    #>   a a1 a2 a3 a4
    #> 1 1  1  1  1  1
    #> 2 2  2  2  2  2
    #> 3 3  3  3  3  3
    #> 4 4  4  4  4  4
    #> 5 5  5  5  5  5