计数值出现在组中最后 x 行的次数

Count number of times value has appeared in last x rows in group

我有一个像下面这样的数据框

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 行时,我们只查看过去的 5 行,所以在第 7 行中,我们计算从第 3 行到第 4 行的 4 的数量7,得到 3。一旦你到达第 11 行,一个新组 'b' 开始,我们重新开始。

如果可能,想与 dplyrgroup_by 合作

提前致谢

编辑:最初要求比例,为了更简单,希望更清楚,已更改为要求数量。对任何混淆表示歉意!

您可以为此使用 zoo::rollapply;这里设置 window 大小为 5partial=T 以包括前几个元素; sum(v == tail(v, 1))是计算每个window中最后一个元素出现的次数:

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
dataDF%>%
  group_by(group)%>%
  mutate(i=1:n(),value1=list(value))%>%
  group_by(group,i)%>%
  mutate(proportion=mean(value==unlist(value1)[if(i<5)1:i else i:(i-4)]))%>%
  ungroup()%>%
  select(-i,-value1)
# A tibble: 20 x 3
   group value proportion
   <fct> <dbl>      <dbl>
 1 a        4.      1.00 
 2 a        4.      1.00 
 3 a        4.      1.00 
 4 a        3.      0.250
 5 a        4.      0.800
 6 a        3.      0.400
 7 a        4.      0.600
 8 a        3.      0.600
 9 a        3.      0.600
10 a        3.      0.800
11 b        3.      1.00 
12 b        1.      0.500
13 b        1.      0.667
14 b        1.      0.750
15 b        3.      0.400
16 b        1.      0.800
17 b        3.      0.400
18 b        2.      0.200
19 b        3.      0.600
20 b        1.      0.400
>