2015-04-01 18 views
8

I miei dati sono osservazioni ordinate e voglio mantenere l'ordinamento il più possibile mentre faccio le manipolazioni.Ordinamento implicito in tidyr :: spread e dplyr :: riepilogo

Prendere la risposta per this question, ho messo "B" davanti a "A" nel dataframe. I dati ampi risultanti sono ordinati per la colonna "nome", cioè "A" prima, quindi "B".

df = data.frame(name=c("B","B","A","A"), 
       group=c("g1","g2","g1","g2"), 
       V1=c(10,40,20,30), 
       V2=c(6,3,1,7)) 

gather(df, Var, Val, V1:V2) %>% 
unite(VarG, Var, group) %>% 
spread(VarG, Val) 

    name V1_g1 V1_g2 V2_g1 V2_g2 
1 A 20 30  1  7 
2 B 10 40  6  3 

C'è un modo per mantenere l'ordinamento originale? in questo modo:

name V1_g1 V1_g2 V2_g1 V2_g2 
1 B 10 40  6  3 
2 A 20 30  1  7 

04/02 edit: ho appena trovato il dplyr::summarise fa l'ordinamento pure. arrange(name, df$name) funziona ancora per ripristinare l'ordine. Ma mi chiedo se lo smistamento extra è necessario dal design dei pacchetti?

df %>% 
    group_by(name) %>% 
    summarise(n()) %>% 

    name n() 
1 A 2 
2 B 2 
+0

interessanti. Sembra che durante la fase di diffusione, anche i livelli dei fattori per la variabile "nome" vengano modificati .... – A5C1D2H2I1M1N2O1R2T1

risposta

7

È possibile ordinare per nome in base all'ordine nella cornice dati originali:

gather(df, Var, Val, V1:V2) %>% 
    unite(VarG, Var, group) %>% 
    spread(VarG, Val) %>% 
    arrange(order(match(name, df$name))) 

# name V1_g1 V1_g2 V2_g1 V2_g2 
# 1 B 10 40  6  3 
# 2 A 20 30  1  7 
+1

Grazie. 'arrangement (match (name, df $ name)' funziona anche, ma come trattare con più livelli di raggruppamento, ad esempio "name", "name1", "name2". Non ha senso per me che 'spread' includa l'ordinamento – Dong

+0

Hai ragione sul non aver bisogno di ordine. Per quanto riguarda i livelli, puoi usare più argomenti in "organizza (a, b, c ...)" e puoi ordinare come preferisci (forse non riesco a vedere il problema), ma capisco il tuo dolore come se avessi già tutto ordinato ... – bergant

+0

@bergant, per me il problema più grande a parte l'ordinamento è che i livelli dei fattori sono stati modificati – A5C1D2H2I1M1N2O1R2T1

3

L'ordine viene preso dall'ordine dei livelli di fattore.

str(df) 
'data.frame': 4 obs. of 4 variables: 
$ name : Factor w/ 2 levels "A","B": 2 2 1 1 
$ group: Factor w/ 2 levels "g1","g2": 1 2 1 2 
$ V1 : num 10 40 20 30 
$ V2 : num 6 3 1 7 

Verificare che i livelli siano "A", "B".

Quindi, se si imposta l'ordine dei livelli per l'ordine in cui sono mostrati in esso funzionerà:

df = data.frame(name=c("B","B","A","A"), 
       group=c("g1","g2","g1","g2"), 
       V1=c(10,40,20,30), 
       V2=c(6,3,1,7)) 

df %>% 
    mutate(name = factor(name,levels=unique(name))) %>% 
    mutate(group = factor(group,levels=unique(group))) %>% 
    gather(Var, Val, V1:V2) %>% 
    unite(VarG, Var, group) %>% 
    spread(VarG, Val) 

Risultati in:

name V1_g1 V1_g2 V2_g1 V2_g2 
1 B 10 40  6  3 
2 A 20 30  1  7