Search code examples
rloopsmultiple-columnsprefix

Adding a numbered prefix to column names in a for loop


I have 50 dataframes that all have the same column names (e.g. df1: colnames = Id, A,B,C,D, df2: colnames = ID, A,B,C,D and so on).

I need to rename these so it becomes df1: colnames = ID, Mth1_A, Mth1_B, Mth1_C, Mth1_D and then df2: ID, Mth2_A, Mth2_B, Mth2_C, Mth2_D. So each column name should correspond to the number of the dataframe.

I've created a function that does this;

col_prefix <- function(df, Mth){
  colnames(df)[2:ncol(df)] <- paste("Mth", colnames(df)[2:ncol(df)], sep = "_")
  return(df)
}

But I'm now trying to create a loop to do it for all 50 and I can't get it to work. This is what I've got so far

dfList <- c("df1", "df2",...,"df50")

for (filename in dfList){
  i <- get(filename)
  i <- col_prefix(i, Mth)
}

Its adding the prefix "Mth" to the datafarmes but its not doing "Mth1", "Mth2", etc. I'm fairly sure this is because in my function Mth is a character but I don't know how to loop through this.

Please help!


Solution

  • Put them in a list and use their name (df1, df2, etc...)to catch the prefix, i.e.

    l1 <- mget(grep(pattern = "df[0-9]+", x = ls(), value = TRUE))
    Map(function(x, y) setNames(x, paste0('MTH', gsub('\\D+', '', y), '_', names(x))), 
        l1, names(l1))
    
    $df1
      MTH1_v1 MTH1_v2
    1       5       9
    2       6      10
    3       7      11
    
    $df2
      MTH2_v1 MTH2_v2
    1      15      19
    2      16     110
    3      17     111
    

    To change all names except the first one then,

    Map(function(x, y) data.frame(x[1], setNames(x[-1], paste0('MTH', gsub('\\D+', '', y), '_', names(x)[-1]))), l1, names(l1))
    
    $df1
      v1 MTH1_v2
    1  5       9
    2  6      10
    3  7      11
    
    $df2
      v1 MTH2_v2
    1 15      19
    2 16     110
    3 17     111
    

    DATA

    dput(df1)
    structure(list(v1 = c(5, 6, 7), v2 = c(9, 10, 11)), class = "data.frame", row.names = c(NA, 
    -3L))
    dput(df2)
    structure(list(v1 = c(15, 16, 17), v2 = c(19, 110, 111)), class = "data.frame", row.names = c(NA, 
    -3L))