web-dev-qa-db-fra.com

Utilisation de lapply pour modifier les noms de colonne d'une liste de cadres de données

J'essaie d'utiliser lapply sur une liste de trames de données; mais en échouant à passer les paramètres correctement (je pense). 

Liste des trames de données:

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

Vecteur avec noms de colonnes:

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

J'aimerais changer les noms de colonnes en utilisant lapply:

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

mais cela ne change pas les noms du tout. Est-ce que je ne passe pas les trames de données elles-mêmes, mais quelque chose d'autre? Je veux juste changer de nom, pas renvoyer le résultat à un nouvel objet.

Merci d'avance, p.

9
user3310782

Vous pouvez également utiliser setNames si vous souhaitez remplacer toutes les colonnes.

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

Si vous ne devez remplacer qu'un sous-ensemble de noms de colonnes, vous pouvez utiliser la solution de @Jogo.

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

Un dernier point, dans R, il y a une différence entre a: b - 1 et 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

MODIFIER

Si vous souhaitez modifier les noms de colonne du data.frame dans un environnement global à partir d'une liste, vous pouvez utiliser list2env mais je ne suis pas sûr que ce soit le meilleur moyen d'obtenir le résultat souhaité. Vous devez également modifier votre liste et utiliser la liste nommée. Le nom doit être identique au nom du data.frame que vous devez remplacer.

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
16
dickoa

essaye ça:

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

vous obtiendrez une nouvelle liste avec des cadres de données modifiés. Si vous voulez manipuler directement la listDF:

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

Je n'ai pas pu obtenir le code utilisé dans ces réponses au travail. J'ai trouvé du code d'un autre forum qui a fonctionné. Cela assignera les nouveaux noms de colonne à chaque image, les autres méthodes créant une copie des images. Pour tout le monde, voici le 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)
}
0
Patrick