Ersatz für "Umbenennen" in dplyr

118

Ich mag die Umbenennungsfunktion von Plyr rename. Ich habe vor kurzem angefangen, dplyr zu verwenden, und habe mich gefragt, ob es eine einfache Möglichkeit gibt, Variablen mit einer Funktion von dplyr umzubenennen, die genauso einfach zu verwenden ist wie die von plyr rename?

vergilcw
quelle

Antworten:

148

dplyr Version 0.3 hat eine neue rename()Funktion hinzugefügt , die genauso funktioniert plyr::rename().

df <- rename(df, new_name = old_name)
aaronwolen
quelle
7
Könnten Sie die Syntax erklären? Das ist wichtiger als der Befehl. Ich benutze, rename(TheDataFrame,OldVarName=NewVarName)aber ich bekomme Error: Unknown variables: NewVarName.und ich verstehe nicht warum.
s_a
2
@s_a Ich habe die Klarstellung hinzugefügt. Es sollte nach Überprüfung angezeigt werden.
Ryan
4
Wenn Sie Probleme haben, hilft es möglicherweise, das Paket explizit anzugeben dplyr::rename(iris, petal_length = Petal.Length).
Boern
2
Zwei kurze Beobachtungen: Der obige Befehl muss dem Datenrahmen zugewiesen werden, damit er wirksam wird, iris <- dplyr::rename(iris, petal_length = Petal.Length)und rename () behandelt keine Variablennamen mit Leerzeichen. Dies führt beispielsweise zu dplyr::rename(iris, petal_length = "petal length")einem Fehler.
Anthony Simon Mielniczuk
2
Sie können verwenden, setNames()wenn Sie die Spaltennamen Großhandel ersetzen:df %>% mutate(foo = 1 +2) %>% setNames(c("blah", "blu", "bar"))
crazybilly
46

Die nächste Version von dplyr unterstützt eine verbesserte Version von select, die auch das Umbenennen beinhaltet:

> mtcars2 <- select( mtcars, disp2 = disp )
> head( mtcars2 )
                  disp2
Mazda RX4         160
Mazda RX4 Wag     160
Datsun 710        108
Hornet 4 Drive    258
Hornet Sportabout 360
Valiant           225
> changes( mtcars, mtcars2 )
Changed variables:
      old         new
disp  0x105500400
disp2             0x105500400

Changed attributes:
      old         new
names 0x106d2cf50 0x106d28a98
Romain Francois
quelle
2
Zu changes
Ihrer Information
2
Nett. Das Einzige ist, dass dies eine Änderung des Denkens des Benutzers bedeutet, da plyrdie Umbenennungsfunktion verwendet, "old"="new"während dplyrVerwendungen verwendet werden, new=olddie sie mit den übrigen dplyr-Funktionen konsistent halten. Persönlich halte ich das nicht für ein Problem - Sie gewöhnen sich schnell an neue Dinge, insbesondere wenn dies eine erhebliche Beschleunigung Ihrer Datenverarbeitung bedeutet.
vergilcw
3
Dies ist das beabsichtigte Merkmal, daher die Wahl des Verbs select. Wir sind uns nicht sicher, ob wir etwas haben, das besagt, alle Variablen auswählen und diese Spalte übrigens umbenennen.
Romain Francois
1
Könnten Sie Ihren Beitrag möglicherweise so bearbeiten, dass der Code das selecttatsächliche Verhalten widerspiegelt, um Verwirrung zu vermeiden ? Ich würde für eine einfache dplyrMöglichkeit stimmen , alle Variablen beizubehalten und nur eine oder zwei umzubenennen. :) Im Moment werde ich weiter laden plyrund verwenden rename.
vergilcw
2
@RomainFrancois @aaronwolen Mit dem OP können Sie erreichen, was Sie wollen mtcars %>% select(matches(".*"),disp2=disp). Ich würde eine sparsamere Lösung lieben, aber dies funktioniert und bewahrt alle Spalten (wenn auch nicht ihre Reihenfolge). dispwird nicht dupliziert.
Farnsy
27

Sie können tatsächlich plyr's verwendenrename Funktion als Teil der dplyrKetten. Ich denke, jede Funktion, die a) a data.frameals erstes Argument nimmt und b) ein data.frameWerk zur Verkettung zurückgibt . Hier ist ein Beispiel:

library('plyr')
library('dplyr')

DF = data.frame(var=1:5)

DF %>%
    # `rename` from `plyr`
    rename(c('var'='x')) %>%
    # `mutate` from `dplyr` (note order in which libraries are loaded)
    mutate(x.sq=x^2)

#   x x.sq
# 1 1    1
# 2 2    4
# 3 3    9
# 4 4   16
# 5 5   25

UPDATE: Die aktuelle Version von dplyrunterstützt das direkte Umbenennen als Teil der selectFunktion (siehe Beitrag von Romain Francois oben). Die allgemeine Aussage über die Verwendung von Nicht-Dplyr-Funktionen als Teil von dplyrKetten ist jedoch weiterhin gültigrename ein interessantes Beispiel.

user2503795
quelle
5
In diesem Fall ist es am besten, dplyr nach plyr zu laden . Auf diese Weise werden die schnelleren dplyr-Funktionen verwendet, sofern verfügbar, und Sie können mutate anstelle von dplyr :: mutate verwenden
Vincent
Sieht so aus, als hätten Sie Recht, wenn Sie in der Verkettung Nicht-Dplyr-Funktionen verwenden können. mtcars%.% umbenennen (c ("mpg", "cyl"), c ("mympg", "mycyl")) funktioniert, wenn Umbenennen die in meiner Antwort definierte Funktion ist.
Vincent
Ich habe die Ladereihenfolge von dplyr und plyr geändert, danke.
user2503795
Dies ist eine anständige Problemumgehung, bringt jedoch eine interessante Diskussion über die Leistung bei größeren Datenmengen hervor, was einer der Hauptvorteile von dplyr ist. Danke für den Vorschlag!
vergilcw
Umbenennen funktioniert durch Referenz wie Setnamen aus dem Paket
data.table
9

Es ist (noch) nicht als Funktion in dplyr aufgeführt: http://cran.rstudio.org/web/packages/dplyr/dplyr.pdf

Die folgende Funktion funktioniert (fast) gleich, wenn Sie nicht sowohl plyr als auch dplyr laden möchten

rename <- function(dat, oldnames, newnames) {
  datnames <- colnames(dat)
  datnames[which(datnames %in% oldnames)] <- newnames
  colnames(dat) <- datnames
  dat
}

dat <- rename(mtcars,c("mpg","cyl"), c("mympg","mycyl"))
head(dat)

                  mympg mycyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4          21.0     6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag      21.0     6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710         22.8     4  108  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive     21.4     6  258 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout  18.7     8  360 175 3.15 3.440 17.02  0  0    3    2
Valiant            18.1     6  225 105 2.76 3.460 20.22  1  0    3    1

Bearbeiten: Der Kommentar von Romain erzeugt Folgendes (beachten Sie, dass die Änderungsfunktion dplyr .1.1 erfordert)

> dplyr:::changes(mtcars, dat)
Changed variables:
          old         new        
disp      0x108b4b0e0 0x108b4e370
hp        0x108b4b210 0x108b4e4a0
drat      0x108b4b340 0x108b4e5d0
wt        0x108b4b470 0x108b4e700
qsec      0x108b4b5a0 0x108b4e830
vs        0x108b4b6d0 0x108b4e960
am        0x108b4b800 0x108b4ea90
gear      0x108b4b930 0x108b4ebc0
carb      0x108b4ba60 0x108b4ecf0
mpg       0x1033ee7c0            
cyl       0x10331d3d0            
mympg                 0x108b4e110
mycyl                 0x108b4e240

Changed attributes:
          old         new        
names     0x10c100558 0x10c2ea3f0
row.names 0x108b4bb90 0x108b4ee20
class     0x103bd8988 0x103bd8f58
Vincent
quelle
3
Das einzige Problem hierbei ist, dass Daten kopiert werden. Keine große Sache, wenn dies zum Spielen mtcarsgedacht ist, dh usw. ... aber ziemlich dramatisch, wenn Sie mit umfangreichen Daten arbeiten. Scheckdplyr:::changes(mtcars, dat)
Romain Francois
1
Danke für den Kommentar Romain. Gibt es einen Grund, warum Änderungen nicht aus dplyr exportiert werden? Scheint eine ziemlich nützliche Funktion zu sein.
Vincent
1
Ich denke, Hadley sieht es meistens als Entwicklungswerkzeug für uns.
Romain Francois
1
Es sollte definitiv exportiert werden. Ich habe vielleicht gerade vergessen
Hadley
2

dplyr::select_all()Kann nicht genau umbenannt werden, kann jedoch zum Neuformatieren von Spaltennamen verwendet werden. In diesem Beispiel werden Leerzeichen und Punkte durch einen Unterstrich ersetzt und alles in Kleinbuchstaben umgewandelt:

iris %>%  
  select_all(~gsub("\\s+|\\.", "_", .)) %>% 
  select_all(tolower) %>% 
  head(2)
  sepal_length sepal_width petal_length petal_width species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
sbha
quelle
1

Ich habe versucht, dplyr :: rename zu verwenden und erhalte eine Fehlermeldung:

occ_5d <- dplyr::rename(occ_5d, rowname='code_5d')
Error: Unknown column `code_5d` 
Call `rlang::last_error()` to see a backtrace

Ich habe stattdessen die Basis-R-Funktion verwendet, die sich als recht einfach und effektiv herausstellt:

names(occ_5d)[1] = "code_5d"
Adams
quelle