2015-06-25 25 views
5

tôi có các dữ liệu sau:dplyr + group_by và tránh chữ cái sắp xếp

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

Đối với mỗi người sử dụng trong bộ này, tôi muốn nhìn vào chuỗi các loại trái cây theo thời gian. Tuy nhiên, một số loại trái cây được liệt kê "trở lại trở lại" trong thời gian.

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 

Những gì tôi đang tìm kiếm là chi tiết của một chuỗi thời gian của người dùng bằng cách độc đáo trái cây.

Vấn đề là, nếu tôi nhóm bằng cách sử dụng và trái cây sau đó tóm tắt, dplyr tự động sắp xếp hoa quả theo thứ tự abc:

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

Những gì tôi thực sự muốn là, đối với người sử dụng 1234 trở lên (ví dụ) cho các loại trái cây được liệt kê theo thứ tự chuỗi thời gian, nhưng loại bỏ bất kỳ bản sao nào. Vì vậy, nơi chúng ta thấy táo> lê> táo> táo> lê> cam> cam, chúng tôi thay vì chỉ nhìn thấy quả táo> lê> táo> lê> cam

+1

'dput' của bạn không hoạt động, vì nó có' vars = list (user) 'và chúng tôi không có' user'. – Frank

+2

woops, xin lỗi về điều đó - cố định dput –

+1

Đầu ra mong muốn của bạn sửa đổi 'time' của quả lê từ' 5' thành '4' – Frank

Trả lời

5

Dựa trên ví dụ của bạn, điều này có thể giúp:

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

Tôi nhận thấy điều đó. Tôi đang cố gắng lập chỉ mục bên trong đường ống dplyr, nhưng vẫn chưa thành công. –

+0

Có lẽ một 'bộ lọc'? dplyr cũng có 'lead' và' lag' có thể hữu ích cho việc kiểm tra các thay đổi. – Frank

+1

cảm ơn bạn, đã làm việc. –

6

Vì vậy, sử dụng rleid chức năng từ phiên bản mới nhất data.table trên cran chúng tôi chỉ đơn giản là có thể làm được (mặc dù không chắc chắn liên quan đến kết quả mong muốn chính xác của bạn)

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

bạn có thể sử dụng group_indices để xử lý một trường hợp như vậy:

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

Tương tự như rleid, nó tạo một id duy nhất cho mỗi nhóm. Bạn về cơ bản lọc ra tất cả các giá trị có cùng id với giá trị trước bằng cách sử dụng 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 
Các vấn đề liên quan