如何将 rle 与 R 中的金额总和相结合?

问题描述

我有一个包含 0 和 1 以及附加到它们的数量的数据集,

test = data.frame(seq = c(0,1,0),amount = c(91.0,100.0,0.0,4.5,5.5,3.0,23.0,89.0,56.0))



  seq amount
1   0   91.0
2   0  100.0
3   0    0.0
4   1    4.5
5   1    5.5
6   0    3.0
7   1   23.0
8   0   89.0
9   0   56.0

事件由 0 的子序列中的第一个 0 定义。我对每个事件中零的数量(计数)以及总和感兴趣。

对于上面的测试,我们会:

  • 事件 1:0 0 0,数量:191.0
  • 事件 2:0,数量:3.0
  • 事件 3:0 0,数量:145.0

所以,我想创建下表,

|      Event |     count    |   amount |
|------------|--------------|----------|
|        1   |      3       | 191.0    |
|        2   |      1       | 3.0      |
|        3   |      2       | 145.0    |

在之前的帖子中,@27 ϕ 9 向我发送了关于 Eventcount 列的好建议。

with(rle(test),data.frame(id = sequence(sum(values == 0)),count = lengths[values == 0]))

但是我如何添加仍然使用 rle 的金额?

解决方法

您可以使用 data.table::rleid 创建连续运行的组,计算每组中的行数并sum amount

library(dplyr)

res <- test %>%
  group_by(Event = data.table::rleid(seq)) %>%
  summarise(seq = first(seq),count = n(),amount = sum(amount))

res

#  Event   seq count amount
#  <int> <dbl> <int>  <dbl>
#1     1     0     3    191
#2     2     1     2     10
#3     3     0     1      3
#4     4     1     1     23
#5     5     0     2    145

如果你只对 0 序列感兴趣 -

res %>%
  filter(seq == 0) %>%
  mutate(Event = row_number()) %>%
  select(-seq)

#  Event count amount
#  <int> <int>  <dbl>
#1     1     3    191
#2     2     1      3
#3     3     2    145

如果您有兴趣继续使用 rle 方法,您可以这样做 -

with(rle(test$seq),data.frame(id = sequence(sum(values == 0)),count = lengths[values == 0],amount = tapply(test$amount,rep(seq_along(values),lengths),sum)[values == 0]))

#  id count amount
#1  1     3    191
#3  2     1      3
#5  3     2    145
,

如果没有迫切需要使用 rle aggregate 可以这样使用:

i <- which(test$seq == 0)
aggregate(cbind(count=1,amount=test$amount[i]),list(Event=cumsum(c(1,diff(i) > 1))),sum)
#  Event count amount
#1     1     3    191
#2     2     1      3
#3     3     2    145

rowsum

i <- which(test$seq == 0)
rowsum(cbind(count=1,cumsum(c(1,diff(i) > 1)))
#  count amount
#1     3    191
#2     1      3
#3     2    145