Jaroslav Kotrba
Jaroslav Kotrba

Reputation: 313

Cum Sum through Rows in a Data Frame

I have a question regarding negative cumulative sum in R through the rows, how can I get the desired output:

# TEST
data <- data.frame(
  `Delivery Year` = c('1976','1977','1978','1979'),
  `Freq` = c(120,100,80,60),
  `Year.1976` = c(10,3,8,0),
  `Year.1977` = c(5,0,5,0),
  `Year.1978` = c(10,10,0,0),
  `Year.1979` = c(13,0,0,14)
)

data

# DESIRED
data <- data.frame(
  `Delivery Year` = c('1976','1977','1978','1979'),
  `Freq` = c(120,100,80,60),
  `Year.1` = c(110,97,72,60),
  `Year.2` = c(105,97,67,60),
  `Year.3` = c(95,87,67,60),
  `Year.4` = c(82,87,67,46)
)

data

enter image description here

Upvotes: 1

Views: 89

Answers (2)

tmfmnk
tmfmnk

Reputation: 40171

One solution using dplyr and purrr could be:

data %>%
    mutate(pmap_dfr(across(-1), ~ accumulate(c(...), `-`)))

 Delivery.Year Freq Year.1 Year.2 Year.3 Year.4
1          1976  120    110    105     95     82
2          1977  100     97     97     87     87
3          1978   80     72     67     67     67
4          1979   60     60     60     60     46

Same with base R:

Reduce(`-`, data[-1], accumulate = TRUE)

Upvotes: 2

r2evans
r2evans

Reputation: 160942

base R

data[,3:6] <- data$Freq - t(apply(data[,3:6], 1, cumsum))
names(data)[3:6] <- paste0("Year.", 1:4)
data
#   Delivery.Year Freq Year.1 Year.2 Year.3 Year.4
# 1          1976  120    110    105     95     82
# 2          1977  100     97     97     87     87
# 3          1978   80     72     67     67     67
# 4          1979   60     60     60     60     46

Upvotes: 1

Related Questions