2015-07-16 8 views
5

Muszę podsumować liczby łańcuchów, które przypisuję grupom, i wiem, że mogę to zrobić w dplyr/tidyr, ale brakuje mi czegoś.Używanie Tidyr/Dplyr do podsumowania liczby grup łańcuchów

Przykład zbioru danych:

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) 

który wygląda następująco:

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 

Chcę grupy wg nazwy i dzień, a następnie policzyć pogrupowane lokalizacje w kolumnach. W tym przykładzie chcę, aby "dom" i "mieszkanie" zostały dodane do kolumny zatytułowanej "Strona główna" i "sklep", "biuro" i "sklep", które mają być policzone w kolumnie "Praca".

Mój obecny kod (który nie działa):

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"))) 

mam tylko włączone moją obecną próbę etapie podsumować, aby pokazać w jaki sposób zostały zbliża go. Domu i pracy kod obecnie wraca wektorów liczby wierszy, które zawierają element z grupy (tj główna = 1 3 5)

Mam przeznaczony Wydajność:

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 

W rzeczywistym zbiorze (30k + wiersze) istnieje wiele wartości Locna na właściciela na dzień, więc Liczby Dom i Praca mogą być liczbami innymi niż 1 i 0 (więc nie ma booleans).

Wielkie dzięki.

Odpowiedz

7

Spróbuj

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

Hnn ... Byłem pewien, że próbowałem tego. Czy użycie funkcji $ Locn zamiast Locn po podsumowaniu zepsuło funkcję? Działa doskonale, dzięki. –

+0

Chyba tak. 'Locn' respektuje grupę,' dane $ Locn' nie. – lukeA

9

Oto proste i skuteczne rozwiązanie wykorzystujące data.table

dla starszych wersji (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 

Dla nowszych wersji (v> = 1.9.5) można zrobić to w jednej linii

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

Oto tidyr alternatywa

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, dodał 'tidyr' alternatywę (jak to wspomniano w pytaniu). –

+5

Nie ode mnie! Zdecydowanie podoba mi się twoje rozwiązanie i zamierzam zaglądać do dcastu, ponieważ wydaje się dość elastyczny.Pozdrawiam –

+1

Czy mogę w szczególności uzyskać wyjaśnienia dotyczące spadków w tej odpowiedzi? –

2

To jak @lukeA proponowanego rozwiązania, ale przy użyciu grepl funkcję:

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

Dzięki. Patrzyłem też na grep, ale byłem pewien, że mogę to zrobić z% w% –

4

Możesz użyć model.matrix z 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 

Albo

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