Erst die Namen ansehen: names() und colnames()
Spaltennamen leben in einem Attribut, das man wie jeden Vektor lesen kann. names() und colnames() geben es für einen Data Frame beide zurück:
Gleiche Antwort. Der eine echte Unterschied: colnames() funktioniert auch auf Matrizen, names() nicht - generischer Code verwendet daher colnames(). Für alltägliche Data Frames sind sie austauschbar.
Die Kernerkenntnis für alles Folgende: Eine Spalte umzubenennen heißt, in diesen Vektor zuzuweisen. Es gibt keine eigene Base-Funktion; man verändert names(df) mit derselben Indexierung wie bei jedem Vektor.
Umbenennen nach Position (funktioniert, aber fragil)
Den Namensvektor nach Position indexieren und zuweisen:
Spalte 2 heißt jetzt price. Für eine schnelle interaktive Korrektur in Ordnung - in einem Skript eine Falle. Positionen sind ein Versprechen über die Spaltenreihenfolge, und die Spaltenreihenfolge ist das Instabilste an importierten Daten: An dem Tag, an dem die eingelesene CSV eine zusätzliche Spalte bekommt, benennt names(df)[2] die falsche um, stillschweigend. Wenn ein Skript nach Position umbenennt, bricht eine Schemaänderung es ohne Fehlermeldung.
Umbenennen nach Name (das robuste Base-Idiom)
Den alten Namen abgleichen, statt einer Position zu vertrauen:
Lies zuerst den inneren Teil: names(sales) == "prc" erzeugt FALSE TRUE FALSE - eine logische Maske über den Namensvektor. Damit zu indexieren wählt den passenden Eintrag aus, und die Zuweisung ersetzt ihn. Ist "prc" nicht vorhanden, passt nichts und nichts ändert sich (kein Fehler - also das Ergebnis prüfen). Dieses Idiom übersteht Umsortierungen, hinzugefügte Spalten und Copy-Paste in andere Skripte. Merk es dir; es ist die Base-R-Antwort auf "eine Spalte umbenennen".
Mehrere auf einmal
Den ganzen Vektor ersetzen, wenn man jede Spalte benennt (üblich direkt nach einem Import), oder match() verwenden, um eine ausgewählte Teilmenge umzubenennen:
match(old, names(df)) gibt die Positionen der alten Namen zurück, sodass die neuen Namen genau dort landen, wo die alten waren - reihenfolgesicher, wie das Einzelnamen-Idiom. Fehlt ein alter Name, gibt match() NA zurück und die Zuweisung wirft einen Fehler - genau der Fehlermodus, den man will: laut.
setNames() für Pipelines
Alle Idiome oben verändern eine Variable in zwei Schritten. setNames(objekt, namen) gibt eine umbenannte Kopie in einem Ausdruck zurück - genau das, was eine Pipeline braucht:
Praktisch, wenn eine Funktion einen unbenannten oder schlecht benannten Frame zurückgibt und man ihn inline korrigieren will - read_something() |> setNames(c("id", "value")) - ohne temporäre Variable.
Der dplyr-Weg: rename() und rename_with()
dplyr's rename() nimmt new = old-Paare - neuer Name zuerst, was jeder genau einmal verwechselt (statisch; die Sandbox führt nur Base R aus):
library(dplyr)
sales |> rename(price = prc, qty = q)
Alte Namen, die der Aufruf nicht berührt, bleiben erhalten, und ein falsch geschriebener alter Name ist ein harter Fehler statt eines stillen No-Ops - eine echte Verbesserung gegenüber dem Base-Idiom. Zum Umbenennen nach Regel statt nach Paar wendet rename_with() eine Funktion auf die Namen an:
sales |> rename_with(toupper) # every column
sales |> rename_with(toupper, starts_with("p")) # just some
Siehe die dplyr-Einführung dazu, wie diese in die Verben-Familie passen.
Chaotische importierte Header aufräumen
Echte CSV-Header kommen als "Order ID", "unit.price ($)", "2024 Total" an - Namen mit Leerzeichen und Symbolen, die überall Backtick-Quoting erzwingen. Base R's make.names() wandelt jeden Zeichenvektor in gültige R-Namen um:
Gültig, aber auf eigene Weise hässlich (X2024.Total). Deshalb standardisieren viele Teams auf clean_names() aus dem janitor-Paket, das in einem Aufruf sauberes snake_case erzeugt (order_id, unit_price, x2024_total): df |> janitor::clean_names(). Wer wöchentlich unsaubere Dateien importiert, hat den Aufwand sofort wieder drin.
Was du mitnimmst
- Spaltennamen sind nur ein Vektor: mit
names()/colnames()lesen, durch Zuweisung hinein umbenennen. names(df)[2] <- "new"ist fragil;names(df)[names(df) == "old"] <- "new"ist das Idiom zum Merken.match()benennt mehrere nach Name um;setNames()benennt inline in einer Pipeline um.- dplyr's
rename(new = old)wirft bei fehlenden Namen einen Fehler (gut), undrename_with()benennt nach Regel um. - Für chaotische importierte Header:
make.names()in Base,janitor::clean_names()für schöne Ergebnisse.
Als Nächstes: Sortieren - sort() für Vektoren, der order()-Trick für Data Frames und arrange().
Häufig gestellte Fragen
Wie benenne ich eine Spalte in R um?
Das robuste Base-Idiom ist der Abgleich nach Name: names(df)[names(df) == "old"] <- "new". Es findet die Spalte namens old, egal wo sie steht, und benennt sie um. In dplyr ist es rename(df, new = old) - Achtung auf die Reihenfolge: neuer Name zuerst.
Was ist der Unterschied zwischen names() und colnames()?
Bei einem Data Frame praktisch keiner - beide lesen und setzen die Spaltennamen. colnames() funktioniert zusätzlich auf Matrizen (wo names() nicht funktioniert), daher verwendet Code, der beides abdecken soll, eher colnames(). Bei gewöhnlichen Data Frames nimm, was dir lieber ist.
Wie benenne ich eine Spalte nach Position in R um?
In den Namensvektor an dieser Position zuweisen: names(df)[2] <- "price" benennt die zweite Spalte um. Das funktioniert, ist aber fragil - an dem Tag, an dem eine Spalte hinzukommt oder die CSV die Spaltenreihenfolge ändert, ist Position 2 eine andere Spalte. Besser nach Name umbenennen.
Wie benenne ich mehrere Spalten auf einmal in R um?
Einen vollständigen Vektor zuweisen: names(df) <- c("id", "name", "price") ersetzt alle Namen der Reihe nach. Um ausgewählte Spalten nach Name umzubenennen, match() verwenden: names(df)[match(c("old1", "old2"), names(df))] <- c("new1", "new2"). In dplyr: rename(df, new1 = old1, new2 = old2).