Home > Mobile >  How to go along a numeric vector and mark the index of currently minimal value until finding a small
How to go along a numeric vector and mark the index of currently minimal value until finding a small

Time:12-08

I want to obtain the indexes of minimal values such as:

v1 <- c(20, 30, 5, 18, 2, 10, 8, 4)

The result is:

1 3 5

Explanation:

Over v1, we start at value 20. Without moving on, we note the minimal value (20) and its index (1). We ignore the adjacent element because it is greater than 20. So 20 still holds the record for smallest. Then we move to 5, which is smaller than 20. Now that 5 is the smallest, we note its index (3). Since 18 isn't smaller than so-far-winner (5), we ignore it and keep going right. Since 2 is the smallest so far, it is the new winner and its position is noted (5). No value smaller than 2 moves right, so that's it. Finally, positions are:

1 # for `20` 
3 # for `5`
5 # for `2`

Clearly, the output should always start with 1, because we never know what comes next.

Another example:

v2 <- c(7, 3, 4, 4, 4, 10, 12, 2, 7, 7, 8)

# output: 
1 2 8

Which.min() seems to be pretty relevant. But I'm not sure how to use it to get the desired result.

CodePudding user response:

You can use:

which(v1 == cummin(v1))

[1] 1 3 5

If you have duplicated cumulative minimums and don't want the duplicates indexed, you can use:

which(v1 == cummin(v1) & !duplicated(v1))

Or:

match(unique(cummin(v1)), v1)

CodePudding user response:

This is the verbose way:

library(purrr)

v1 <- c(20, 30, 5, 18, 2, 10, 8, 4)

v1 %>%
  length() %>%
  seq() %>%
  map_dbl(~ which.min(v1[1: .x])) %>%
  unique()
#> [1] 1 3 5

Created on 2021-12-08 by the reprex package (v2.0.1)

  •  Tags:  
  • r min
  • Related