2016-05-26 9 views
6

ho un esempio minimo di un insieme di dati D che sembra qualcosa di simile:R: Produrre tabella di frequenza selezionando alcune righe

score person freq 
    10  1 3 
    10  2 5 
    10  3 4 
    8  1 3 
    7  2 2 
    6  4 1 

Ora, voglio essere in grado di tracciare la frequenza del punteggio = 10 contro persona .

Tuttavia, se faccio:

#My bad, turns out the next line only works for matrices anyway: 
#D = D[which(D[,1] == 10)] 

D = subset(D, score == 10) 

allora ottengo:

score person freq 
    10  1 3 
    10  2 5 
    10  3 4 

Tuttavia, questo è quello che avrei desidera ottenere:

score person freq 
    10  1 3 
    10  2 5 
    10  3 4 
    10  4 0 

C'è Qualunque modo veloce e indolore per farmi questo in R?

risposta

4

È possibile utilizzare complete() dal pacchetto tidyr per creare le righe mancanti e quindi si può semplicemente sottoinsieme:

library(tidyr) 
D2 <- complete(D, score, person, fill = list(freq = 0)) 
D2[D2$score == 10, ] 
## Source: local data frame [4 x 3] 
## 
## score person freq 
## (int) (int) (dbl) 
## 1 10  1  3 
## 2 10  2  5 
## 3 10  3  4 
## 4 10  4  0 

complete() prende come primo argomento il frame di dati che dovrebbe funzionare con. Quindi seguire i nomi delle colonne che dovrebbero essere completate. L'argomento fill è un elenco che fornisce per ciascuna delle colonne rimanenti (che è solo freq qui) il valore con cui devono essere riempiti.

Come suggerito da docendo-discimus, questo può essere ulteriormente semplificato utilizzando anche il pacchetto dplyr come segue:

library(tidyr) 
library(dplyr) 
complete(D, score, person, fill = list(freq = 0)) %>% filter(score == 10) 
+1

Oppure con dplyr-piping 'completo (df, punteggio, persona, riempimento = elenco (freq = 0))%>% filter (score == 10) ' –

+0

Sì! Ti dispiace, se aggiungo questo alla risposta? – Stibu

+0

No, certo che no. Vai avanti –

6

Ecco un approccio di base R:

subset(as.data.frame(xtabs(freq ~ score + person, df)), score == 10) 
# score person Freq 
#4  10  1 3 
#8  10  2 5 
#12 10  3 4 
#16 10  4 0 
0

Qui è un approccio dplyr:

D %>% mutate(freq = ifelse(score == 10, freq, 0), 
       score = 10) %>% 
     group_by(score, person) %>% 
     summarise(freq = max(freq)) 

Source: local data frame [4 x 3] 
Groups: score [?] 

    score person freq 
    (dbl) (int) (dbl) 
1 10  1  3 
2 10  2  5 
3 10  3  4 
4 10  4  0 
Problemi correlati