2017-01-21 5 views
1

Предположим, что у меня есть матрица m x n M1 и k x l матрица M2 с l < = n. Я хочу найти все эти строки в M1, которые содержат в себе некоторую строку M2.Найдите строки матрицы, содержащие строки другой матрицы.

Для примера рассмотрим следующую ситуацию:

> M1 <- matrix(c(1,2,3,4,5,6,7,8,9), nrow = 3, ncol = 3, byrow = TRUE) 
> M2 <- matrix(c(1,3,8,9), nrow = 2, ncol = 2, byrow = TRUE) 
> M1 
     [,1] [,2] [,3] 
[1,] 1 2 3 
[2,] 4 5 6 
[3,] 7 8 9 
> M2 
     [,1] [,2] 
[1,] 1 3 
[2,] 8 9 

Затем ряды один и три М1 выполнить условие, в строке один содержит 1 и 3 и последней строки 8 и 9.

Так как для достижения этого эффективным способом? Я написал код с использованием циклов, но поскольку я работаю с очень большими матрицами, это решение занимает много времени.

+0

Вы можете подумать о представлении 'M1' и' M2' как 'table (row (M1), factor (M1, 1: 9))' и 'table (row (M2), factor (M2, 1: 9)) ', соответственно. Таким образом, вы можете найти любую связь между строками более простым способом. Падение на редкие альтернативы, так как иначе будут проблемы с памятью, 'library (Matrix); tab1 = sparseMatrix (i = строка (M1), j = M1, x = 1L); tab2 = sparseMatrix (i = строка (M2), j = M2, x = 1L); tcrossprod (tab1, tab2) '. Последний объект подсчитывает совпадения между каждой строкой 'M1' и' M2' и может быть сравнен с 'nrow (M2)' для извлечения вашего результата. –

+0

@StefanH Если какой-либо из нижеприведенных ответов решает вашу проблему, пожалуйста, подумайте о ее маркировке. –

ответ

1

Более общий пример:

M1 <- matrix(c(1,2,3,1,2,3,4,5,6,7,8,9,10,11,12,13,1,2), nrow = 6, ncol = 3, byrow = TRUE) 
M2 <- matrix(c(1,2,6,9, 10,11,16,17, 19, 2), nrow = 5, ncol =2, byrow = TRUE) 

Во-первых, использовать match, чтобы найти индексы значений соответствия в M1.

ind <- match(M1, M2) 

Теперь, используя моды оператора %% с индексами и количеством строк, вы найдете строки. Это работает, потому что индексы всегда будут содержать строку M2, а также общее количество строк, поэтому числа в одной строке возвратят тот же результат.

rows <- ind %% nrow(M2) 

Затем m представляет собой матрицу, содержащую номер строки совпадающих значений между M1 и M2. Линии будут выбраны, только если один и тот же индекс появится в той же строке 2 раза (или, более общо, число раз, равное числу столбцов в M2). Это гарантирует, что строка M1 будет рассмотрена только в том случае, если она содержит все элементы строки в M2.

m <- matrix(rows, nrow = nrow(M1)) 
matchRows <- apply(m, 1, duplicated, incomparables = NA) 
M1rows <- which(colSums(matchRows)==ncol(M2)-1) 
+0

Третья строка кажется мне волшебной, я не знаю, почему это работает, она также работает в общем случае? – StefanH

+0

@StefanH Я обновил сообщение, добавив более общий пример и объяснив код. Надеюсь, это яснее. –

+0

Хорошо, вижу. Спасибо, но я не имел в виду эту проблему. Ваше решение просто работает, если все строки M2 содержатся где-то в строках M1. Но это не так, рассмотрим M2 <- матрицу (c (1,4,8,910,11,16,17), nrow = 4, ncol = 2, byrow = TRUE), где результат неверен.Изобразите строки в M2 как числа, для которых я хочу знать, содержатся ли они в строках M1, где совершенно верно, что только одно число встречается в строке M1, но в этих случаях я не хочу рассчитывать. – StefanH

1

Этот метод будет проверять каждую строку из М2 и возвращает индекс строки из M1, если он содержится или НС в случае, если это не

M1 <- matrix(c(1,2,3,4,5,6,7,8,9), nrow = 3, ncol = 3, byrow = TRUE) 
> M1 
    [,1] [,2] [,3] 
[1,] 1 2 3 
[2,] 4 5 6 
[3,] 7 8 9 

M2 <- matrix(c(1,3,8,5,4,5,1,2), nrow = 4, ncol = 2, byrow = TRUE) 
> M2 
    [,1] [,2] 
[1,] 1 3 
[2,] 8 5 
[3,] 4 5 
[4,] 1 2 

y = apply(M2,1,function(x){ 
    z = unique(which(M1 %in% x)%%nrow(M1)) 
    ifelse(length(z)==1,ifelse(z==0,nrow(M1),z),NA) 
}) 

> y 
[1] 1 NA 2 1 

Это означает, что строка 2 от М2 не в M1, а строки 1 и 4 из M2 находятся в строке 1 в M1. Также строка 3 в M2 находится в строке 2 в M1.

+0

Спасибо за ваш ответ, но это не работает, если несколько строк M2 встречаются несколько раз, например, для M1 = matrix (c (1,2,3,1,2,3,4,5,6,7,8) , 9), nrow = 4, ncol = 3, byrow = TRUE). – StefanH

Смежные вопросы