2015-06-25 7 views
3

У меня есть некоторые данные, которые смотрят на группу людей и фрукты, которые они едят с течением времени. Я хочу использовать dplyr, чтобы посмотреть на каждого отдельного человека, пока они не едят банан и не суммируют все фрукты, которые они съедали , пока они не едят свой первый банан.r + dplyr фильтрация временных рядов

данные:

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

Моя первая мысль была бы сгруппировать данные, чтобы найти первый экземпляр каждого пользователя есть банан:

data <- data %>% transform(var = ifelse(site=="banana", 'banana','other')) 

data_ban <- data %>% 
    filter(var=='banana') %>% 
    group_by(user, var, time) %>% 
    group_by(user) %>% 
    summarise(first_banana = min(time)) 

Но теперь я застрял на том, как на самом деле примените это обратно к исходному «data» dataframe и установите фильтр, который говорит: для каждого пользователя включать данные только до времени, указанного в «data_ban». Есть идеи?

+0

Вы можете также разместить ожидаемый результат. Может быть 'data%>% group_by (user)%>% slice (1: (который (int == 'banana') [1L]))' – akrun

+0

@akrun, то, что вы опубликовали, дает ожидаемый результат. В чем разница между [1L] и [1], которую написал Ромайн ниже? –

+0

Это просто получить целочисленный индекс вместо числового индекса. 1L принуждение к целому числу (предположительно быстрее) – akrun

ответ

4

Вы можете попробовать slice

data %>% 
    group_by(user) %>% 
    slice(1:(which(int=='banana')[1L])) 
2

Что-то вроде этого: группировка user и фильтрация time ниже, чем в первый раз, когда они едят банан.

> data %>% group_by(user) %>% filter(time <= which(site=="banana")[1]) 
Source: local data frame [17 x 4] 
Groups: user 

    user site time int 
1 1234 apple 1 other 
2 1234 pear 2 other 
3 1234 apple 3 other 
4 1234 apple 4 other 
5 1234 pear 5 other 
6 1234 orange 6 other 
7 1234 orange 7 other 
8 1234 lemon 8 other 
9 1234 lime 9 other 
10 1234 apple 10 other 
11 1234 banana 11 banana 
12 9584 apple 1 other 
13 9584 pear 2 other 
14 9584 orange 3 other 
15 9584 orange 4 other 
16 9584 lemon 5 other 
17 9584 banana 6 banana 

В противном случае возможно anti_join.

+0

Мне нравится это решение! is: Что делает векторный вызов ([1])? Я обнаружил, что с ним мне не хватает User 4758, но его удаление дает те же результаты, только с этим добавленным пользователем ... –

+0

... захват * first * время, когда пользователь ест банан –

Смежные вопросы