-1

suppose i have a list of number:

numbers = c(1, 2, 5, 6, 3, 2, 3, 7, 6)

and a threshold

threshold = 6

I want to group the elements in the number list according to the threshold -- summing up the elements until you reach/over the threshold. Save the index of the first element of each group, so the desired output is:

1, 4, 5, 8, 9

1 because it's the start

4 because 1+2+5 = 8 > 6 and this include 3 elements

it is similar to this post Sum list of numbers until threshold but we want to keep adding until we reach the end of the list.

Math Avengers
  • 762
  • 4
  • 15

2 Answers2

2

You can use the function cumsumbinning from the package MESS :

numbers = c(1, 2, 5, 6, 3, 2, 3, 7, 6)
threshold = 6
which(!duplicated(MESS::cumsumbinning(numbers, threshold - 1, cutwhenpassed=TRUE), fromLast = TRUE))
#[1] 3 4 7 8 9

If you want the first element in the group.

which(!duplicated(MESS::cumsumbinning(numbers, threshold - 1, cutwhenpassed=TRUE)))
#[1] 1 4 5 8 9

cumsumbinning with cutwhenpassed=TRUE creates a new group whenever the value passes the threshold value hence I used threshold - 1.

MESS::cumsumbinning(numbers, threshold - 1, cutwhenpassed=TRUE)
#[1] 1 1 1 2 3 3 3 4 5
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
  • is there another way to do this without the MESS packages? I keep getting errors when downloading the MESS packages. – Math Avengers Mar 26 '21 at 14:09
  • Another way I can think of is messy loops. What is the issue that you are facing downloading the package? I installed it myself while trying to answer this question and I could download it without any problem using `install.packages('MESS')` – Ronak Shah Mar 27 '21 at 00:22
  • I am getting lots of errors like `ERROR: dependencies 'glmnet', 'kinship2' are not available for package 'MESS'` – Math Avengers Mar 29 '21 at 02:02
  • I think the main problem is this line `cannot find -lgfortran` – Math Avengers Mar 29 '21 at 02:07
1

I think this will also serve the purpose

library(purrr)
setdiff(which(accumulate(numbers, ~ifelse(.x + .y <  6, .y + .x, 0)) ==0), which(numbers == 0))

#check on new vector numbers
numbers = c(1, 2, 5, 6, 3, 2, 3, 7, 6, 0, 2, 3, 7, 1, 2)

setdiff(which(accumulate(numbers, ~ifelse(.x + .y <  6, .y + .x, 0)) ==0), which(numbers == 0))
[1]  3  4  7  8  9 13
AnilGoyal
  • 25,297
  • 4
  • 27
  • 45