2014-11-15 8 views
6

Ho un dataframe che assomiglia a questo:GROUP BY e la scala/normalizzare una colonna in r

Store Temperature Unemployment Sum_Sales 
1  1  42.31  8.106 1643691 
2  1  38.51  8.106 1641957 
3  1  39.93  8.106 1611968 
4  1  46.63  8.106 1409728 
5  1  46.50  8.106 1554807 
6  1  57.79  8.106 1439542 

Quello che non riesco a capire in R è come gruppo da e applicare. Quindi, per ogni negozio (raggruppato), voglio normalizzare/ridimensionare due colonne (somma_vendita e temperatura).

output desiderato che voglio è il seguente:

Store Temperature Unemployment Sum_Sales 
1  1  1.000  8.106 1.00000 
2  1  0.000  8.106 0.94533 
3  1  0.374  8.106 0.00000 
4  2  0.012  8.106 0.00000 
5  2  0.000  8.106 1.00000 
6  2  1.000  8.106 0.20550 

Ecco la funzione di normalizzazione che ho creato:

normalit<-function(m){ 
    (m - min(m))/(max(m)-min(m)) 
} 

sto usando il pacchetto DPLY e non riesco a capire come raggruppare e applicare tale funzione a una colonna. Ho provato qualcosa di simile e ho ricevuto un errore:

df2 <- df %.% 
    group_by('Store') %.% 
    summarise(Temperature = normalit(Temperature), Sum_Sales = normalit(Sum_Sales))) 

Qualsiasi suggerimento/aiuto sarebbe molto apprezzato. Grazie.

+0

Hai una colonna 'disoccupazione' nel risultato. È lo stesso per ogni negozio> – jlhoward

+0

sì .. mi dispiace per non aver specificato – itjcms18

risposta

9

Il problema è che si sta utilizzando il verbo dplyr errato. Riepiloga creerà un risultato per gruppo per variabile. Quello che vuoi è mutare. Mutare cambia le variabili e restituisce un risultato della stessa lunghezza dell'originale. Vedi http://cran.rstudio.com/web/packages/dplyr/vignettes/introduction.html. Sotto due approcci utilizzando dplyr:

df %>% 
    group_by(Store) %>% 
    mutate(Temperature = normalit(Temperature), Sum_Sales = normalit(Sum_Sales)) 

df %>% 
    group_by(Store) %>% 
    mutate_each(funs(normalit), Temperature, Sum_Sales) 

Nota: la variabile Store è diversa tra i dati e il risultato desiderato. Ho pensato che @jlhoward avesse i dati giusti.

+0

Ricevo un errore "impossibile trovare la funzione normalit", c'è qualche pacchetto che devo installare per questo? @Vincent –

+2

Vedere la funzione di normalizzazione OP – Vincent

2

Ecco una soluzione data.table. Ho cambiato un po 'il tuo esempio per avere due tipi di negozi.

df <- read.table(header=T,text="Store Temperature Unemployment Sum_Sales 
1  1  42.31  8.106 1643691 
2  1  38.51  8.106 1641957 
3  1  39.93  8.106 1611968 
4  2  46.63  8.106 1409728 
5  2  46.50  8.106 1554807 
6  2  57.79  8.106 1439542") 

library(data.table) 
DT <- as.data.table(df) 
DT[,list(Temperature=normalit(Temperature),Sum_Sales=normalit(Sum_Sales)), 
    by=list(Store,Unemployment)] 
# Store Unemployment Temperature Sum_Sales 
# 1:  1  8.106 1.00000000 1.0000000 
# 2:  1  8.106 0.00000000 0.9453393 
# 3:  1  8.106 0.37368421 0.0000000 
# 4:  2  8.106 0.01151461 0.0000000 
# 5:  2  8.106 0.00000000 1.0000000 
# 6:  2  8.106 1.00000000 0.2055018 

Si noti che la normalizzazione avrà problemi se c'è solo una riga per uno stoer.

+0

Nice solution @jlhoward. Presumo che la disoccupazione è aggiunta alla lista in modo da non farla cadere. Solo per curiosità, come manteresti la disoccupazione se non fosse costante in ogni negozio e ottenessi comunque il risultato desiderato? – Vincent

+0

OP desidera 1 riga per archivio. Se la disoccupazione non è costante per un determinato negozio, quale valore useresti? – jlhoward

+0

Mi chiedevo solo se ci sono tre righe per archivio (come nell'output desiderato di OP), come manteresti Disoccupazione se non attraverso by = list(). – Vincent