2016-05-07 3 views
4
m = matrix(1:10, nrow = 5, ncol = 2) 
y = c(1,2,2,1,1) 

Я хочу вектор v которого i-й элемент m[i,y[i]].Индексирование матрицы на вектор

Я думал, что m[,y] сделает это, но это явно неправильно.

+1

Не ясно, как вы хотите, чтобы определить 'i', скажем, длина' V'. – SabDeM

+0

Как насчет 'v <- sapply (1: nrow (m), function (x) m [x, y [x]])' –

+0

И еще одно актуальное обсуждение предыдущего вопроса - http://stackoverflow.com/questions/35022161/matrix-indexing-r – thelatemail

ответ

6

Вы можете использовать cbind() для создания матрицы, которая будет использоваться для индексирования.

m[cbind(seq_along(y), y)] 
# [1] 1 7 8 4 5 
4

Кроме того, поскольку в данном случае мы выбираем строки 1, 2, ..., nrow(m),

diag(m[, y]) 
# [1] 1 7 8 4 5 
+2

Это очень неэффективно. Пусть 'y = sample (c (1,2), 10^6, replace = TRUE)' и 'm = matrix (1: (2 * 10^6), nrow = 10^6, ncol = 2)'. 'system.time (m [cbind (seq_along (y), y)]' возвращает правильный результат менее чем за секунду. Попробуйте сделать тот же пример с приведенным выше кодом. –

+5

@rawr - аргументы за миллисекунды раздражают да, но в этом случае 'diag' в значительной степени убивает возможность даже запускать эту функцию. Индексирование матрицы по примеру 10^5 от Джозефа проходит через 0,007 секунды на моей древней двухъядерной машине.' diag' терпит неудачу с «... не может выделить вектор размером 37,3 ГБ ». Очень немногие люди имеют 37 ГБ бара, лежащего вокруг. – thelatemail

+2

Хотя я согласен с вашими комментариями, не все всегда работают с матрицами размером 10^5, и никогда не мешает осознавать другой подход. но, видимо, это причиняет кому-то боль, чтобы уменьшить ответ, который действительно решает проблему. – Julius