2017-01-25 4 views
2

У меня есть входные данные следующим образом.R: проверка числа по вертикали с заданным условием (сортировка со временем)

A <- read.csv(text="Date,User,Deal 
1/1/2017,A,FALSE 
1/2/2017,A,TRUE 
1/3/2017,A,FALSE 
1/4/2017,A,FALSE 
1/5/2017,A,TRUE 
1/6/2017,A,FALSE 
1/7/2017,A,FALSE 
1/6/2017,B,TRUE 
1/7/2017,B,TRUE") 

После данных, сгруппированных пользователем, отсортированных с датой, я хочу, чтобы сохранить запись с Deal = T, и дополнительный столбец, чтобы следить за количеством записей происходит до этого курса = TRUE для данного пользователь. Таким образом, ожидаемый выход:

Date  User Deal NO.Actions 
    1/2/2017 A TRUE   2 
    1/5/2017 A TRUE   3 
    1/6/2017 B TRUE   1 
    1/7/2017 B TRUE   1 

Любой способ достичь этого? Эффективность также будет представлять собой проблему.

Обновление: дополнительный столбец получен из подсчета количества ложных значений до True, просмотрев столбец сделки для данного пользователя.

+0

Можете ли вы предоставить ** более подробную информацию о дополнительной колонке ** –

+0

Нет времени для полного ответа, но предполагая, что dataframe заказана? user и date, это willl производит '2,3,1,1':' as.vector ( sapply (уникальный (A $ User), function (x) diff (c (0, который (A [A $ User = = x, «Сделка»] == T)))) ) ' – Jean

+1

совершенно неясно. Что вы подразумеваете под «отслеживанием количества записей, которые происходят до этого Deal = T'? Можете ли вы предоставить некоторые детали своих расчетов? –

ответ

0

Хитрость заключается в добавлении дополнительной колонки, для которой воспроизводится «раунд». Для этого я добавил, сколько TRUE произошло. Но, чтобы избежать TRUE, рассматриваемого как начало нового раунда (вместо конца предыдущего), мне нужно использовать lag для смещения (и включить default, чтобы мы начали с 1, а не NA). Затем, group_by пользователь и круглый, подсчитайте действия с mutate и фильтруйте только те, где Deal == TRUE.

A %>% 
    group_by(User) %>% 
    mutate(
    round = cumsum(lag(Deal, default = TRUE)) 
    ) %>% 
    group_by(User, round) %>% 
    mutate(nActions = n()) %>% 
    filter(Deal) 

дает

 Date User Deal round nActions 
    <fctr> <fctr> <lgl> <int> <int> 
1 1/2/2017  A TRUE  1  2 
2 1/5/2017  A TRUE  2  3 
3 1/6/2017  B TRUE  1  1 
4 1/7/2017  B TRUE  2  1 

Если вы хотите сохранить «раундов», которые еще не привели к «Deal», вы можете использовать `срез (п()), чтобы сохранить последнюю строку в каждой группе, например, так:

A %>% 
    group_by(User) %>% 
    mutate(
    round = cumsum(lag(Deal, default = TRUE)) 
) %>% 
    group_by(User, round) %>% 
    mutate(nActions = n()) %>% 
    slice(n()) 

который дает

 Date User Deal round nActions 
    <fctr> <fctr> <lgl> <int> <int> 
1 1/2/2017  A TRUE  1  2 
2 1/5/2017  A TRUE  2  3 
3 1/7/2017  A FALSE  3  2 
4 1/6/2017  B TRUE  1  1 
5 1/7/2017  B TRUE  2  1 
0

Я слежу за комментариями @ waterling и получаю желаемые результаты. разместите его здесь как одну из альтернатив.

A$Date <- as.Date(A$Date, "%m/%d/%Y") 
B <- A %>% arrange(User,Date) 
B 
> B 
    Date User Deal 
1 2017-01-01 A FALSE 
2 2017-01-02 A TRUE 
3 2017-01-03 A FALSE 
4 2017-01-04 A FALSE 
5 2017-01-05 A TRUE 
6 2017-01-06 A FALSE 
7 2017-01-07 A FALSE 
8 2017-01-06 B TRUE 
9 2017-01-07 B TRUE 

, а затем создать дополнительный столбец:

B%>%filter(Deal) 
    %>% mutate(No.Actions = as.vector(sapply(unique(B$User), 
     function(x) diff(c(0,which(B[B$User == x, "Deal"] == T)))))) 

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

  • Нет связанных вопросов^_^