在循环中将所有列名称附加到多个data.frames中

时间:2014-08-25 17:15:17

标签: r

我有多个data.frames,它们都有不同的名称,但列名相同,例如:

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)))
  }

如何在每个df中附加具有该df名称的列名?

输出结果为:

> 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

等...

这是我的初始解决方案,但不起作用:

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

2 个答案:

答案 0 :(得分:2)

使用列表中的数据框执行此操作更清晰,更清晰。然后就不需要对assignget等进行笨拙的使用。

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 = "_")))

答案 1 :(得分:1)

一种方法是:

 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

或者

  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