Как пройти по числовому вектору и отметить индекс текущего минимального значения, пока не будет найдено меньшее значение?

#r #min

#r #мин

Вопрос:

Я хочу получить индексы минимальных значений, таких как:

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

Результат:

 1 3 5
 

Объяснение:

Снова v1 , мы начинаем со значения 20 . Не двигаясь дальше, мы отмечаем минимальное значение ( 20 ) и его индекс ( 1 ). Мы игнорируем соседний элемент, потому что он больше 20 . So 20 по-прежнему сохраняет рекорд для наименьшего. Затем мы переходим к 5 , которое меньше, чем 20 . Теперь, когда это 5 наименьшее, мы отмечаем его индекс ( 3 ) . Поскольку 18 значение не меньше, чем so-far-winner ( 5 ) , мы игнорируем его и продолжаем движение вправо. Поскольку 2 это наименьшее значение на данный момент, оно является новым победителем, и его позиция отмечается ( 5 ). Никакое значение меньше, чем 2 перемещается вправо, вот и все. Наконец, позиции:

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

Очевидно, что вывод всегда должен начинаться с 1 , потому что мы никогда не знаем, что будет дальше.

Другой пример:

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

# output: 
1 2 8
 

Which.min() кажется, это довольно актуально. Но я не уверен, как его использовать, чтобы получить желаемый результат.

Комментарии:

1. which(v1 == cummin(v1)) может быть — как вы хотите обрабатывать дублированные кумулятивные минимумы?

2. @RitchieSacramento при наличии дубликатов возвращает индекс первого повторяющегося вхождения. Как v2 и выше.

Ответ №1:

Вы можете использовать:

 which(v1 == cummin(v1))

[1] 1 3 5
 

Если вы дублировали совокупные минимумы и не хотите, чтобы дубликаты индексировались, вы можете использовать:

 which(v1 == cummin(v1) amp; !duplicated(v1))
 

Или:

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

Ответ №2:

Это подробный способ:

 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
 

Создано 2021-12-08 пакетом reprex (v2.0.1)