Подтвердить что ты не робот

R - как получить значение многомерного массива вектором индексов

Скажем, у меня есть многомерный массив с именем pi, и его количество измерений неизвестно до времени выполнения:

dims <- rep(3, dim_count)
pi <- array(0, dims)

Как вы можете видеть, размерность зависит от dim_count. Как получить значение из массива, когда у меня есть вектор индексов? Например, когда у меня есть:

dim_count <- 5
indexes <- c(1, 2, 3, 3, 3)

Я хочу получить

pi[1, 2, 3, 3, 3]

Есть ли короткий, эффективный и, надеюсь, элегантный способ сделать это?

4b9b3361

Ответ 1

Использование малоизвестного использования [:

При индексировании массивов на [ один аргумент i может быть матрицей с таким количеством столбцов, как размеры x; результатом является вектор с элементами, соответствующими наборам индексов в каждой строке i.

вы можете просто:

pi[matrix(indexes, 1)]

Ответ 2

do.call("[",...), похоже, работает.

indexes <- c(1,2,3,3,3)
pi[1,2,3,3,3] <- 17  ## so we know if we succeeded or not
do.call("[",c(list(pi),as.list(indexes)))

Обратите внимание, что ваш пример не будет работать - ваши измерения были все 3, но некоторые из ваших индексных элементов были > 3...

Ответ 3

do.call() - это вариант:

dim_count <- 5
indexes <- c(1, 2, 2, 2, 3)
dims <- rep(3, dim_count)
pi <- array(seq_len(prod(dims)), dims)

do.call(`[`, c(list(x = pi), as.list(indexes)))

Что дает:

> do.call(`[`, c(list(x = pi), as.list(indexes)))
[1] 202
> pi[1, 2, 2, 2, 3]
[1] 202

Трудный бит получает список аргументов в правильном формате. pi должен быть первым аргументом "[" (или назван как аргумент x, см. ?"["), в то время как мы хотим, чтобы каждый элемент indexes сам являлся компонентом поставляемого списка, а не вектором внутри этот список. Следовательно, свернутый c(list(x = pi), as.list(indexes)).

Альтернативным способом построения списка аргументов, который может быть проще, является следующее:

ARGS <- vector("list", length = dim_count + 1)
ARGS[[1]] <- pi
ARGS[2:length(ARGS)] <- indexes
do.call("[", ARGS)

который дает

> do.call("[", ARGS)
[1] 202
> pi[1, 2, 2, 2, 3]
[1] 202