2014-10-28 2 views
15

AGGIORNAMENTO: dal commento sottostante su questo post, questo funziona ora come previsto, senza i problemi che ho esposto qui.dplyr 'rinomina' la funzione di valutazione standard non funziona come previsto?

Di seguito è riportato un esempio di utilizzo di rename_ da dplyr. Mi aspettavo di essere in grado di riportare il nome della colonna al suo nome originale usando il secondo esempio qui sotto, ma suppongo che le regole di valutazione degli argomenti delle funzioni in qualche modo gli impediscano di funzionare nel modo in cui penso. C'è una soluzione semplice che utilizza la funzione plyr originale rename (oltre a utilizzare la funzione base pacchetto names), ma ho la sensazione che mi manchi una soluzione dplyr per questo.

Ho una soluzione alternativa, come illustrato di seguito, ma accetterei sia una soluzione dplyr per il secondo esempio che funziona come previsto, sia una spiegazione del motivo per cui non dovrei aspettarmi che funzioni nel modo in cui lo desidero.

Grazie, Matt

EDIT: Ho aggiunto un esempio di seguito utilizzando rename_ per fare questo lavoro, ma è complicato. Presumo che se il bug che Hadley si riferisce a quanto sotto verrà corretto, funzionerà come mostrato di seguito. Ma fino ad allora, il mio modo imbarazzante lo fa, ma probabilmente è meglio usare il metodo standard plyr. Aggiunta anche la tecnica di base R alla fine, ad esempio la completezza.

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

Nel caso qualcuno si stia chiedendo, 'rename_ (dat, .dots = setNames (x," new "))' ora funziona come previsto. – cboettig

+0

Ulteriori informazioni su questo genere di cose sono disponibili nella vignetta dplyr su una valutazione non standard: https://cran.r-project.org/web/packages/dplyr/vignettes/nse.html – RobinL

risposta

14

Ci sono una cosa pochi che rendono questa dolorosa:

  1. c(x = "new") è lo stesso di c("x" = "new"), e non il contrario di c(new = x).

  2. È possibile costruire il vettore che si desidera con setNames(x, "new"), ma ...

  3. Ho dimenticato di aggiungere la (bug report a https://github.com/hadley/dplyr/issues/708) .dots argomento di rename_ quindi non si può fare:

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

    Invece è necessario utilizzare do.call:

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

Quindi, sto provando a fai il 'do.call' esempio di lavoro, e non riesco a farlo funzionare. Non sei sicuro di come cambiarlo per incorporare l'oggetto 'dat' in quella chiamata, poiché non è referenziato nella chiamata stessa. – mpettis

+0

E, in vari modi di provare 'setNames', sto ottenendo il seguente tipo di errore:' Tutti gli argomenti da rinominare devono essere denominati.FALSE' – mpettis

+0

@mpettis che invocazione di call.t dovrebbe essere un po 'meglio – hadley

2

Nel mio Rstudio, definisco:

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

voglio cambiare il nome della variabile da -mionome

Non funziona:

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

Ma questo funziona: