2014-09-17 17 views
6

Ho un set di dati lungo con una riga per individuo raggruppato con le scuole. Ogni riga ha un fattore ordinato {1, 2, 3, 4}, "gatti". Voglio ottenere la percentuale di 1, 2, 3 e 4 all'interno di ciascuna scuola. Il set di dati è simile al seguente:dplyr: Conteggi/percentuali di fattori raggruppati per scuola non raggruppati

school_number   cats 
1   10505    3 
2   10505    3 
3   10502    1 
4   10502    1 
5   10502    2 
6   10502    1 
7   10502    1 
8   10502    2 
10   10503    3 
11   10505    2 

Ho provato qualcosa di simile:

df_pcts <- df %>% 
    group_by(school_number) %>% 
    mutate(total=sum(table(cats))) %>% 
    summarize(cat_pct = table(cats)/total) 

ma la variabile totale prodotto dalla fase mutare() mette il numero totale complessivo di righe in ogni riga. Non riesco nemmeno ad arrivare alla fase finale di riepilogo. Non ho capito bene.

P.S. In alcuni altri post ho visto linee come questa:

n = n() 

quando faccio che ricevo un messaggio che dice,

Error in n() : This function should not be called directly 

Da dove viene questo?

TIA

+0

quello di uscita avete bisogno? colonne separate per 1,2,3 gatti o righe separate per ogni combinazione scuola/gatto? – jalapic

+0

Puoi anche usare 'df%>% group_by (school_number, cats)%>% riepilogo (n = n())%>% mutate (pct = 100 * n/sum (n))' – akrun

+0

Puoi digitare solo ' mutate nella vostra sessione e confermate se l'ultima riga dell'output è ''? Se invece l'output è '', questo è esattamente il problema: in qualche modo plyr è stato caricato dopo che dplyr è stato caricato (e il mutato di plyr non presta attenzione a group_by). Questa è una causa comune (sebbene non l'unica) dei problemi di "group_by non funziona". –

risposta

9

Forse questo aiuta un po ', anche se non sono sicuro al 100% di quello di uscita è necessario.

Questo conta il numero di righe di ogni combinazione di school_number/gatti che esistono nella vostra df utilizzando tally. Quindi calcola la percentuale di "gatti" in ogni numero di scuola, quindi raggruppando solo per numero di banco.

df %>% 
    group_by(school_number,cats) %>% 
    tally %>% 
    group_by(school_number) %>% 
    mutate(pct=(100*n)/sum(n)) 

Dà questo:

# school_number cats n  pct 
    # 1   10502 1 4 66.66667 
    # 2   10502 2 2 33.33333 
    # 3   10503 3 1 100.00000 
    # 4   10505 2 1 33.33333 
    # 5   10505 3 2 66.66667 

EDIT:

di aggiungere in righe con 0% che mancano dai dati di esempio, si potrebbe fare quanto segue. Associa l'output sopra con un df che contiene lo 0% per tutte le combinazioni school_number/cats. Conserva solo la prima istanza di questo bind (le prime istanze contengono sempre valori> 0% se esistono). Ho poi organizzato dal school_number e gatti per facilitare la lettura:

y<-df %>% 
    group_by(school_number,cats) %>% 
    tally %>% 
    group_by(school_number) %>% 
    mutate(pct=(100*n)/sum(n)) %>% 
    select(-n) 

x<-data.frame(school_number=rep(unique(df$school_number),each=4), cats=1:4,pct=0) 

rbind(y,x) %>% 
    group_by(school_number,cats)%>% 
    filter(row_number() == 1) %>% 
    arrange(school_number,cats) 

che dà:

# school_number cats  pct 
#1   10502 1 66.66667 
#2   10502 2 33.33333 
#3   10502 3 0.00000 
#4   10502 4 0.00000 
#5   10503 1 0.00000 
#6   10503 2 0.00000 
#7   10503 3 100.00000 
#8   10503 4 0.00000 
#9   10505 1 0.00000 
#10   10505 2 33.33333 
#11   10505 3 66.66667 
#12   10505 4 0.00000 
0

Tutti combinazione di scuola numero e gatti poi a sinistra si uniscono al fine di calcolare per cento. Se poi NA 0

expand.grid(school_number = unique(df$school_number), cats = levels(df$cats)) %>% 
    left_join(df %>% 
       group_by(school_number, cats) %>% 
       tally %>% 
       mutate(pct = (n/sum(n) * 100))) %>% 
    select(-n) %>% 
    mutate(pct = ifelse(is.na(pct), 0, pct)) %>% 
    arrange(school_number) 

che dà

school_number cats  pct 
1   10502 1 66.66667 
2   10502 2 33.33333 
3   10502 3 0.00000 
4   10502 4 0.00000 
5   10503 1 0.00000 
6   10503 2 0.00000 
7   10503 3 100.00000 
8   10503 4 0.00000 
9   10505 1 0.00000 
10   10505 2 33.33333 
11   10505 3 66.66667 
12   10505 4 0.00000 
+1

Mentre questo frammento di codice può risolvere la domanda, [inclusa una spiegazione] (http: // meta. stackexchange.com/questions/114762/explaining-entirely-code-based-answers) aiuta davvero a migliorare la qualità del tuo post. Ricorda che stai rispondendo alla domanda per i lettori in futuro, e queste persone potrebbero non conoscere le ragioni del tuo suggerimento sul codice. –

Problemi correlati