【问题标题】:R Calculate cumsum for every third valueR计算每三个值的cumsum
【发布时间】:2021-04-16 08:53:42
【问题描述】:

我想计算不是NA 的每 3 个值的总和。 我希望我可以用以下示例数据框解释我的问题:

library(tidyverse)
df <- tibble( 
  date = lubridate::today() +0:19,
  value= c(1,2.5,2,NA,NA,6.5,1,9,3,8,4,7,NA,NA,NA,1,5,3,6,7))

> df
# A tibble: 20 x 2
   date       value
   <date>     <dbl>
 1 2021-04-16   1  
 2 2021-04-17   2.5
 3 2021-04-18   2  
 4 2021-04-19  NA  
 5 2021-04-20  NA  
 6 2021-04-21   6.5
 7 2021-04-22   1  
 8 2021-04-23   9  
 9 2021-04-24   3  
10 2021-04-25   8  
11 2021-04-26   4  
12 2021-04-27   7  
13 2021-04-28  NA  
14 2021-04-29  NA  
15 2021-04-30  NA  
16 2021-05-01   1  
17 2021-05-02   5  
18 2021-05-03   3  
19 2021-05-04   6  
20 2021-05-05   7  

我首先需要一个索引,它可以帮助我更详细地解释我的请求: df$index&lt;-c(1,1,1,NA,NA,2,2,2,3,3,3,4,NA,NA,NA,4,4,5,5,5)

我希望每 3 行不是NA 进行分组。为此,创建了index-列。然后我想计算该组最后一行中 3 个分组值的总和:

df$cumsum&lt;-c(NA,NA,5.5,NA,NA,NA,NA,16.5,NA,NA,15,NA,NA,NA,NA,NA,13,NA,NA,16)

我的最终数据框应如下所示:

# A tibble: 20 x 4
   date       value index cumsum
   <date>     <dbl> <dbl>  <dbl>
 1 2021-04-16   1       1   NA  
 2 2021-04-17   2.5     1   NA  
 3 2021-04-18   2       1    5.5
 4 2021-04-19  NA      NA   NA  
 5 2021-04-20  NA      NA   NA  
 6 2021-04-21   6.5     2   NA  
 7 2021-04-22   1       2   NA  
 8 2021-04-23   9       2   16.5
 9 2021-04-24   3       3   NA  
10 2021-04-25   8       3   NA  
11 2021-04-26   4       3   15  
12 2021-04-27   7       4   NA  
13 2021-04-28  NA      NA   NA  
14 2021-04-29  NA      NA   NA  
15 2021-04-30  NA      NA   NA  
16 2021-05-01   1       4   NA  
17 2021-05-02   5       4   13  
18 2021-05-03   3       5   NA  
19 2021-05-04   6       5   NA  
20 2021-05-05   7       5   16  

有人可以帮我解决问题吗?

非常感谢!

【问题讨论】:

    标签: r


    【解决方案1】:
    • 删除NA
    • 创建 3 行组
    • valuesum 放在每组的最后一行。
    • 加入原始数据框以取回所有行。
    • arrangedate的数据。
    library(dplyr)
    
    df %>%
      filter(!is.na(value)) %>%
      group_by(index = ceiling(row_number()/3)) %>%
      mutate(cumsum = ifelse(row_number() == n(), sum(value), NA)) %>%
      ungroup %>%
      right_join(df, by = c("date", "value")) %>%
      arrange(date)
    
    
    #   date       value index cumsum
    #   <date>     <dbl> <dbl>  <dbl>
    # 1 2021-04-16   1       1   NA  
    # 2 2021-04-17   2.5     1   NA  
    # 3 2021-04-18   2       1    5.5
    # 4 2021-04-19  NA      NA   NA  
    # 5 2021-04-20  NA      NA   NA  
    # 6 2021-04-21   6.5     2   NA  
    # 7 2021-04-22   1       2   NA  
    # 8 2021-04-23   9       2   16.5
    # 9 2021-04-24   3       3   NA  
    #10 2021-04-25   8       3   NA  
    #11 2021-04-26   4       3   15  
    #12 2021-04-27   7       4   NA  
    #13 2021-04-28  NA      NA   NA  
    #14 2021-04-29  NA      NA   NA  
    #15 2021-04-30  NA      NA   NA  
    #16 2021-05-01   1       4   NA  
    #17 2021-05-02   5       4   13  
    #18 2021-05-03   3       5   NA  
    #19 2021-05-04   6       5   NA  
    #20 2021-05-05   7       5   16  
    

    【讨论】:

    • 是否还有不创建indexcumsum 列的解决方案?我想用新值直接覆盖value-列。也许没有right_join-command?
    • 您需要index 列来创建组,尽管您可以在最后使用select(-index) 将其删除。您可以使用mutate(value = 代替mutate(cumsum = 直接替换value 列。要在没有连接命令的情况下执行此操作,我们可能需要考虑另一种逻辑,而不是我在这里实现的逻辑。
    • 是的,你是对的!覆盖很容易。但是你能提供一个没有join-function 的解决方案吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-08
    • 1970-01-01
    相关资源
    最近更新 更多