2015-08-03 14 views
11

Ho un dataframe con la struttura del pannello: 2 osservazioni per ogni unità da due anni:Come controllare i nomi di nuove variabili dopo la diffusione di tidyr?

library(tidyr) 
mydf <- data.frame(
    id = rep(1:3, rep(2,3)), 
    year = rep(c(2012, 2013), 3), 
    value = runif(6) 
) 
mydf 
# id year  value 
#1 1 2012 0.09668064 
#2 1 2013 0.62739399 
#3 2 2012 0.45618433 
#4 2 2013 0.60347152 
#5 3 2012 0.84537624 
#6 3 2013 0.33466030 

vorrei ridisegnare questi dati a grande formato che può essere fatto facilmente con tidyr::spread. Tuttavia, poiché i valori della variabile year sono numeri, anche i nomi delle mie nuove variabili diventano numeri che ne rendono più difficile l'ulteriore utilizzo.

spread(mydf, year, value) 
# id  2012  2013 
#1 1 0.09668064 0.6273940 
#2 2 0.45618433 0.6034715 
#3 3 0.84537624 0.3346603 

So che posso facilmente rinominare le colonne. Tuttavia, se mi piacerebbe rimodellare in una catena con altre operazioni, diventa scomodo. Per esempio. la seguente riga ovviamente non ha senso.

library(dplyr) 
mydf %>% spread(year, value) %>% filter(2012 > 0.5) 

I seguenti lavori, ma non è che concisa:

tmp <- spread(mydf, year, value) 
names(tmp) <- c("id", "y2012", "y2013") 
filter(tmp, y2012 > 0.5) 

Qualsiasi idea di come posso cambiare i nuovi nomi di variabile all'interno spread?

risposta

11

È possibile utilizzare backticks per i nomi delle colonne che iniziano con i numeri e filter dovrebbe funzionare come previsto

mydf %>% 
     spread(year, value) %>% 
     filter(`2012` > 0.5) 
    # id  2012  2013 
    #1 3 0.8453762 0.3346603 

o un'altra opzione sarebbe utilizzando unite per unire due colonne a un singolo columnn dopo la creazione di una seconda colonna 'year1' con la stringa 'y'.

mydf %>% 
    mutate(year1='y') %>% 
    unite(yearN, year1, year) %>% 
    spread(yearN, value) %>% 
    filter(y_2012 > 0.5) 
# id y_2012 y_2013 
#1 3 0.8453762 0.3346603 

anche noi possiamo cambiare la colonna 'anno' all'interno mutate utilizzando paste

mydf %>% 
    mutate(year=paste('y', year, sep="_")) %>% 
    spread(year, value) %>% 
    filter(y_2012 > 0.5) 
2

Un'altra opzione è quella di utilizzare la funzione setNames() come la prossima cosa nel tubo:

mydf %>% 
    spread(mydf, year, value) %>% 
    setNames(c("id", "y2012", "y2013")) %>% 
    filter(y2012 > 0.5) 

L'unico problema con setNames è che devi sapere esattamente quali saranno le tue colonne quando li fai spread(). Il più delle volte, non è un problema, soprattutto se lavori in modo semi-interattivo.

Ma se si manca una coppia chiave/valore nei dati originali, c'è la possibilità che non si visualizzi come una colonna e si può finire per denominare le colonne in modo errato senza nemmeno saperlo. Certo, setNames() genera un errore se il numero di nomi non corrisponde al numero di colonne, quindi hai un po 'di controllo degli errori integrato.

Eppure, la comodità di usare setNames() ha superato il rischio di più spesso che no per me.

Problemi correlati