Подсчитайте, сколько раз значение появлялось в последних x строках в группе

У меня есть кадр данных, подобный следующему

dataDF <- data.frame(
  group = c(rep('a', 10), rep('b', 10)),
  value = c(4, 4, 4, 3, 4, 3, 4, 3, 3, 3,
            3, 1, 1, 1, 3, 1, 3, 2, 3, 1)
)

Я хочу найти, сколько раз каждое значение появлялось в группе за последние 5 записей (или, если в ней еще не было 5 строк, то общее количество до сих пор).

Итак, я бы закончил с:

   group value number_l5
1      a     4         1
2      a     4         2
3      a     4         3
4      a     3         1
5      a     4         4
6      a     3         2
7      a     4         3
8      a     3         3
9      a     3         3
10     a     3         4
11     b     3         1
12     b     1         1
13     b     1         2
14     b     1         3
15     b     3         2
16     b     1         4
17     b     3         2
18     b     2         1
19     b     3         3
20     b     1         2

Таким образом, в первых трех строках значение равно 4 для каждой строки, поэтому совокупный счет равен 1,2,3. В 4-й строке мы впервые видим 3, поэтому счет равен 1. К тому времени, когда вы пройдете 5-ю строку, мы просматриваем только последние пять строк, поэтому в строке 7 мы подсчитываем количество 4-х от строки 3 до 7, получается 3. Как только вы дойдете до 11 строки, начнется новая группа «b», и мы начнем снова.

Хотел бы сделать с dplyr и group_by, если это возможно

заранее спасибо

РЕДАКТИРОВАТЬ: Первоначально запрошенная пропорция, чтобы сделать проще и, надеюсь, более понятным, изменилась, чтобы запросить число. Приносим извинения за путаницу!


person user1165199    schedule 11.06.2018    source источник
comment
Условия не ясны   -  person akrun    schedule 11.06.2018


Ответы (1)


Вы можете использовать zoo::rollapply для этого; Здесь установите размер окна как 5 и partial=T, чтобы включить первые несколько элементов; sum(v == tail(v, 1)) заключается в подсчете количества раз, когда последний элемент появлялся в каждом окне:

library(dplyr)
library(zoo)

dataDF %>% 
    group_by(group) %>% 
    mutate(proportion = rollapply(value, 5, function(v) sum(v == tail(v, 1)), partial=T, align='right'))

# A tibble: 20 x 3
# Groups:   group [2]
#   group value proportion
#   <fct> <dbl>      <int>
# 1 a         4          1
# 2 a         4          2
# 3 a         4          3
# 4 a         3          1
# 5 a         4          4
# 6 a         3          2
# 7 a         4          3
# 8 a         3          3
# 9 a         3          3
#10 a         3          4
#11 b         3          1
#12 b         1          1
#13 b         1          2
#14 b         1          3
#15 b         3          2
#16 b         1          4
#17 b         3          2
#18 b         2          1
#19 b         3          3
#20 b         1          2
person Psidom    schedule 11.06.2018