【问题标题】:find yearly cumsum of a variable in R?在R中找到一个变量的年度累积?
【发布时间】:2020-07-18 14:14:34
【问题描述】:

在下面的代码中,我想找到每年的cumsum。现在,Variable A 在整个期间都是summed。任何帮助将不胜感激。

library(dplyr)
library(lubridate)
set.seed(50)
DF <- data.frame(date = seq(as.Date("2001-01-01"), to= as.Date("2003-12-31"), by="day"),
                       A = runif(1095, 0,10))
DF1 <- DF %>% 
  mutate(Year = year(date), Month = month(date), JDay = yday(date)) %>%
  filter(between(Month,5,10)) %>%
  group_by(Year, JDay) %>% 
  mutate(Precipitation = cumsum(A))

【问题讨论】:

    标签: r dataframe group-by tidyverse cumsum


    【解决方案1】:

    只需从分组变量中删除 JDay

    DF1 <- DF %>% 
      mutate(Year = year(date), Month = month(date), JDay = yday(date)) %>%
      filter(between(Month,5,10)) %>%
      group_by(Year) %>% 
      mutate(Precipitation = cumsum(A)) %>%
      ungroup()
    

    【讨论】:

    • 我删除了我之前的评论——我还加载了其他几个包(tidyversetidyr),我认为这是没有得到正确答案的唯一原因。
    【解决方案2】:

    这里的问题似乎与您的分组条款有关。具体来说,由于您的数据中YearJDay 的不同组合与DF 中的行一样多,因此mutate 中的后续cumsum 操作将简单地返回与输入列相同的值, A。我相信以下内容应该可以满足您的需求

    library(dplyr)
    library(lubridate)
    
    set.seed(50)
    DF <- data.frame(date = seq(as.Date("2001-01-01"), to= as.Date("2003-12-31"), by="day"),
                     A = runif(1095, 0,10))
    DF1 <- DF %>% 
      mutate(Year = year(date), Month = month(date), JDay = yday(date)) %>%
      filter(between(Month,5,10)) %>%
      arrange(Year, JDay) %>% 
      group_by(Year) %>% 
      mutate(Precipitation =  cumsum(A)) %>% 
      ungroup()
    
    # illustrate that Precipitation does indeed give the cumulative value of A for
    # each year by printing the first 5 observations for each year in DF1
    DF1 %>% 
      group_by(Year) %>% 
      slice(1:5)
    #> # A tibble: 15 x 6
    #> # Groups:   Year [3]
    #>    date           A  Year Month  JDay Precipitation
    #>    <date>     <dbl> <dbl> <dbl> <dbl>         <dbl>
    #>  1 2001-05-01 6.25   2001     5   121          6.25
    #>  2 2001-05-02 0.188  2001     5   122          6.43
    #>  3 2001-05-03 5.37   2001     5   123         11.8 
    #>  4 2001-05-04 5.55   2001     5   124         17.4 
    #>  5 2001-05-05 5.15   2001     5   125         22.5 
    #>  6 2002-05-01 2.95   2002     5   121          2.95
    #>  7 2002-05-02 6.75   2002     5   122          9.71
    #>  8 2002-05-03 7.77   2002     5   123         17.5 
    #>  9 2002-05-04 8.13   2002     5   124         25.6 
    #> 10 2002-05-05 5.58   2002     5   125         31.2 
    #> 11 2003-05-01 9.98   2003     5   121          9.98
    #> 12 2003-05-02 8.24   2003     5   122         18.2 
    #> 13 2003-05-03 6.13   2003     5   123         24.4 
    #> 14 2003-05-04 5.22   2003     5   124         29.6 
    #> 15 2003-05-05 9.81   2003     5   125         39.4
    

    【讨论】:

    • 我更新了我的答案以表明代码确实生成了一个数据框,其中Precipitation 表示每个YearA 的累积值。如果输出不是您所追求的,您能否提供一个表示您期望得到的代表?
    • 我重新启动了我的 R 会话并仅加载 lubridatedplyr 包,它开始工作。以前我也加载了tidyversetidyr 包。我不知道为什么,但我认为包裹之间可能存在某种混淆,这就是为什么我没有得到正确答案的原因。
    【解决方案3】:

    这是一个data.table 解决方案。如果您想要每年的 cumsum,但只显示从第 5 个月到第 10 个月的间隔,这将是 data.table 代码:

    library(lubridate)
    #> 
    #> Attaching package: 'lubridate'
    #> The following objects are masked from 'package:base':
    #> 
    #>     date, intersect, setdiff, union
    library(data.table)
    #> 
    #> Attaching package: 'data.table'
    #> The following objects are masked from 'package:lubridate':
    #> 
    #>     hour, isoweek, mday, minute, month, quarter, second, wday, week,
    #>     yday, year
    set.seed(50)
    DF <- data.frame(date = seq(as.Date("2001-01-01"), to= as.Date("2003-12-31"), by="day"),
                     A = runif(1095, 0,10))
    
    data.table(DF)[, `:=` (Year = year(date), Month = month(date), JDay = yday(date))][, Precipitation := cumsum(A), by=Year][between(Month, 5, 10)][]
    #>            date         A Year Month JDay Precipitation
    #>   1: 2001-05-01 6.2465000 2001     5  121      568.9538
    #>   2: 2001-05-02 0.1877191 2001     5  122      569.1416
    #>   3: 2001-05-03 5.3717570 2001     5  123      574.5133
    #>   4: 2001-05-04 5.5457454 2001     5  124      580.0591
    #>   5: 2001-05-05 5.1508288 2001     5  125      585.2099
    #>  ---                                                   
    #> 548: 2003-10-27 0.1979292 2003    10  300     1479.8115
    #> 549: 2003-10-28 6.7286553 2003    10  301     1486.5402
    #> 550: 2003-10-29 8.7215420 2003    10  302     1495.2617
    #> 551: 2003-10-30 8.2572257 2003    10  303     1503.5190
    #> 552: 2003-10-31 9.6567923 2003    10  304     1513.1757
    

    如果您只想要 5-10 个月的 cumsum,您可以在计算 cumsum 之前放置过滤器:

    data.table(DF)[, `:=` (Year = year(date), Month = month(date), JDay = yday(date))][between(Month, 5, 10)][, Precipitation := cumsum(A), by=Year][]
    #>            date         A Year Month JDay Precipitation
    #>   1: 2001-05-01 6.2465000 2001     5  121      6.246500
    #>   2: 2001-05-02 0.1877191 2001     5  122      6.434219
    #>   3: 2001-05-03 5.3717570 2001     5  123     11.805976
    #>   4: 2001-05-04 5.5457454 2001     5  124     17.351722
    #>   5: 2001-05-05 5.1508288 2001     5  125     22.502550
    #>  ---                                                   
    #> 548: 2003-10-27 0.1979292 2003    10  300    916.597973
    #> 549: 2003-10-28 6.7286553 2003    10  301    923.326629
    #> 550: 2003-10-29 8.7215420 2003    10  302    932.048171
    #> 551: 2003-10-30 8.2572257 2003    10  303    940.305396
    #> 552: 2003-10-31 9.6567923 2003    10  304    949.962189
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-17
      • 2016-08-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-02-20
      相关资源
      最近更新 更多