D'abord voir les noms : names() et colnames()
Les noms de colonnes vivent dans un attribut que tu peux lire comme n'importe quel vecteur. names() et colnames() le renvoient tous deux pour un data frame :
Même réponse. La seule vraie différence : colnames() marche aussi sur les matrices, names() non - donc le code générique utilise colnames(). Pour les data frames du quotidien, ils sont interchangeables.
L'idée clé pour tout ce qui suit : renommer une colonne, c'est affecter dans ce vecteur. Il n'y a pas de fonction de base dédiée ; tu modifies names(df) avec la même indexation que sur n'importe quel vecteur.
Renommer par position (ça marche, mais c'est fragile)
Indexe le vecteur de noms par position et affecte :
La colonne 2 s'appelle maintenant price. Très bien pour une correction rapide en interactif - et un piège dans un script. Les positions sont une promesse sur l'ordre des colonnes, et l'ordre des colonnes est la chose la moins stable des données importées : le jour où le CSV que tu lis gagne une colonne supplémentaire, names(df)[2] renomme la mauvaise, silencieusement. Si un script renomme par position, un changement de schéma le casse sans message d'erreur.
Renommer par nom (l'idiome de base robuste)
Matche l'ancien nom au lieu de faire confiance à une position :
Lis d'abord la partie intérieure : names(sales) == "prc" produit FALSE TRUE FALSE - un masque logique sur le vecteur de noms. L'indexer avec sélectionne l'entrée correspondante, et l'affectation la remplace. Si "prc" n'y est pas, rien ne correspond et rien ne change (pas d'erreur - donc vérifie le résultat). Cet idiome survit au réordonnancement, aux colonnes ajoutées, et au copier-coller dans d'autres scripts. Mémorise-le ; c'est la réponse de R de base à « renommer une colonne ».
Plusieurs à la fois
Remplace le vecteur entier quand tu nommes toutes les colonnes (courant juste après un import), ou utilise match() pour renommer un sous-ensemble choisi :
match(old, names(df)) renvoie les positions des anciens noms, donc les nouveaux noms atterrissent exactement là où étaient les anciens - insensible à l'ordre, comme l'idiome à un seul nom. Si un ancien nom manque, match() renvoie NA et l'affectation plante, ce qui est le mode d'échec que tu veux : bruyant.
setNames() pour les pipelines
Tous les idiomes ci-dessus modifient une variable en deux étapes. setNames(object, names) renvoie une copie renommée en une seule expression, ce qu'un pipeline attend :
Pratique quand une fonction renvoie un data frame sans noms ou mal nommé et que tu veux le corriger en ligne - read_something() |> setNames(c("id", "value")) - sans variable temporaire.
La méthode dplyr : rename() et rename_with()
Le rename() de dplyr prend des paires new = old - le nouveau nom d'abord, ce que tout le monde inverse au moins une fois (statique ; le bac à sable n'exécute que R de base) :
library(dplyr)
sales |> rename(price = prc, qty = q)
Les anciens noms non touchés par l'appel sont conservés tels quels, et un ancien nom mal orthographié est une erreur franche plutôt qu'un non-événement silencieux - une vraie amélioration par rapport à l'idiome de base. Pour renommer par règle plutôt que par paire, rename_with() applique une fonction aux noms :
sales |> rename_with(toupper) # every column
sales |> rename_with(toupper, starts_with("p")) # just some
Vois l'intro à dplyr pour la place de ces verbes dans la famille.
Nettoyer des en-têtes importés en vrac
Les vrais en-têtes CSV arrivent en "Order ID", "unit.price ($)", "2024 Total" - des noms avec espaces et symboles qui forcent les backticks partout. Le make.names() de R de base convertit n'importe quel vecteur de caractères en noms R valides :
Valide, mais moche à sa façon (X2024.Total). C'est pourquoi beaucoup d'équipes standardisent sur le clean_names() du package janitor, qui produit du snake_case propre (order_id, unit_price, x2024_total) en un appel : df |> janitor::clean_names(). Si tu importes des fichiers en vrac chaque semaine, il se rentabilise immédiatement.
Ce que tu retiens
- Les noms de colonnes ne sont qu'un vecteur : lis-les avec
names()/colnames(), renomme en affectant dedans. names(df)[2] <- "new"est fragile ;names(df)[names(df) == "old"] <- "new"est l'idiome à mémoriser.match()en renomme plusieurs par nom ;setNames()renomme en ligne dans un pipeline.- Le
rename(new = old)de dplyr plante sur les noms manquants (tant mieux) etrename_with()renomme par règle. - Pour les en-têtes importés en vrac :
make.names()en base,janitor::clean_names()pour un joli résultat.
Prochaine étape : le tri - sort() pour les vecteurs, l'astuce order() pour les data frames, et arrange().
Questions fréquentes
Comment renommer une colonne en R ?
L'idiome de base robuste est de matcher par nom : names(df)[names(df) == "old"] <- "new". Il trouve la colonne appelée old où qu'elle se trouve et la renomme. En dplyr c'est rename(df, new = old) - note l'ordre : le nouveau nom d'abord.
Quelle est la différence entre names() et colnames() ?
Sur un data frame, aucune en pratique - les deux lisent et définissent les noms de colonnes. colnames() marche aussi sur les matrices (là où names() ne marche pas), donc le code censé gérer les deux tend à utiliser colnames(). Sur de simples data frames, utilise celui que tu préfères.
Comment renommer une colonne par position en R ?
Affecte dans le vecteur de noms à cette position : names(df)[2] <- "price" renomme la deuxième colonne. Ça marche, mais c'est fragile - le jour où une colonne est ajoutée ou où le CSV change l'ordre des colonnes, la position 2 est une autre colonne. Préfère renommer par nom.
Comment renommer plusieurs colonnes à la fois en R ?
Affecte un vecteur complet : names(df) <- c("id", "name", "price") remplace tous les noms dans l'ordre. Pour en renommer quelques-unes choisies par nom, utilise match() : names(df)[match(c("old1", "old2"), names(df))] <- c("new1", "new2"). En dplyr : rename(df, new1 = old1, new2 = old2).