2015-06-25 11 views
5

Mam następujące dane:dplyr + group_by i uniknąć alfabetyczne sortowanie

data <- structure(list(user = c(1234L, 1234L, 1234L, 1234L, 1234L, 1234L, 
1234L, 1234L, 1234L, 1234L, 1234L, 4758L, 4758L, 9584L, 9584L, 
9584L, 9584L, 9584L, 9584L), time = c(1L, 2L, 3L, 4L, 5L, 6L, 
7L, 8L, 9L, 10L, 11L, 5L, 6L, 1L, 2L, 3L, 4L, 5L, 6L), fruit = structure(c(1L, 
6L, 1L, 1L, 6L, 5L, 5L, 3L, 4L, 1L, 2L, 4L, 2L, 1L, 6L, 5L, 5L, 
3L, 2L), .Label = c("apple", "banana", "lemon", "lime", "orange", 
"pear"), class = "factor"), count = c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), cum_sum = c(1L, 
2L, 3L, 4L, 5L, 6L, 7L, 8L, 9L, 10L, 11L, 1L, 2L, 1L, 2L, 3L, 
4L, 5L, 6L)), .Names = c("user", "time", "fruit", "count", "cum_sum" 
), row.names = c(NA, -19L), class = "data.frame") 

dla każdego użytkownika w tym zestawie, chcę patrzeć na sekwencji owoców w czasie. Ale niektóre owoce są wymienione "z powrotem do tyłu" na czas.

user time fruit count cum_sum 
1 1234 1 apple  1 1 
2 1234 2 pear  1 2 
3 1234 3 apple  1 3 
4 1234 4 apple  1 4 
5 1234 5 pear  1 5 
6 1234 6 orange  1 6 
7 1234 7 orange  1 7 

Co szukam jest bardziej szeregów czasowych przez użytkownika poprzez unikalnej owoców.

Problem jest, jeśli grupa przez użytkownika i owoców następnie podsumować dplyr automatycznie sortuje owoce alfabetycznie:

data %>% 
    group_by(user, fruit) %>% 
    summarise(temp_var=1) %>% 
    mutate(cum_sum = cumsum(temp_var)) 

Co ja naprawdę chcę to dla użytkownika 1234 powyżej (na przykład) na owoce być wymienione w kolejności szeregów czasowych, ale usuwając wszelkie duplikaty. Więc gdzie widzimy Apple> gruszka> Apple> Apple> gruszka> pomarańczy> pomarańcza, byśmy tylko zamiast zobaczyć Apple>>> Apple gruszka gruszka> pomarańczowy

+1

Twoje 'dput' nie działa, ponieważ ma' vars = list (user) ', a my nie mamy' user'. – Frank

+2

woops, przepraszam za to - naprawiono dput –

+1

Twoje pożądane wyjście modyfikuje 'czas' gruszki z' 5' na '4' – Frank

Odpowiedz

5

podstawie Twoich przykładów, może to pomóc:

data %>% 
group_by(user) %>% 
filter(c(T,fruit[-1L] != fruit[-length(fruit)])) %>% 
mutate(cum_sum = cumsum(count), 
    time = seq_along(count)) 
# Source: local data frame [16 x 5] 
# Groups: user 
# 
# user time fruit count cum_sum 
# 1 1234 1 apple  1  1 
# 2 1234 2 pear  1  2 
# 3 1234 3 apple  1  3 
# 4 1234 4 pear  1  4 
# 5 1234 5 orange  1  5 
# 6 1234 6 lemon  1  6 
# 7 1234 7 lime  1  7 
# 8 1234 8 apple  1  8 
# 9 1234 9 banana  1  9 
# 10 4758 1 lime  1  1 
# 11 4758 2 banana  1  2 
# 12 9584 1 apple  1  1 
# 13 9584 2 pear  1  2 
# 14 9584 3 orange  1  3 
# 15 9584 4 lemon  1  4 
# 16 9584 5 banana  1  5 
+0

Zauważyłem to. Próbuję indeksować wewnątrz rury dplyr, ale nie udało się jeszcze. –

+0

Może "filtr"? dplyr ma również "lead" i "lag", które mogą być przydatne do sprawdzania zmian. – Frank

+1

dziękuję, to działało. –

6

Więc za pomocą rleid funkcję z najnowszej wersji na CRAN data.table możemy po prostu zrobić (choć nie jestem pewien odnośnie dokładnego żądanym wyjściu)

library(data.table) ## v >= 1.9.6 
res <- setDT(data)[, .(fruit = fruit[1L]), by = .(user, indx = rleid(fruit)) 
        ][, cum_sum := seq_len(.N), by = user 
         ][, indx := NULL] 
res 
#  user fruit cum_sum 
# 1: 1234 apple  1 
# 2: 1234 pear  2 
# 3: 1234 apple  3 
# 4: 1234 pear  4 
# 5: 1234 orange  5 
# 6: 1234 lemon  6 
# 7: 1234 lime  7 
# 8: 1234 apple  8 
# 9: 1234 banana  9 
# 10: 4758 lime  1 
# 11: 4758 banana  2 
# 12: 9584 apple  1 
# 13: 9584 pear  2 
# 14: 9584 orange  3 
# 15: 9584 lemon  4 
# 16: 9584 banana  5 
3

można użyć group_indices obsłużyć taki przypadek:

data %>% 
    filter(group_indices_(., .dots = c("user", "fruit")) != 
      lag(group_indices_(., .dots = c("user", "fruit")), default = 0)) %>% 
    group_by(user) %>% 
    mutate(cum_sum = row_number()) 

W podobny sposób do rleid, generuje unikalny identyfikator dla każdej grupy. Zasadniczo odfiltrowujesz wszystkie wartości, które mają ten sam identyfikator co poprzedni, używając lag().

#Source: local data frame [16 x 3] 
#Groups: user 
# 
# user fruit cum_sum 
#1 1234 apple  1 
#2 1234 pear  2 
#3 1234 apple  3 
#4 1234 pear  4 
#5 1234 orange  5 
#6 1234 lemon  6 
#7 1234 lime  7 
#8 1234 apple  8 
#9 1234 banana  9 
#10 4758 lime  1 
#11 4758 banana  2 
#12 9584 apple  1 
#13 9584 pear  2 
#14 9584 orange  3 
#15 9584 lemon  4 
#16 9584 banana  5 
Powiązane problemy