2016-06-29 4 views
1

Я ищу быстрый способ возврата индексов столбцов матрицы, соответствующих значениям, указанным в векторе (в идеале от 1-й длины или столько же, сколько число строки в матрице) , например:Возвращаемые значения столбцов столбца матрицы в R

mat <- matrix(1:100,10) 
values <- c(11,2,23,12,35,6,97,3,9,10) 

нужную функцию, которую я называю rowMatches() бы вернуть:

rowMatches(mat, values) 
[1] 2 1 3 NA 4 1 10 NA 1 1 

Действительно, значение 11 впервые встречается на 2-м столбце первой строки, значение 2 появляется в первом столбце второй строки, значение 23 i s в третьем столбце 3-й строки, значение 12 не находится в 4-й строке ... и так далее.

Поскольку я не нашел какого-либо решения в пакете matrixStats, я пришел с этой функцией:

rowMatches <- function(mat,values) {    
    res <- integer(nrow(mat)) 
    matches <- mat == values 
    for (col in ncol(mat):1) { 
     res[matches[,col]] <- col 
    } 
    res[res==0] <- NA 
    res 
} 

Для моего предполагаемого использования, будут миллионы строк и несколько столбцов. Поэтому разбиение матрицы на строки (в списке, называемом, например, rows), и вызов Map(match, as.list(values), rows) будет слишком медленным.
Но меня не удовлетворяет моя функция, потому что есть цикл, который может быть медленным, если есть много столбцов. Должно быть возможно использовать apply() на столбцах, но это не ускорится.

Любые идеи?

+1

Посмотреть 'max.col' - вы можете использовать' max.col (спички, "первый") 'и использовать' NA' где бы то ни было 'rowSums (совпадения) == 0L' –

+0

Отлично! Я не знал о 'max.col()'. Вы можете опубликовать это решение, и я его проверю. (для mtoto в результатах поиска есть «NA» в соответствующем индексе) – jeanlain

ответ

0
res <- arrayInd(match(values, mat), .dim = dim(mat)) 
res[res[, 1] != seq_len(nrow(res)), 2] <- NA 
#  [,1] [,2] 
# [1,] 1 2 
# [2,] 2 1 
# [3,] 3 3 
# [4,] 2 NA 
# [5,] 5 4 
# [6,] 6 1 
# [7,] 7 10 
# [8,] 3 NA 
# [9,] 9 1 
#[10,] 10 1 
0

ответ Роланда это хорошо, но я выложу альтернативное решение:

res <- which(mat==values, arr.ind = T) 
res <- res[match(seq_len(nrow(mat)), res[,1]), 2] 
Смежные вопросы