2014-10-28 3 views
15

UPDATE: Von Kommentar unten auf diesem Beitrag funktioniert das jetzt wie erwartet, ohne die Probleme, die ich hier dargelegt habe.dplyr 'rename' Standard-Evaluierungsfunktion funktioniert nicht wie erwartet?

Unten finden Sie ein Spielzeugbeispiel für die Verwendung von rename_ von dplyr. Ich habe erwartet, dass ich den Spaltennamen wieder in den ursprünglichen Namen ändern kann, indem ich das zweite Beispiel verwende, aber ich vermute, dass die Bewertungsregeln für Funktionsargumente irgendwie verhindern, dass es so funktioniert, wie ich denke. Es gibt eine einfache Umgehung mit dem ursprünglichen plyr-Paket rename Funktion (sowie die Verwendung des Basispakets names Funktion), aber ich habe das Gefühl, dass ich eine dplyr-Lösung zu diesem Thema vermisse.

Ich habe einen Workaround wie unten gezeigt, aber ich würde sowohl eine dplyr-Lösung für das zweite Beispiel, wie ich erwarte, oder eine Erklärung, warum ich nicht erwarten sollte, dass es so funktioniert, wie ich es will.

Danke, Matt

EDIT: Ich habe ein Beispiel unter rename_ mit dieser Arbeit zu machen, aber kompliziert. Ich nehme an, wenn der Fehler, auf den sich Hadley unten bezieht, behoben wird, wird dies funktionieren, wie er unten zeigt. Aber bis dahin ist meine peinliche Art, aber es ist wahrscheinlich besser, die Standardmethode plyr zu verwenden. Zum Beispiel wurde auch die Basis-R-Technik am Ende hinzugefügt, zum Beispiel Vollständigkeit.

library(plyr) 
library(dplyr) 

# dataframe to operate on 
dat <- data_frame(a=1, b=1) 

# identifier with string of column name in dat 
x <- "a" 


# Renaming using standard evaluation this way works 
dat %>% 
    rename_("new" = x) 
# Source: local data frame [1 x 2] 
# 
# new b 
# 1 1 1 


# But changing it back does not 
# I expect "a" to be the name, not the identifier x 
dat %>% 
    rename_("new" = x) %>% 
    rename_(x = "new") 
# Source: local data frame [1 x 2] 
# 
# x b 
# 1 1 1 


# This works, but seems really awkward... 
dat %>% 
    rename_("newname" = x) %>% 
    do(do.call(rename_, setNames(list(., "newname"), c(".data", x)))) 

# Source: local data frame [1 x 2] 
# 
# a b 
# 1 1 1 


# This works fine 
dat %>% 
    rename_("new" = x) %>% 
    plyr::rename(c("new" = x)) 
# Source: local data frame [1 x 2] 
# 
# a b 
# 1 1 1 


# Base R way 
datrn <- dat %>% 
    rename_("newname" = x) 
names(datrn)[names(datrn) == "newname"] = x 
datrn 
# Source: local data frame [1 x 2] 
# 
# a b 
# 1 1 1 
+8

Falls sich jemand wundern sollte, 'rename_ (dat, .dots = setNames (x," neu "))' funktioniert jetzt wie erwartet. – cboettig

+0

Weitere Informationen über diese Art von Sachen gibt es in der dplyr-Vignette auf Nicht-Standard-Bewertung: https://cran.r-project.org/web/packages/dplyr/vignettes/nse.html – RobinL

Antwort

14

Es gibt ein paar, was diese schmerzhaft:

  1. c(x = "new") ist die gleiche wie c("x" = "new"), und nicht das Gegenteil von c(new = x).

  2. können Sie bauen den Vektor Sie mit setNames(x, "new") wollen, aber ...

  3. Ich habe das .dots Argument rename_ (Fehlerbericht bei https://github.com/hadley/dplyr/issues/708) hinzufügen, damit Sie nicht tun können:

    rename_(dat, .dots = setNames(x, "new")) 
    

    Stattdessen müssen Sie verwenden do.call:

    do.call(rename_, c(list(quote(dat)), list(setNames(x, "new")))) 
    
+0

Also, ich versuche es Mach das 'tu.Call' Beispiel Arbeit, und ich bekomme es nicht zur Arbeit. Ich bin mir nicht sicher, wie ich dies ändern könnte, um das 'dat'-Objekt in diesen Aufruf einzubeziehen, da es im Aufruf selbst nicht referenziert wird. – mpettis

+0

Und auf verschiedene Arten, 'setNames' zu versuchen, erhalte ich den folgenden Fehlertyp:' Alle Argumente, die umbenannt werden müssen, müssen benannt werden.FALSE' – mpettis

+0

@mpettis, dass der Anruf von do.call ein bisschen besser sein sollte – hadley

2

In meinem Rstudio definiere ich:

x <- 'myname' 
dat <- data.frame(yes=1, no=2) 

ich den Variablennamen aus ja-myname

Es funktioniert nicht ändern wollen:

rename_(dat, .dots = setNames(x, "yes")) 

Aber das funktioniert:

rename_(dat, .dots = setNames("yes", x)) 

rename_(dat, .dots = setNames("yes", paste(x))) 
Verwandte Themen