2015-04-29 10 views
6

Desidero aggiungere un suffisso o prefisso alla maggior parte dei nomi delle variabili in un data.frame, in genere dopo che sono stati tutti trasformati in qualche modo e prima dell'esecuzione unirsi. Non ho un modo per farlo senza rompere le mie corde.Aggiunta del prefisso o del suffisso alla maggior parte dei nomi delle variabili data.frame nel flusso di lavoro R spogliato

Ad esempio, con questi dati:

library(dplyr) 
set.seed(1) 
dat14 <- data.frame(ID = 1:10, speed = runif(10), power = rpois(10, 1), 
        force = rexp(10), class = rep(c("a", "b"),5)) 

Voglio arrivare a questo risultato (nota nomi delle variabili):

class speed_mean_2014 power_mean_2014 force_mean_2014 
1  a  0.5572500    0.8  0.5519802 
2  b  0.2850798    0.6  1.0888116 

mio approccio attuale è:

means14 <- dat14 %>% 
    group_by(class) %>% 
    select(-ID) %>% 
    summarise_each(funs(mean(.))) 

names(means14)[2:length(names(means14))] <- paste0(names(means14)[2:length(names(means14))], "_mean_2014") 

C'è un'alternativa a quella goffa ultima linea che rompe le mie pipe? Ho guardato a select() e rename() ma non voglio specificare esplicitamente ciascun nome di variabile, poiché di solito voglio rinominare tutto eccetto una singola variabile e potrebbe avere un data.frame molto più ampio rispetto a questo esempio.

sto immaginando comando pipe finale che approssima la funzione truccata:

appendname(cols = 2:n, str = "_mean_2014", placement = "suffix") 

che non esiste per quanto ne so.

risposta

4

Dopo ulteriore sperimentazione dal distacco a questa domanda, ho trovato che la funzione setNames lavorerà con le tubazioni in quanto restituisce un data.frame:

dat14 %>% 
    group_by(class) %>% 
    select(-ID) %>% 
    summarise_each(funs(mean(.))) %>% 
    setNames(c(names(.)[1], paste0(names(.)[-1],"_mean_2014"))) 

    class speed_mean_2014 power_mean_2014 force_mean_2014 
1  a  0.5572500    0.8  0.5519802 
2  b  0.2850798    0.6  1.0888116 
3

Questo è un po 'più veloce, ma non del tutto ciò che si vuole:

dat14 %>% 
    group_by(class) %>% 
    select(-ID) %>% 
    summarise_each(funs(mean(.))) -> means14 

names(means14)[-1] %<>% paste0("_mean_2014") 

se non è stato utilizzato il% <>% - operatore di prima sicuramente controllare questo link out, la sua uno strumento super-utile .

si può usare anche per ricalcolare o arrotondamento alcune colonne, in questo modo df$meancolumn %<>% round(), e così via, si tratta solo molto spesso e solo consente di risparmiare un sacco di scrittura

+0

piacevole uso di '% <>%' e grazie per aver postato il link, sempre buono da rileggere come aggiornamento – infominer

+1

grazie, mi sono totalmente innamorato dell'operatore '% <>%', è proprio così utile, poiché tali compiti vengono visualizzati così spesso, è possibile utilizzarli anche per ricalcolare o arrotondare alcune colonne, come questo 'df $ meancolumn% <>% round()', e così via, viene visualizzato molto spesso e ti fa risparmiare un sacco di scrittura – grrgrrbla

+0

Sicuramente un miglioramento, grazie. Io uso '% <>%' spesso per sostituire 'df <- df %>% ...' ma non mi è mai venuto in mente di usarlo per altri tipi di dati come i vettori. Il tuo esempio con 'round()' è abbastanza conciso! –

0

questo è più di un passo indietro, ma si potrebbe pensare a rimodellare i vostri dati al fine di applicare la funzione a più anni allo stesso tempo. Ciò conserverà l'ordine. Se vuoi finire per confrontare diversi anni, potrebbe aver senso che l'anno sia una variabile separata in un dataframe, piuttosto che archiviare l'anno nei nomi. Dovresti essere in grado di usare sumarise_ per ottenere il comportamento mean_year. Vedere http://cran.r-project.org/web/packages/dplyr/vignettes/nse.html

library(dplyr) 
library(tidyr) 
set.seed(1) 
dat14 <- data.frame(ID = 1:10, speed = runif(10), power = rpois(10, 1), 
        force = rexp(10), class = rep(c("a", "b"),5)) 

dat14 %>% 
    gather(variable, value, -ID, -class) %>% 
    mutate(year = 2014) %>% 
    group_by(class, year, variable)%>% 
    summarise(mean = mean(value))` 
0

Mentre soluzione Sam Firkes utilizza setNames() ist certamente l'unica soluzione mantenendo un tubo ininterrotta, non funzionerà con i tbl oggetti da dplyr, dal momento che i nomi delle colonne non sono accessibili con i metodi della solita base di R funzioni di denominazione. Ecco una funzione che puoi usare all'interno di una pipe con gli oggetti tbl, grazie alla soluzione this di hrbrmstr. Aggiunge prefissi e suffissi predefiniti agli indici delle colonne specificati. L'impostazione predefinita è tutte le colonne.

tbl.renamer <- function(tbl,prefix="x",suffix=NULL,index=seq_along(tbl_vars(tbl))){ 
    newnames <- tbl_vars(tbl) # Get old variable names 
    names(newnames) <- newnames 
    names(newnames)[index] <- paste0(prefix,".",newnames,suffix)[index] # create a named vector for .dots 
    rename_(tbl,.dots=newnames) # rename the variables 
} 

Esempio di utilizzo (Supponiamo auth_users beeing un oggetto tbl_sql):

auth_user %>% tbl_vars 
tbl.renamer(auth_user) %>% tbl_vars 
auth_user %>% tbl.renamer %>% tbl_vars 
auth_user %>% tbl.renamer(index = c(1,5)) %>% tbl_vars 
3

A partire dal febbraio 2017 si può fare questo con il comando dplyr rename_(...).

Nel caso di questo esempio si potrebbe fare.

dat14 %>% 
    group_by(class) %>% 
    select(-ID) %>% 
    summarise_each(funs(mean(.))) %>% 
    rename_(names(.)[-1], paste0(names(.)[-1],"_mean_2014"))) 

Questo è abbastanza simile alla risposta con set_names ma funziona con Tibbles troppo!

Problemi correlati