【问题标题】:how to calculate cumsum with depreciation in a grouped dataframe?如何在分组数据框中计算折旧累计和?
【发布时间】:2019-08-17 05:21:31
【问题描述】:

我试图用折旧率计算累积和。

我有一个带有列号的分组数据框。 我想一一加上折旧的数字。 如果比率为 1,则基数 r 中的 cumsum 函数就足够了。 但如果没有,假设 0.5 的比率(意味着每个数字将乘以 0.5 以添加下一个数字), cumsum 是不够的。 我尝试编写自己的函数来使用 dplyr,但它失败了。

library(tidyverse)
# dataframe
id=sample(1:5,25,replace=TRUE)
num=rnorm(25)
df=data.frame(id,num)

# my custom function
depre=function(data){
    rate=0.5
    r=nrow(data)
    sl=data$num
    nl=data$num
    for (i in 2:r){
        sl[i]=sl[i-1]*rate+nl[i]
    }
    return(sl)
}

# work with one group
df %>% filter(id==1) %>% depre(.)

# failed to work with dplyr
df %>% group_by(id) %>% mutate(sl=depre(.))

我希望列 s 的第一个元素应该与列 num 中的相同。 但是下面的,应该按 0.5 倍折旧并添加下一个 num。 它在一组中工作,但在多组数据框中失败。 错误消息是:“错误:列 sl 的长度必须为 6(组大小)或 1,而不是 25”。 我不知道。谁能有线索? 谢谢

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    如果你将向量而不是数据框传递给你的函数,你的函数就会起作用

    depre <-  function(num){
        rate = 0.5
        r= length(num)
        sl = num
        nl =  num
        for (i in 2:r){
          sl[i]=sl[i-1]*rate+nl[i]
        }
        return(sl)
    }
    

    然后按组应用。

    library(dplyr)
    df %>% group_by(id) %>% mutate(sl = depre(num))
    

    【讨论】:

      【解决方案2】:

      我们可以通过'id'拆分并使用OP的功能而无需任何更改

      library(dplyr)
      library(purrr)
      df %>% 
          group_split(id, keep = FALSE) %>% 
          map_df(~ tibble(id = .$id, sl = depre(.)))
      #      id     sl
      #   <int>  <dbl>
      # 1     1  1.07 
      # 2     1 -0.776
      # 3     1 -0.518
      # 4     1  0.628
      # 5     1  0.601
      # 6     1  1.10 
      # 7     2 -0.734
      # 8     2 -0.583
      # 9     2 -0.437
      #10     2 -3.45 
      # … with 15 more rows
      

      或者一个选项是accumulate from purrr,这会更紧凑

      out <- df %>% 
           group_by(id) %>%
           mutate(sl = accumulate(num, ~ .y + .x * 0.5))
      out
      # A tibble: 25 x 3
      # Groups:   id [5]
      #      id     num      sl
      #   <int>   <dbl>   <dbl>
      # 1     3 -0.784  -0.784 
      # 2     2 -0.734  -0.734 
      # 3     2 -0.216  -0.583 
      # 4     3 -0.335  -0.727 
      # 5     5 -1.09   -1.09  
      # 6     4 -0.0854 -0.0854
      # 7     1  1.07    1.07  
      # 8     2 -0.145  -0.437 
      # 9     3 -1.17   -1.53  
      #10     5 -0.819  -1.36  
      # … with 15 more rows
      
      
      
      out %>% 
         filter(id == 1)
      # A tibble: 6 x 3
      # Groups:   id [1]
      #     id    num     sl
      #  <int>  <dbl>  <dbl>
      #1     1  1.07   1.07 
      #2     1 -1.31  -0.776
      #3     1 -0.129 -0.518
      #4     1  0.887  0.628
      #5     1  0.287  0.601
      #6     1  0.800  1.10 
      

      OP函数的问题是输入是整个数据集,在获取行数的过程中,它使用nrow(data),这将是总行数。对于group_bydplyr 约定是n() - 给出行数。通过执行group_split,输入data.frame 将split 成为data.frames 的子集,其中nrow 将适用于创建的函数

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2022-11-14
        • 2021-08-21
        • 2017-03-06
        • 2017-02-23
        • 2020-08-07
        • 1970-01-01
        • 1970-01-01
        • 2021-04-23
        相关资源
        最近更新 更多