USER_1
USER_1

Reputation: 2469

Append all column names in multiple data.frames in a loop

I have multiple data.frames that all have different names but same column names, for example:

filenames <- c(1:10)
for (i in filenames){
  filenames[i] <- paste("df",filenames[i],sep="")  
  assign((filenames[i]), data.frame(matrix(rnorm(20), nrow=10)))
  }

How can one append the column names within each df with the name of that df?

The output would be:

> head(df1)
      df1_X1     df1_X2
1  0.2343486  0.2191546
2  0.5042413  2.0720167
3 -0.1082240  0.7376801
4  0.2346395  0.4677974
5  1.1559909 -1.1432890
6 -1.5554426 -0.2309197
> head(df2)
       df2_X1     df2_X2
1 -2.79824632 -0.1879618
2  1.93410571  0.3012066
3  0.72948663  0.2139871
4  0.59290004  1.1093813
5  0.04826737 -0.4062374
6 -0.78271090 -1.2870127

etc...

Here is my initial solution, which does not work:

for (i in length(filenames)){  
  colnames(filenames[i]) <- paste(filenames[i], colnames(filenames[i]), sep = "_") 
}

Upvotes: 0

Views: 136

Answers (2)

akrun
akrun

Reputation: 887138

One way would be:

 df1 <- data.frame(X1=1:5, X2=6:10)
 df2 <- data.frame(X1=16:20, X2=21:25)
 name1 <- ls(pattern="^df\\d+$") 
 cNames <- colnames(df1) #assuming that column names are the same for all dataframes

 for(i in 1:2){
  assign(name1[i], `names<-` (get(name1[i]), paste(name1[i],cNames, sep="_"))) 
  }

 df1
 # df1_X1 df1_X2
 #1      1      6
 #2      2      7
 #3      3      8
 #4      4      9
 #5      5     10

 df2
 #  df2_X1 df2_X2
 #1     16     21
 #2     17     22
 #3     18     23
 #4     19     24
 #5     20     25

Or

  cNames1 <- c(t(outer(name1, cNames, FUN=paste, sep="_")))
  names2 <- split(cNames1,gsub("_.*", "", cNames1))
  list2env(
       Map(function(n1, data) {
       names(data) <- n1
       data
      }, names2, mget(name1)),
               envir = .GlobalEnv)
  df1
 #  df1_X1 df1_X2
 #1      1      6
 #2      2      7
 #3      3      8
 #4      4      9
 #5      5     10

Upvotes: 1

joran
joran

Reputation: 173577

It is clearer and cleaner to do this with the data frames in a list. Then there's no need for awkward uses of assign, get, etc.

df1 <- data.frame(X1=1:5, X2=6:10)
df2 <- data.frame(X1=16:20, X2=21:25)

dfs <- list(df1 = df1,df2 = df2)

dfs_new <- lapply(names(dfs),
                  function(x) setNames(dfs[[x]],paste(x,colnames(dfs[[x]]),
                                                      sep = "_")))

Upvotes: 2

Related Questions