7

I am currently trying to simplify this summation. I am new to R.

Data

Lx = c(5050.0, 65.0, 25.0, 19.0, 17.5, 16.5, 15.5, 14.5, 13.5, 12.5, 6.0, 0.0)

Summation series

Tx = c(sum(Lx[1:12]),sum(Lx[2:12]),sum(Lx[3:12]),sum(Lx[4:12]),
       sum(Lx[5:12]),sum(Lx[6:12]),sum(Lx[7:12]),sum(Lx[8:12]),
       sum(Lx[9:12]),sum(Lx[10:12]),sum(Lx[11:12]),sum(Lx[12:12]))
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
  • 1
    Does this answer your question? [Calculate cumsum from the end towards the beginning](https://stackoverflow.com/questions/50413415/calculate-cumsum-from-the-end-towards-the-beginning) – Maël Jan 27 '22 at 09:11

5 Answers5

16

You can do:

rev(cumsum(rev(Lx)))

[1] 5255.0  205.0  140.0  115.0   96.0   78.5   62.0   46.5   32.0   18.5    6.0    0.0

Or alternatively, using Reduce():

Reduce(`+`, Lx, right = TRUE, accumulate = TRUE)

[1] 5255.0  205.0  140.0  115.0   96.0   78.5   62.0   46.5   32.0   18.5    6.0    0.0
Ritchie Sacramento
  • 29,890
  • 4
  • 48
  • 56
2

Using a for loop:

Tx_new <- vector(length = length(Lx))
for (i in 1:length(Lx)) {
  
  Tx_new[i] <- sum(Lx[i:length(Lx)])
  
}
2

A possible solution, using sapply:

sapply(1:12, function(x) sum(Lx[x:12]))

#>  [1] 5255.0  205.0  140.0  115.0   96.0   78.5   62.0   46.5   32.0   18.5
#> [11]    6.0    0.0
PaulS
  • 21,159
  • 2
  • 9
  • 26
2

Package spatstat.utils provides a fast version ("under certain conditions") of the reverse cumulative sum, revcumsum, which is based on computing sum(x[i:n]) with n = length(x) (basically @Jan Brederecke's answer):

Lx = c(5050.0, 65.0, 25.0, 19.0, 17.5, 16.5, 15.5, 14.5, 13.5, 12.5, 6.0, 0.0)

# install.packages("spatstat.utils")
spatstat.utils::revcumsum(Lx)
#  [1] 5255.0  205.0  140.0  115.0   96.0   78.5   62.0   46.5   32.0   18.5    6.0    0.0

Benchmark

x = c(5050.0, 65.0, 25.0, 19.0, 17.5, 16.5, 15.5, 14.5, 13.5, 12.5, 6.0, 0.0)
bm <- microbenchmark(
  fRev(x),
  fReduce(x),
  fJan(x), 
  fEshita(x), 
  fsapply(x),
  fRevcumsum(x),
  times = 100L
)
autoplot(bm)

rev(cumsum(rev(Lx))) and spatstat.utils::revcumsum(Lx) seem like the fastest solutions.

enter image description here

Maël
  • 45,206
  • 3
  • 29
  • 67
1

Please try the following code:

Lx = c(5050.0, 65.0, 25.0, 19.0, 17.5, 16.5, 15.5, 14.5, 13.5, 12.5, 6.0, 0.0)

l=length(Lx)

aa=list()

for(i in 1:l)

{ 
  x=sum((Lx[i:l]))

  aa=append(aa,x)
  
}

all the values after summation will be in the list "aa".

Peace Wang
  • 2,399
  • 1
  • 8
  • 15