Jemand hätte das schon fragen sollen, aber ich konnte keine Antwort finden. Sagen wir, ich habe:
x = data.frame(q=1,w=2,e=3, ...and many many columns...)
Was ist der eleganteste Weg, um eine beliebige Teilmenge von Spalten, deren Position ich nicht unbedingt kenne, in andere beliebige Namen umzubenennen?
Beispiel: Ich möchte umbenennen "q"
und "e"
in "A"
und "B"
, was ist der eleganteste Code, um dies zu tun?
Natürlich kann ich eine Schleife machen:
oldnames = c("q","e")
newnames = c("A","B")
for(i in 1:2) names(x)[names(x) == oldnames[i]] = newnames[i]
Aber ich frage mich, ob es einen besseren Weg gibt? Vielleicht mit einigen der Pakete? ( plyr::rename
etc.)
old = c("a", "d", "e")
rename_at()
arbeitete daran, Variablennamen einer Teilmenge zu ändern.Mit dplyr würden Sie tun:
library(dplyr) df = data.frame(q = 1, w = 2, e = 3) df %>% rename(A = q, B = e) # A w B #1 1 2 3
Oder wenn Sie Vektoren verwenden möchten, wie von @ Jelena-bioinf vorgeschlagen:
library(dplyr) df = data.frame(q = 1, w = 2, e = 3) oldnames = c("q","e") newnames = c("A","B") df %>% rename_at(vars(oldnames), ~ newnames) # A w B #1 1 2 3
LD Nicolas May schlug vor, eine Änderung durch
rename_at
folgende zu ersetzenrename_with
:df %>% rename_with(~ newnames[which(oldnames == .x)], .cols = oldnames) # A w B #1 1 2 3
quelle
old
undnew
Namen als Vektoren, denke ichrename_with
Sie können entweder eine Funktion oder eine Formel verwenden, um alle als.cols
Argument angegebenen Spalten umzubenennen . Zum Beispielrename_with(iris, toupper, starts_with("Petal"))
ist äquivalent zurename_with(iris, ~ toupper(.x), starts_with("Petal"))
.Eine andere Lösung für Datenrahmen, die nicht zu groß sind, ist (basierend auf der Antwort von @thelatemail):
x <- data.frame(q=1,w=2,e=3) > x q w e 1 1 2 3 colnames(x) <- c("A","w","B") > x A w B 1 1 2 3
Alternativ können Sie auch Folgendes verwenden:
names(x) <- c("C","w","D") > x C w D 1 1 2 3
Darüber hinaus können Sie auch eine Teilmenge der Spaltennamen umbenennen:
names(x)[2:3] <- c("E","F") > x C E F 1 1 2 3
quelle
Hier ist die effizienteste Methode, die ich gefunden habe, um mehrere Spalten mit einer Kombination aus
purrr::set_names()
und einigenstringr
Operationen umzubenennen .library(tidyverse) # Make a tibble with bad names data <- tibble( `Bad NameS 1` = letters[1:10], `bAd NameS 2` = rnorm(10) ) data # A tibble: 10 x 2 `Bad NameS 1` `bAd NameS 2` <chr> <dbl> 1 a -0.840 2 b -1.56 3 c -0.625 4 d 0.506 5 e -1.52 6 f -0.212 7 g -1.50 8 h -1.53 9 i 0.420 10 j 0.957 # Use purrr::set_names() with annonymous function of stringr operations data %>% set_names(~ str_to_lower(.) %>% str_replace_all(" ", "_") %>% str_replace_all("bad", "good")) # A tibble: 10 x 2 good_names_1 good_names_2 <chr> <dbl> 1 a -0.840 2 b -1.56 3 c -0.625 4 d 0.506 5 e -1.52 6 f -0.212 7 g -1.50 8 h -1.53 9 i 0.420 10 j 0.957
quelle
~
und.
Argumente in derset_names()
Pipe tun.purrr::set_names()
.purrr
Funktionen~
bedeutet die Tilde "für jede Spalte". Das.
ist dplyr Syntax für LHS = linke Seite des Rohres, also die Referenz auf das Objekt , das geleitet wird, in diesem Falldata
.~
ist eine Formel. Sie können auch einen Funktionsaufruf verwenden und die Argumente an das...
Argument übergeben, dasset_names
beispielsweiserlang::set_names(head(iris), paste0, "_hi")
entsprichtrlang::set_names(head(iris), ~ paste0(.x, "_hi"))
.Ich bin kürzlich selbst darauf gestoßen, wenn Sie nicht sicher sind, ob die Spalten vorhanden sind, und nur diejenigen umbenennen möchten, die dies tun:
existing <- match(oldNames,names(x)) names(x)[na.omit(existing)] <- newNames[which(!is.na(existing))]
quelle
Aufbauend auf der Antwort von @ user3114046:
x <- data.frame(q=1,w=2,e=3) x # q w e #1 1 2 3 names(x)[match(oldnames,names(x))] <- newnames x # A w B #1 1 2 3
Dies hängt nicht von einer bestimmten Reihenfolge der Spalten im
x
Dataset ab.quelle
match
sich darum kümmert. Das Beste, was Sie tun werden, ist wahrscheinlich diesetnames
Antwort von @ mnel .match
immer noch ein positionsorientierter Befehl ist , obwohl ich keinen Positionsvektor explizit angeben muss . In diesem Sinne habe ich auch die Antwortposition von @ user3114046 als basiert angesehen (obwohl ich dachte, der%in%
Befehl kümmert sich um die Dinge (oder versucht es)). Natürlich können Sie argumentieren, dass alle Befehle positionsorientiert sind, wenn wir uns mit dem Mechanismus auf niedriger Ebene befassen ... aber das meine ich nicht ... die Antwort auf die Datentabelle ist großartig, da es keine Mehrfachaufrufe von gibtname
Befehle.Dies würde alle Vorkommen dieser Buchstaben in allen Namen ändern:
names(x) <- gsub("q", "A", gsub("e", "B", names(x) ) )
quelle
gsubfn
Antwort zu finden. Vielleicht kommt G.Grothendieck vorbei. Er ist der Regex-Meister.names(x)[names(x) %in% c("q","e")]<-c("A","B")
quelle
oldnames
so sortiert ist, dass sieoldnames[i]
zuvoroldnames[j]
für i <j auftritt .Sie können den Namen festlegen, als Liste speichern und dann die Massenumbenennung für die Zeichenfolge vornehmen. Ein gutes Beispiel hierfür ist, wenn Sie einen langen bis breiten Übergang für einen Datensatz durchführen:
names(labWide) Lab1 Lab10 Lab11 Lab12 Lab13 Lab14 Lab15 Lab16 1 35.75366 22.79493 30.32075 34.25637 30.66477 32.04059 24.46663 22.53063 nameVec <- names(labWide) nameVec <- gsub("Lab","LabLat",nameVec) names(labWide) <- nameVec "LabLat1" "LabLat10" "LabLat11" "LabLat12" "LabLat13" "LabLat14""LabLat15" "LabLat16" "
quelle
Nebenbei bemerkt, wenn Sie eine Zeichenfolge mit allen Spaltennamen verknüpfen möchten, können Sie einfach diesen einfachen Code verwenden.
colnames(df) <- paste("renamed_",colnames(df),sep="")
quelle
Wenn die Tabelle zwei Spalten mit demselben Namen enthält, lautet der Code folgendermaßen:
quelle
Sie können einen benannten Vektor verwenden.
Mit Basis R (vielleicht etwas klobig):
x = data.frame(q = 1, w = 2, e = 3) rename_vec <- c(q = "A", e = "B") names(x) <- ifelse(is.na(rename_vec[names(x)]), names(x), rename_vec[names(x)]) x #> A w B #> 1 1 2 3
Oder eine
dplyr
Option mit!!!
:library(dplyr) rename_vec <- c(A = "q", B = "e") # the names are just the other way round than in the base R way! x %>% rename(!!!rename_vec) #> A w B #> 1 1 2 3
Letzteres funktioniert, weil der 'Big-Bang'- Operator
!!!
die Auswertung einer Liste oder eines Vektors erzwingt.?`!!`
quelle
!!!oldnames
kehrt zurück,c("A", "B")
aber in welche Logik wird dies umgewandeltc("A", "w", "B")
??`!!`
Use `!!!` to add multiple arguments to a function. Its argument should evaluate to a list or vector: args <- list(1:3, na.rm = TRUE) ; quo(mean(!!!args))
. Ich denke, ich werde diese Erklärung der Antwort hinzufügen. Prost auf dasViele Antworten, also habe ich gerade die Funktion geschrieben, damit Sie sie kopieren / einfügen können.
rename <- function(x, old_names, new_names) { stopifnot(length(old_names) == length(new_names)) # pull out the names that are actually in x old_nms <- old_names[old_names %in% names(x)] new_nms <- new_names[old_names %in% names(x)] # call out the column names that don't exist not_nms <- setdiff(old_names, old_nms) if(length(not_nms) > 0) { msg <- paste(paste(not_nms, collapse = ", "), "are not columns in the dataframe, so won't be renamed.") warning(msg) } # rename names(x)[names(x) %in% old_nms] <- new_nms x } x = data.frame(q = 1, w = 2, e = 3) rename(x, c("q", "e"), c("Q", "E")) Q w E 1 1 2 3
quelle
rename(x, c("q", "e"), c("Q", "E"))
scheint nicht mehr in dplyr umbenennen zu funktionieren?Wenn eine Zeile der Daten die Namen enthält, in die Sie alle Spalten ändern möchten, können Sie dies tun
names(data) <- data[row,]
Gegeben
data
ist der Datenrahmen undrow
die Zeilennummer die neuen Werte enthält.Dann können Sie die Zeile mit den Namen mit entfernen
quelle
Dies ist die Funktion, die Sie benötigen: Übergeben Sie dann einfach das x in einer Umbenennung (X) und es werden alle angezeigten Werte umbenannt. Wenn es nicht vorhanden ist, tritt kein Fehler auf
rename <-function(x){ oldNames = c("a","b","c") newNames = c("d","e","f") existing <- match(oldNames,names(x)) names(x)[na.omit(existing)] <- newNames[which(!is.na(existing))] return(x) }
quelle
Es gibt einige Antworten, die die Funktionen erwähnen
dplyr::rename_with
undrlang::set_names
bereits. Durch sie sind getrennt. Diese Antwort zeigt die Unterschiede zwischen den beiden und die Verwendung von Funktionen und Formeln zum Umbenennen von Spalten.rename_with
aus demdplyr
Paket kann entweder eine Funktion oder eine Formel verwenden, um eine Auswahl von Spalten umzubenennen, die als.cols
Argument angegeben sind. Zum Beispiel den Funktionsnamen übergebentoupper
:library(dplyr) rename_with(head(iris), toupper, starts_with("Petal"))
Entspricht der Übergabe der Formel
~ toupper(.x)
:rename_with(head(iris), ~ toupper(.x), starts_with("Petal"))
Wenn Sie alle Spalten umbenennen, können Sie sie auch
set_names
aus dem rlang-Paket verwenden. Um ein anderes Beispiel zu erstellen, verwenden wirpaste0
als Umbenennungsfunktion.pasteO
nimmt 2 Argumente an, daher gibt es verschiedene Möglichkeiten, das zweite Argument zu übergeben, je nachdem, ob wir eine Funktion oder eine Formel verwenden.rlang::set_names(head(iris), paste0, "_hi") rlang::set_names(head(iris), ~ paste0(.x, "_hi"))
Dasselbe kann erreicht
rename_with
werden, indem der Datenrahmen als erstes Argument.data
, die Funktion als zweites Argument.fn
, alle Spalten als drittes Argument.cols=everything()
und die Funktionsparameter als viertes Argument übergeben werden...
. Alternativ können Sie das zweite, dritte und vierte Argument in eine Formel einfügen, die als zweites Argument angegeben wird.rename_with(head(iris), paste0, everything(), "_hi") rename_with(head(iris), ~ paste0(.x, "_hi"))
rename_with
funktioniert nur mit Datenrahmen.set_names
ist allgemeiner und kann auch Vektorumbenennungen durchführenrlang::set_names(1:4, c("a", "b", "c", "d"))
quelle