Search code examples
rdataframesumcumsum

Cumulative sum for more values in one entry


Let's say I have this dataframe (the "number" variable is also from character-type in the original dataframe):

df <- data.frame(
  id = c(1,2,2,1,2),
  number = c(30.6, "50.2/15.5", "45/58.4", 80, "57/6"))
df$number <- as.character(df$number)

Now I want to add another column with the cumulative sum for each ID and I did this with df %>% mutate(csum = ave(number, id, FUN=cumsum)), which works for the single numbers, but of course not for the numbers separated with "/". How can I solve this problem?

The final dataframe should be like this:

df2 <- data.frame(
  id = c(1,2,2,1,2),
  number = c(30.6, "50.2/15.5", "45/58.4", 80, "57/6"),
  csum = c(30.6, "50.2/15.5", "95.2/73.9", 110.6, "152.2/79.9"))
df2

Solution

  • One way could be:

    1. group with group_by
    2. separate in column a and b
    3. mutate across a and b and apply cumsum
    4. unite from tidyr package using na.rm=TRUE argument
    library(dplyr)
    library(tidyr)
    
    df %>% 
      group_by(id) %>% 
      separate(number, c("a", "b"), sep="/", remove = FALSE, convert = TRUE) %>% 
      mutate(across(c(a,b), ~cumsum(.))) %>% 
      unite(csum, c(a,b), sep = '/', na.rm = TRUE)
    
         id number    csum      
      <dbl> <chr>     <chr>     
    1     1 30.6      30.6      
    2     2 50.2/15.5 50.2/15.5 
    3     2 45/58.4   95.2/73.9 
    4     1 80        110.6     
    5     2 57/6      152.2/79.9