4

What is the opposite of cumsum() in R

a = c(2, 5, 8)
cumsum = c(2, 7, 15)
cumdiff = c(2, 3, 1)

Because 5-2 = 3 and 8-7 = 1.

Is there a package that can be used for this one in R?

Maël
  • 45,206
  • 3
  • 29
  • 67
Lilac_Mimo
  • 315
  • 5

3 Answers3

4

In base R:

cumdiff <- function(x) x - head(c(0, cumsum(x)), -1)
#cumdiff <- function(x) x - c(0, cumsum(x))[-(length(x) + 1)]

In dplyr, with lag and default = 0:

library(dplyr)
cumdiff <- function(x) x - lag(cumsum(x), default = 0)

Result:

a = c(2,5,8)
cumdiff(a)
#[1] 2 3 1
Maël
  • 45,206
  • 3
  • 29
  • 67
2

If by cumdiff you mean the current value in the vector minus the cumsum of the previous values, you could use the below:

a = c(2,5,8)
cumdiff <- function(x){
  out <- x - lag(cumsum(x))
  out[1] <- x[1]
  return(out)
}
cumdiff(a)
[1] 2 3 1


library(dplyr)
tibble(a) %>% 
  mutate(cumsum = cumsum(a),
         cumdiff = cumdiff(a))
#> # A tibble: 3 × 3
#>       a cumsum cumdiff
#>   <dbl>  <dbl>   <dbl>
#> 1     2      2       2
#> 2     5      7       3
#> 3     8     15       1

Created on 2022-09-08 by the reprex package (v2.0.1)

CyG
  • 382
  • 1
  • 12
  • So if cumdiff[1] cannot be stated as the fst row in a? – Lilac_Mimo Sep 08 '22 at 09:13
  • Techincally you can't compute the cumdiff for the first one, but if you want you still want to return the starting value you could edit the code as below: `cumdiff <- function(x){ out <- x - lag(cumsum(x)) out[1] <- x[1] return(out) }cumdiff(a) tibble(a = c(2,5,8)) %>% mutate(cumsum = cumsum(a), cumdiff = cumdiff(a))` I've edited my answer so you it returns the first value as you wished – CyG Sep 08 '22 at 09:47
0
library(dplyr)
data.frame(a)  %>% 
  mutate(
         cumdiff = a - lag(cumsum(a)),
         cumdiff = ifelse(is.na(cumdiff), a, cumdiff)
         )
  a cumdiff
1 2       2
2 5       3
3 8       1
Chris Ruehlemann
  • 20,321
  • 4
  • 12
  • 34