【问题标题】:cumulative sum by ID with lag带有滞后的 ID 累积总和
【发布时间】:2019-05-27 00:21:46
【问题描述】:

我想通过 id 创建一个累积总和。但是,它不应该将属于正在计算的行的值相加。

我已经尝试过 cumsum。但是,我不知道如何添加一个语句,该语句指定不添加进行总和的行的数量。我要查找的结果列是第三列:“sum”。

例如,对于 id 1,第一行是 sum=0,因为不应该添加这一行。但是,对于 id 1 和第 2 行 sum=100,因为第 2 行之前的 id 1 的数量是 100,依此类推。

   id amount sum
1:  1    100   0
2:  1     20 100
3:  1    150 120
4:  2     60   0
5:  2    100  60
6:  1     30 270
7:  2     40 160 

这是我尝试过的:

  df[,sum:=cumsum(amount),
      by ="id"] 

  data: df <- data.table(id = c(1, 1, 1, 2, 2,1,2), amount = c(100, 20, 
  150,60,100,30,40),sum=c(0,100,120,0,60,270,160) ,stringsAsFactors = 
  FALSE)

【问题讨论】:

    标签: r datatable cumulative-sum multiple-conditions


    【解决方案1】:

    你可以不使用lag来做到这一点:

    > df %>%
          group_by(id) %>%
          mutate(sum = cumsum(amount) - amount)
    # A tibble: 7 x 3
    # Groups:   id [2]
         id amount   sum
      <dbl>  <dbl> <dbl>
    #1    1    100     0
    #2    1     20   100
    #3    1    150   120
    #4    2     60     0
    #5    2    100    60
    #6    1     30   270
    #7    2     40   160
    

    【讨论】:

      【解决方案2】:

      与dplyr -

      df %>% 
        group_by(id) %>% 
        mutate(sum = lag(cumsum(amount), default = 0)) %>% 
        ungroup()
      
      # A tibble: 7 x 3
           id amount   sum
        <dbl>  <dbl> <dbl>
      1     1    100     0
      2     1     20   100
      3     1    150   120
      4     2     60     0
      5     2    100    60
      6     1     30   270
      7     2     40   160
      

      感谢@thelatemail,这是data.table 版本-

      df[, sum := cumsum(shift(amount, fill=0)), by=id]
      

      【讨论】:

        【解决方案3】:

        这是base R中的一个选项

        df$Sum <- with(df, ave(amount, id, FUN = cumsum) - amount)
        df$Sum
        #[1]   0 100 120   0  60 270 160
        

        或者通过删除最后一个观察,取cumsum

        with(df, ave(amount, id, FUN  = function(x) c(0, cumsum(x[-length(x)]))))
        

        【讨论】:

          【解决方案4】:

          您可以使用lag 函数来移动要求和的值。

          library(tidyverse)
          
          df <- data.frame(id = c(1, 1, 1, 2, 2,1,2), amount = c(100, 20, 
          150,60,100,30,40),sum=c(0,100,120,0,60,270,160) ,stringsAsFactors = 
          FALSE)
          
          df %>% 
              group_by(id) %>% 
              mutate(sum = cumsum(lag(amount, 1, default=0)))
          
          # A tibble: 7 x 3
          # Groups:   id [2]
               id amount   sum
            <dbl>  <dbl> <dbl>
          1     1    100     0
          2     1     20   100
          3     1    150   120
          4     2     60     0
          5     2    100    60
          6     1     30   270
          7     2     40   160
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2022-07-26
            • 1970-01-01
            • 1970-01-01
            • 2019-02-15
            • 1970-01-01
            • 2018-06-28
            • 1970-01-01
            相关资源
            最近更新 更多