【问题标题】:How to combine rle with amount sum in R?如何将rle与R中的金额相结合?
【发布时间】:2021-07-12 12:19:10
【问题描述】:

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

test = data.frame(seq = c(0,0,0,1,1,0,1,0,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 定义。我对每个事件中零的数量(计数)以及总和感兴趣。

对于上面的 test,我们会:

  • 事件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 的金额总和?

【问题讨论】:

    标签: r sequence rle


    【解决方案1】:

    您可以使用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
    

    【讨论】:

    • 这太棒了!非常感谢你,@Ronak Shah
    【解决方案2】:

    如果没有迫切需要使用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, amount=test$amount[i]), cumsum(c(1, diff(i) > 1)))
    #  count amount
    #1     3    191
    #2     1      3
    #3     2    145
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-16
      • 1970-01-01
      • 2019-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多