R :: Как мне сопоставить строки одной матрицы со строками в другой матрице, независимо от порядка столбцов?

#r #matrix #set-intersection

#r #матрица #set-пересечение

Вопрос:

У меня есть две матрицы, и мне нужно найти, отображаются ли наборы из двух столбцов в одной матрице в другой матрице без учета порядка (A: B = B: A).

В качестве примера приведем две матрицы:

 X <- matrix(c(23, 33, 4, 21, 5, 27, 47, 39, 37, 8, 30, 42, 59, 63, 53, 50, 49, 65, 53, 59), nrow = 10, ncol = 2, byrow = F)
Y <- matrix(c(30, 21, 53, 23, 63, 37), nrow = 3, ncol = 2, byrow = F)
> X
      [,1] [,2]
 [1,]   23   30
 [2,]   33   42
 [3,]    4   59
 [4,]   21   63
 [5,]    5   53
 [6,]   27   50
 [7,]   47   49
 [8,]   39   65
 [9,]   37   53
[10,]    8   59
> Y
     [,1] [,2]
[1,]   30   23
[2,]   21   63
[3,]   53   37
  

Я хочу иметь возможность найти, например, Y[1,] в X, будь то {30,23} или {23,30} .

Я пробовал merge , intersect , и setdiff , но ни один из них не вернет все возможные совпадения.

 > merge(data.frame(X),data.frame(Y))
  X1 X2
1 21 63
> merge(data.frame(Y),data.frame(X))
  X1 X2
1 21 63
> intersect(data.frame(X),data.frame(Y))
  X1 X2
1 21 63
> intersect(data.frame(Y),data.frame(X))
  X1 X2
1 21 63
> setdiff(data.frame(Y),data.frame(X))
  X1 X2
1 30 23
2 53 37
> setdiff(data.frame(X),data.frame(Y))
  X1 X2
1 23 30
2 33 42
3  4 59
4  5 53
5 27 50
6 47 49
7 39 65
8 37 53
9  8 59 
  

Конечная цель — идентифицировать строки в X, которые содержат совпадения (с содержимым или без него). Итак, в псевдокоде это будет:

для каждого Y[i,] в X
возвращаемый номер строки X

Любая помощь будет с благодарностью.

Комментарии:

1. Как указано, ожидаемый результат представляет собой список всех совпадений. Использование match находит совпадения только там, где значения находятся в одних и тех же столбцах (Y [1,1] в X [1,1] и Y [1,2] в X [1,2]). Мне нужно найти строки, где (Y [1,1] в X [1,1] и Y [1,2] в X [1,2]) ИЛИ (Y [1,1] в X [1,2] и Y [1,2] в X[1,1]).

Ответ №1:

Мы можем sort по строке для каждого набора данных

 x1 <- t(apply(X, 1, sort))
y1 <- t(apply(Y, 1, sort))
  

а затем выполните a match для общих paste строк каждого набора данных, чтобы вернуть индекс строки соответствия

 match(do.call(paste, as.data.frame(y1)), do.call(paste, as.data.frame(x1)))
#[1] 1 4 9
  

Комментарии:

1. Хорошее, простое решение, сортировка обоих по строкам, чтобы меньшие значения всегда были впереди. Вещи, которые вы упускаете из виду, когда бьетесь головой о стену! Спасибо тебе за это, @akrun!

Ответ №2:

Вы могли бы использовать merge подход, который вы пробовали после сортировки каждой строки и проверки индекса строки в X dataframe.

 x1 <- transform(data.frame(t(apply(X, 1, sort))), row = 1:nrow(X))
y1 <- data.frame(t(apply(Y, 1, sort)))
merge(x1, y1)

#  X1 X2 row
#1 21 63   4
#2 23 30   1
#3 37 53   9