Хотя which.min
и друзья не поддерживают это напрямую, which(..., arr.ind=TRUE)
делает:
which(B == min(B), arr.ind=TRUE)
# row col
# [1,] 1 4
Очень важно примечание: при этом есть две заметки:
Это не сообщает о существовании связей;и
Это предполагает, что будет работать равенство с плавающей запятой, что склонно к Почему эти числа не равны? и R FAQ 7.31 . Таким образом, хотя это, вероятно, работает большую часть времени, возможно , что это не всегда будет работать. В случае, если он не работает, он вернет 0-строку matrix
. Одним из смягчающих шагов было бы введение допуска, такого как
which(abs(B - min(B)) < 1e-9, arr.ind=TRUE)
# row col
# [1,] 1 4
, где 1e-9
преднамеренно мал, но "мал" относительно диапазона ожидаемых значений в матрице.
Более быстрая альтернатива
Честно говоря, which.max
дает вам достаточно информации, если вы знаете размеры матрицы.
m <- which.min(B)
c( (m-1) %% nrow(B) + 1, (m-1) %/% nrow(B) + 1 )
# [1] 1 4
Для фона: matrix
в R это просто вектор, упорядоченный по столбцам.
matrix(1:15, nrow=3)
# [,1] [,2] [,3] [,4] [,5]
# [1,] 1 4 7 10 13
# [2,] 2 5 8 11 14
# [3,] 3 6 9 12 15
Таким образом, мы можем использовать модуль %%
и целочисленное деление (пол) %/%
, чтобы определить число строк и столбцов соответственно:
(1:15-1) %% 3 + 1
# [1] 1 2 3 1 2 3 1 2 3 1 2 3 1 2 3
(1:15-1) %/% 3 + 1
# [1] 1 1 1 2 2 2 3 3 3 4 4 4 5 5 5
И оказывается, что этот последний метод намного быстрее (не слишком удивительно, учитывая, что сложная часть выполнена в C):
microbenchmark::microbenchmark(
a = which(B == min(B), arr.ind=TRUE), # first answer, imperfect
b = which(abs(B - min(B)) < 1e-9, arr.ind=TRUE), # second, technically more correct
c = { # third, still correct, faster
m <- which.min(B)
c( (m-1) %% nrow(B) + 1, (m-1) %/% nrow(B) + 1 )
}, times=10000)
# Unit: microseconds
# expr min lq mean median uq max neval
# a 8.4 9.0 10.27770 9.5 10.4 93.5 10000
# b 9.0 9.6 10.94061 10.3 11.1 158.4 10000
# c 3.3 4.0 4.48250 4.2 4.7 38.7 10000