Как сохранить индексацию в пределах вектора?

#r

#r

Вопрос:

Как можно индексировать вектор по кругу?

У меня есть вектор чисел. Я хотел бы индексировать этот вектор по одному (например, i [1], i[2] …). Однако после index_n > length(i) я хотел бы, чтобы индекс снова «обводил» вектор по кругу. снова.

 i = c("cat", "dog", "ghost")
i[4] # 4 is 1 greater than than the length of the vector, i want to return the first element "cat"
## > NA
  

Есть много способов, которыми я мог бы сделать это с помощью логических операторов. Мне интересно, существует ли функция, которая это уже делает.

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

1. Пользовательская функция с использованием MOD()?

Ответ №1:

Встроенной функции нет, но вы можете написать свою собственную

 looper <- function(x, i) {
   x[ (i-1) %% length(x)   1 ]
}

i <- c("cat", "dog", "ghost")
looper(i, 3)
# [1] "ghost"
looper(i, 4)
# [1] "cat"
looper(i, 10)
# [1] "cat"
looper(i, 11)
# [1] "dog"
  

Это также будет работать с векторами индексов

 looper(i, 1:7)
# [1] "cat"   "dog"   "ghost" "cat"   "dog"   "ghost" "cat"  
  

И если вы действительно хотите пофантазировать, вы могли бы создать класс и перезаписать его функцию индексирования. Например

 `[.looper` <- function(x, i) {
    x <- unclass(x)
    x[ (i-1) %% length(x)   1 ]
}
make_looper <- function(x) {
    class(x) <- "looper"
    x
}
  

Тогда вы могли бы сделать

 x <- make_looper(i)
x[1]
# [1] "cat"
x[2]
# [1] "dog"
x[3]
# [1] "ghost"
x[4]
# [1] "cat"
  

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

1. Всегда можно перезаписать [ , чтобы она автоматически зацикливалась 😉 (нет, на самом деле я не рекомендую это как окончательное решение … можете ли вы представить, как все могло бы сломаться, если бы это поведение изменилось для всего?)

2. @r2evans На самом деле, это интересный вопрос. Интересно, сколько людей полагаются на неявное значение NA, возвращаемое при индексации за пределами обычных границ. Я предполагаю, что часть, которую было бы легче запутать, заключается не в извлечении значений, а в их присвоении. Я бы предположил, что люди с большей вероятностью присваивают несуществующим значениям с целью добавления новых значений, а не замены существующих значений.