2015-07-16 20 views
5

Ho bisogno di riepilogare i conteggi delle stringhe che sto assegnando ai gruppi, e so che posso farlo in dplyr/tidyr ma mi manca qualcosa.Utilizzo di Tidyr/Dplyr per riepilogare i conteggi di gruppi di stringhe

Esempio set di dati:

Owner = c('bob','julia','cheryl','bob','julia','cheryl') 
Day = c('Mon', 'Tue') 
Locn = c('house','store','apartment','office','house','shop') 
data <- data.frame(Owner, Day, Locn) 

che assomiglia a questo:

Owner Day  Locn 
1 bob Mon  house 
2 julia Tue  store 
3 cheryl Mon apartment 
4 bob Tue office 
5 julia Mon  house 
6 cheryl Tue  shop 

voglio gruppo per nome e il giorno, e poi contare su sedi raggruppate in colonne. In questo esempio voglio "casa" e "appartamento" da aggiungere a una colonna intitolata "Casa" e "archivio", "ufficio" e "negozio" da contare in una colonna "Lavoro".

mio codice attuale (che non funziona):

grouped_locn <- data %>% 
    dplyr::arrange(Owner, Day) %>% 
    dplyr::group_by(Owner, Day) %>% 
    dplyr::summarize(Home = which(data$Locn %in% c('house', 'apartment')), 
       Work = which(data$Locn %in% c("store", "office", "apartment"))) 

ho incluso solo il mio attuale tentativo di riassumere passo per mostrare come mi è stato si avvicina. Il codice casa e un lavoro restituisce attualmente vettori dei numeri di riga che contengono un elemento del gruppo (ovvero Home = 1 3 5)

mia uscita destinata:

Owner Day Home Work 
1 bob Mon  1  0 
2 bob Tue  0  1 
3 julia Mon  1  0 
4 julia Tue  0  1 
5 cheryl Mon  1  0 
6 cheryl Tue  0  1 

Nel set di dati attuale (30k + righe) ci sono più valori di Locn per proprietario al giorno, quindi i conteggi Casa e Lavoro possono essere numeri diversi da 1 e 0 (quindi non booleani).

Molte grazie.

risposta

7

Prova questa

data %>% 
    group_by(Owner, Day) %>% 
    summarise(Home = sum(Locn %in% c("house", "apartment")), 
      Work = sum(Locn %in% c("store", "office", "shop"))) 
+0

Hnn ... Ero sicuro di averlo provato. L'utilizzo dei dati $ Locn invece di Locn dopo il riepilogo risolve la funzione? Funziona perfettamente, grazie. –

+0

Credo di si. 'Locn' rispetta il raggruppamento,' data $ Locn' no. – lukeA

9

Ecco una soluzione semplice ed efficace utilizzando data.table

Per le versioni precedenti (v < 1.9.5)

library(data.table) # v < 1.9.5 
setDT(data)[, Locn2 := c("Work", "Home")[(Locn %in% c('house', 'apartment')) + 1L]] 
dcast.data.table(data, Owner + Day ~ Locn2, length) 
#  Owner Day Home Work 
# 1: bob Mon 1 0 
# 2: bob Tue 0 1 
# 3: cheryl Mon 1 0 
# 4: cheryl Tue 0 1 
# 5: julia Mon 1 0 
# 6: julia Tue 0 1 

Per le versioni più recenti (v> = 1.9.5) si può fare questo in una sola riga

dcast(setDT(data), Owner + Day ~ c("Work", "Home")[(Locn %in% c('house', 'apartment')) + 1L], length) 

Ecco un tidyr alternativa

library(dplyr) 
library(tidyr) 
data %>% 
    mutate(temp = 1L, 
     Locn = ifelse(Locn %in% c('house', 'apartment'), "Home", "Work")) %>% 
    spread(Locn, temp, fill = 0L) 

# Owner Day Home Work 
# 1 bob Mon 1 0 
# 2 bob Tue 0 1 
# 3 cheryl Mon 1 0 
# 4 cheryl Tue 0 1 
# 5 julia Mon 1 0 
# 6 julia Tue 0 1 
+1

Ok, aggiunto un 'alternativa tidyr' (come lei ha ricordato nella questione). –

+5

Non da me! Mi piacciono decisamente le tue soluzioni e guarderò il dcast perché sembra piuttosto flessibile.Cheers –

+1

Posso iniziare a ottenere spiegazioni per i downvotes su questa risposta in particolare? –

2

Questo è come soluzione proposta @lukeA, ma utilizzando la funzione grepl:

library(dplyr) 

data %<>% arrange(Owner, Day) %>% group_by(Owner, Day) %>% 
    summarise(Home=sum((grepl("house|apartment", Locn))*1), 
      Work=sum((grepl("store|office|shop", Locn))*1)) 
+0

Grazie. Stavo guardando anche grep, ma ero sicuro di poterlo fare con% in% –

4

si può utilizzare model.matrix da base R

data[c('Work', 'Home')] <- model.matrix(~0+indx, transform(data, 
     indx = Locn %in% c('house', 'apartment'))) 

    data 
# Owner Day  Locn Work Home 
#1 bob Mon  house 0 1 
#2 julia Tue  store 1 0 
#3 cheryl Mon apartment 0 1 
#4 bob Tue office 1 0 
#5 julia Mon  house 0 1 
#6 cheryl Tue  shop 1 0 

O

library(qdapTools) 
data[c('Work', 'Home')] <- mtabulate(data$Locn %in% c('house', 'apartment'))