Search code examples
rdplyrcumsum

Mutate multiple cumsum in dplyr


I am trying to develop a cumsum with mutate. The challenge is that I have 10 columns to do and I know how to do one by one. Is there a way where I can do something like mutate(across(all_of(c(3:4)), ~cumsum(c(3:4)))?

cat %>% 
  group_by(animals) %>%
  mutate(weight1 = cumsum(weight1),
         weight2 = cumsum(weight2))
structure(list(animals = c("E1", "E1", "E1", 
"E2", "E2", "E2"), period = structure(c(18690, 
18697, 18704, 18690, 18697, 18704), class = "Date"), weight1 = c(704, 
734, 653, 851, 911, 829), weight2 = c(0, 235, 325, 0, 148, 
200)), row.names = c(NA, -6L), class = c("data.table", "data.frame")) 

Expected output:

  animals period     weight1 weight2
  <chr>   <date>       <dbl>   <dbl>
1 E1      2021-03-04     704       0
2 E1      2021-03-11    1438     235
3 E1      2021-03-18    2091     560
4 E2      2021-03-04     851       0
5 E2      2021-03-11    1762     148
6 E2      2021-03-18    2591     348

Solution

  • try to do this

    df <- structure(list(animals = c("E1", "E1", "E1", 
                               "E2", "E2", "E2"), period = structure(c(18690, 
                                                                       18697, 18704, 18690, 18697, 18704), class = "Date"), weight1 = c(704, 
                                                                                                                                        734, 653, 851, 911, 829), weight2 = c(0, 235, 325, 0, 148, 
                                                                                                                                                                              200)), row.names = c(NA, -6L), class = c("data.table", "data.frame")) 
    
    library(dplyr)
    
    df %>% 
      group_by(animals) %>% 
      mutate(across(starts_with("weight"), cumsum))
    #> # A tibble: 6 x 4
    #> # Groups:   animals [2]
    #>   animals period     weight1 weight2
    #>   <chr>   <date>       <dbl>   <dbl>
    #> 1 E1      2021-03-04     704       0
    #> 2 E1      2021-03-11    1438     235
    #> 3 E1      2021-03-18    2091     560
    #> 4 E2      2021-03-04     851       0
    #> 5 E2      2021-03-11    1762     148
    #> 6 E2      2021-03-18    2591     348
    

    Created on 2021-03-24 by the reprex package (v1.0.0)

    or

    vars <- names(df)[3:4]

    df %>% group_by(animals) %>% mutate(across(all_of(vars), cumsum))