Using lapply to change column names of a list of data frames

↘锁芯ラ 提交于 2019-11-27 01:24:13

问题


I'm trying to use lapply on a list of data frames; but failing at passing the parameters correctly (I think).

List of data frames:

df1 <- data.frame(A = 1:10, B= 11:20)
df2 <- data.frame(A = 21:30, B = 31:40) 

listDF <- list(df1, df2,df3)    #multiple data frames w. way less columns than the length of vector todos

Vector with columns names:

todos <-c('col1','col2', ......'colN')

I'd like to change the column names using lapply:

lapply (listDF, function(x) { colnames(x)[2:length(x)] <-todos[1:length(x)-1] }  )

but this doesn't change the names at all. Am I not passing the data frames themselves, but something else? I just want to change names, not to return the result to a new object.

Thanks in advance, p.


回答1:


You can also use setNames if you want to replace all columns

df1 <- data.frame(A = 1:10, B= 11:20)
df2 <- data.frame(A = 21:30, B = 31:40) 

listDF <- list(df1, df2)
new_col_name <- c("C", "D")

lapply(listDF, setNames, nm = new_col_name)
## [[1]]
##     C  D
## 1   1 11
## 2   2 12
## 3   3 13
## 4   4 14
## 5   5 15
## 6   6 16
## 7   7 17
## 8   8 18
## 9   9 19
## 10 10 20

## [[2]]
##     C  D
## 1  21 31
## 2  22 32
## 3  23 33
## 4  24 34
## 5  25 35
## 6  26 36
## 7  27 37
## 8  28 38
## 9  29 39
## 10 30 40

If you need to replace only a subset of column names, then you can use the solution of @Jogo

lapply(listDF, function(df) {
  names(df)[-1] <- new_col_name[-ncol(df)]
  df
})

A last point, in R there is a difference between a:b - 1 and a:(b - 1)

1:10 - 1
## [1] 0 1 2 3 4 5 6 7 8 9

1:(10 - 1)
## [1] 1 2 3 4 5 6 7 8 9

EDIT

If you want to change the column names of the data.frame in global environment from a list, you can use list2env but I'm not sure it is the best way to achieve want you want. You also need to modify your list and use named list, the name should be the same as name of the data.frame you need to replace.

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

new_col_name <- c("C", "D")

listDF <- lapply(listDF, function(df) {
  names(df)[-1] <- new_col_name[-ncol(df)]
  df
})

list2env(listDF, envir = .GlobalEnv)
str(df1)
## 'data.frame':    10 obs. of  2 variables:
##  $ A: int  1 2 3 4 5 6 7 8 9 10
##  $ C: int  11 12 13 14 15 16 17 18 19 20



回答2:


try this:

lapply (listDF, function(x) { 
  names(x)[-1] <- todos[-length(x)]
  x 
})

you will get a new list with changed dataframes. If you want to manipulate the listDF directly:

for (i in 1:length(listDF)) names(listDF[[i]])[-1] <- todos[-length(listDF[[i]])]



回答3:


I was not able to get the code used in these answers to work. I found some code from another forum which did work. This will assign the new column names into each dataframe, the other methods created a copy of the dataframes. For anyone else here is the code.

# Create some dataframes
df1 <- data.frame(A = 1:10, B= 11:20)
df2 <- data.frame(A = 21:30, B = 31:40)

listDF <- c("df1", "df2") #Notice this is NOT a list
new_col_name <- c("C", "D") #What do you want the new columns to be named?

# Assign the new column names to each dataframe in "listDF"
for(df in listDF) {
  df.tmp <- get(df)
  names(df.tmp) <- new_col_name
  assign(df, df.tmp)
}


来源:https://stackoverflow.com/questions/33567101/using-lapply-to-change-column-names-of-a-list-of-data-frames

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!