2014-10-28 13 views
15

AKTUALIZACJA: Od komentarza znajdującego się poniżej tego wpisu, teraz działa on zgodnie z oczekiwaniami, bez problemów, które tu przedstawiłem.Standardowa funkcja oceny dplyr 'rename' nie działa zgodnie z oczekiwaniami?

Poniżej znajduje się zabawny przykład użycia rename_ z dplyr. Spodziewałem się, że będę mógł zmienić nazwę kolumny z powrotem na jej oryginalną nazwę, używając drugiego przykładu poniżej, ale domyślam się, że zasady oceny argumentów funkcji uniemożliwiają jej działanie w sposób, w jaki myślę. Istnieje proste obejście, używając oryginalnej funkcji pakietu plyr rename (jak również przy użyciu funkcji podstawowej pakietu names), ale mam wrażenie, że brakuje mi rozwiązania dplyr.

Mam obejście, jak pokazano poniżej, ale z zadowoleniem przyjmuję zarówno rozwiązanie dplyr do drugiego przykładu działającego zgodnie z oczekiwaniami, jak i wyjaśnienie, dlaczego nie powinienem oczekiwać, że będzie działać tak, jak chcę.

Dziękuję Matt

EDIT: dodałem przykład poniżej używając rename_ do tej pracy, ale jest skomplikowana. Zakładam, że jeśli błąd, o którym wspomniał Hadley poniżej, zostanie rozwiązany, to zadziała, jak pokazuje poniżej. Ale do tego czasu mój dziwny sposób ma, ale prawdopodobnie lepiej jest użyć standardowej metody plyr. Dodatkowo dodano na końcu technikę R, na przykład kompletność.

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

Jeśli ktoś się zastanawia, 'rename_ (dat, .dots = setNames (x," new "))' teraz działa zgodnie z oczekiwaniami. – cboettig

+0

Więcej informacji na ten temat można znaleźć w winietce dplyr na temat niestandardowej oceny: https://cran.r-project.org/web/packages/dplyr/vignettes/nse.html – RobinL

Odpowiedz

14

Istnieje kilka rzeczy, które czynią ten bolesny:

  1. c(x = "new") jest taka sama jak c("x" = "new"), a nie odwrotnie od c(new = x).

  2. Można skonstruować wektor chcesz z setNames(x, "new"), Ale ...

  3. zapomniałem dodać .dots argument rename_ (raport o błędzie w https://github.com/hadley/dplyr/issues/708), więc nie można zrobić:

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

    Zamiast tego trzeba użyć do.call:

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

Próbuję więc spraw, aby 'zrobić.zadzwoń do przykładu i nie pracuję. Nie wiem, jak to zmienić, aby włączyć obiekt 'dat' do tego wywołania, ponieważ nie jest on przywoływany w samym wywołaniu. – mpettis

+0

I na różne sposoby wypróbowania 'setNames', otrzymuję następujący typ błędu:' Wszystkie argumenty do zmiany nazwy muszą być nazwane. FALSE' – mpettis

+0

@mpettis że wywołanie do.call powinno być nieco lepsze – hadley

2

W moim Rstudio, zdefiniować:

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

Chcę zmienić nazwę zmiennej z tak do myname

To nie działa:

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

Ale to działa:

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

rename_(dat, .dots = setNames("yes", paste(x))) 
Powiązane problemy