Насколько мне известно, не существует простого способа сделать это встроенным в R. Однако вы можете воспользоваться тем фактом, что массив на самом деле хранится как вектор с атрибутом измерения (dim
). Таким образом, вы можете получить доступ к элементам напрямую, без использования нескольких запятых. Сложность состоит в том, чтобы определить, какие индексы базового вектора представляют нужный фрагмент массива. Это просто требует немного математики.
Я думаю, вы ищете что-то вроде этого:
at <- function(Array, Dimension, Slice, index = FALSE)
{
if(!is.array(Array))
stop("'at()' can only be called on arrays")
if(!(is.numeric(Dimension) && Dimension > 0))
stop("Invalid value of Dimension supplied to 'at()'")
# Get the numbers of dimensions and elements in our Array
n <- length(Array)
dims <- dim(Array)
n_dims <- length(dims)
if(Dimension > n_dims | Dimension < 1)
stop("Invalid dimension chosen in 'at()'")
if(max(Slice) > dims[Dimension])
stop("Invalid slice chosen for given dimension")
final_result <- numeric()
for(i in seq_along(Slice))
{
run_length <- cumprod(c(1, dims)[-(n_dims + 1)])[Dimension]
skip_length <- run_length * (dims[Dimension] - 1)
# Now we simply make a repeating pattern of membership / non-membership
pattern <- rep_len(c(rep(T, run_length), rep(F, skip_length)), n)
shifted_pattern <- c(rep(FALSE, run_length * (Slice[i] - 1)), pattern)
loop_result <- which(shifted_pattern[seq(n)])
final_result <- c(final_result, loop_result)
}
if(index == FALSE)
{
dims[Dimension] <- length(Slice)
return(array(Array[final_result], dim = dims))
}
return(sort(final_result))
}
Вот как вы можете использовать это. Начнем с массива (давайте всего 3 измерения)
my_array <- array(0, dim = c(2, 3, 4))
my_array
#> , , 1
#>
#> [,1] [,2] [,3]
#> [1,] 0 0 0
#> [2,] 0 0 0
#>
#> , , 2
#>
#> [,1] [,2] [,3]
#> [1,] 0 0 0
#> [2,] 0 0 0
#>
#> , , 3
#>
#> [,1] [,2] [,3]
#> [1,] 0 0 0
#> [2,] 0 0 0
#>
#> , , 4
#>
#> [,1] [,2] [,3]
#> [1,] 0 0 0
#> [2,] 0 0 0
Теперь я могу получить индексы базового массива, которые представляют 2-ю матрицу третьего измерения (то есть my_array[, , 2]
), например:
at(my_array, 3, 2, index = T)
# [1] 7 8 9 10 11 12
Это означает, что если я напишу что-нибудь в my_array[c(7, 8, 9, 10, 11, 12)]
, это изменит элементы в соответствующем срезе матрицы:
my_array[at(my_array, 3, 2, index = T)] <- 69
my_array
#> , , 1
#>
#> [,1] [,2] [,3]
#> [1,] 0 0 0
#> [2,] 0 0 0
#>
#> , , 2
#>
#> [,1] [,2] [,3]
#> [1,] 69 69 69
#> [2,] 69 69 69
#>
#> , , 3
#>
#> [,1] [,2] [,3]
#> [1,] 0 0 0
#> [2,] 0 0 0
#>
#> , , 4
#>
#> [,1] [,2] [,3]
#> [1,] 0 0 0
#> [2,] 0 0 0
И, конечно, это означает, что мы можем сделать все oop где мы можем выбрать размеры. Здесь мы сначала сбросим my_array в нули, а затем поместим номер измерения в каждый элемент в первом срезе в этом измерении. Обратите внимание, что некоторые ячейки перезаписываются в процессе, если они принадлежат первому срезу нескольких измерений.
# Reset my_array first
my_array[] <- 0
for(i in 1:3)
{
my_array[at(my_array, i, 1, index = T)] <- i;
}
my_array
#> , , 1
#>
#> [,1] [,2] [,3]
#> [1,] 3 3 3
#> [2,] 3 3 3
#>
#> , , 2
#>
#> [,1] [,2] [,3]
#> [1,] 2 1 1
#> [2,] 2 0 0
#>
#> , , 3
#>
#> [,1] [,2] [,3]
#> [1,] 2 1 1
#> [2,] 2 0 0
#>
#> , , 4
#>
#> [,1] [,2] [,3]
#> [1,] 2 1 1
#> [2,] 2 0 0
Хотя пример для трехмерного массива, это должно работать для любого числа измерений.
Причина index = T
заключается в том, что, опуская это, мы можем напрямую получить нужный фрагмент без использования индексации:
at(my_array, 3, 1:2)
#> , , 1
#>
#> [,1] [,2] [,3]
#> [1,] 3 3 3
#> [2,] 3 3 3
#>
#> , , 2
#>
#> [,1] [,2] [,3]
#> [1,] 2 1 1
#> [2,] 2 0 0
Например, в ответе ОП вы можете использовать это сделать следующим образом:
Indexlist2 <- numeric()
for(j in 2:4)
{
if(StartPoint2QQQ[j] == 1)
{
j_matches <- which(at(MatrixQQQ, j, 1) == max(at(MatrixQQQ, j, 1)), arr.ind = T)
Indexlist2 <- rbind(Indexlist2, j_matches)
}
}
Теперь у нас есть
Indexlist2
#> dim1 dim2 dim3 dim4
#> [1,] 2 2 1 2
#> [2,] 2 2 2 1
MatrixQQQ[Indexlist2]
#> [1] 5.0 0.2