Удалить матрицу, содержащуюся в другом - PullRequest
0 голосов
/ 02 декабря 2018

У меня есть две матрицы:

> A
      [,1] [,2] [,3] [,4] [,5]
 [1,]    1    1    1    2    3
 [2,]    6    1    2    3    2
 [3,]    8    1    1    3    2
 [4,]    3    1    1    1    1
 [5,]    7    2    1    2    2
 [6,]    4    2    2    2    1
 [7,]    5    2    2    3    2
 [8,]    2    2    1    2    3
 [9,]    9    1    1    3    3

и

> B
      [,1] [,2] [,3] [,4] [,5]
 [1,]    7    2    1    2    2
 [2,]    4    2    2    2    1
 [3,]    5    2    2    3    2

Матрица B содержится в A (строки 5,6,7 из A).Я пытаюсь написать код, который удаляет строки B из A, то есть производит такую ​​матрицу:

      [,1] [,2] [,3] [,4] [,5]
 [1,]    1    1    1    2    3
 [2,]    6    1    2    3    2
 [3,]    8    1    1    3    2
 [4,]    3    1    1    1    1
 [5,]    2    2    1    2    3
 [6,]    9    1    1    3    3

Ответы [ 2 ]

0 голосов
/ 02 декабря 2018

Предполагая, что A и B имеют одинаковое количество столбцов, и существует только одно совпадение B в пределах A,

aux <- function(m) paste0(c(t(m)), collapse = "")
A[-1:-nrow(B) - (gregexpr(aux(B), aux(A))[[1]] - 1)[1] / (2 * ncol(A)), ]
#      [,1] [,2] [,3] [,4] [,5]
# [1,]    1    1    1    2    3
# [2,]    6    1    2    3    2
# [3,]    8    1    1    3    2
# [4,]    3    1    1    1    1
# [5,]    2    2    1    2    3
# [6,]    9    1    1    3    3

Здесь aux преобразует матрицув строку, например,

aux(B)
# [1] "7,2,1,2,2,4,2,2,2,1,5,2,2,3,2"

и gregexpr(aux(B), aux(A)) находит B в A.Остальное преобразует указанную позицию aux(B) в aux(A) в строки A, которые нужно удалить.

То есть это удаляет матрицу B из A в целом.Проблема возникла бы, если бы B началось, скажем, в середине некоторого ряда A.

0 голосов
/ 02 декабря 2018

Одним из способов будет использование anti_join из dplyr:

require(dplyr) 
as.matrix(anti_join(as.data.frame (A), as.data.frame (B)))

Это предполагает, что вы хотите удалить отдельные строки, которые появляются в B из A. Это не будет работать, если вы хотите удалитьтолько экземпляры всей матрицы В.

===

Давайте попробуем другой вариант, основанный на превосходном решении Юлиуса (если вы решите пойти с этим, пожалуйста, примите решение Юлиуса, а не это - я просто пытаюсь увидетьесли я могу улучшить его):

Сначала давайте создадим более сложный пример:

A<-structure(c(1, 6, 8, 3, 7, 4, 5, 2, 9, 7, 4, 5, 1, 2, 2, 3, 1, 
1, 1, 1, 2, 2, 2, 2, 1, 2, 2, 2, 1, 2, 1, 2, 1, 2, 1, 1, 1, 2, 
2, 1, 1, 1, 2, 2, 7, 4, 5, 1, 2, 3, 3, 1, 2, 2, 3, 2, 3, 2, 2, 
3, 2, 2, 2, 1, 3, 2, 2, 1, 2, 1, 2, 3, 3, 2, 1, 2, 1, 2, 2, 1
), .Dim = c(16L, 5L))

Эта матрица имеет два полных экземпляра B и один дополнительный экземпляр B, который начинается всередина строки 13 и заканчивается в середине строки 16:

      [,1] [,2] [,3] [,4] [,5]
 [1,]    1    1    1    2    3
 [2,]    6    1    2    3    2
 [3,]    8    1    1    3    2
 [4,]    3    1    1    1    1
 [5,]    7    2    1    2    2
 [6,]    4    2    2    2    1
 [7,]    5    2    2    3    2
 [8,]    2    2    1    2    3
 [9,]    9    1    1    3    3
[10,]    7    2    1    2    2
[11,]    4    2    2    2    1
[12,]    5    2    2    3    2
[13,]    1    1    7    2    1
[14,]    2    2    4    2    2
[15,]    2    1    5    2    2
[16,]    3    2    1    1    1

Теперь давайте попробуем изменить решение Юлиуса, чтобы удалить оба «реальных» экземпляра B, но не «случайный» экземпляр, которыйпроисходит в середине строки:

aux <- function(m) paste0(c(t(m)), collapse = "") # Julius's original aux function
locsaux<-gregexpr(aux(B),aux(A))[[1]] #obtaining the locations of instances of B within A
locations<-((locsaux[(locsaux-1)%%ncol(A)==0]-1)/ncol(A))+1 # first, making sure the locations occur at the start of a line, then translating them to row number in A
A[-unlist(sapply(locations, function(x) seq(x,x+nrow(B)-1),simplify=FALSE)),] # removing the rows identified in previous lines plus the subsequent n-1 rows, where n is the number of rows in B

Результат:

      [,1] [,2] [,3] [,4] [,5]
 [1,]    1    1    1    2    3
 [2,]    6    1    2    3    2
 [3,]    8    1    1    3    2
 [4,]    3    1    1    1    1
 [5,]    2    2    1    2    3
 [6,]    9    1    1    3    3
 [7,]    1    1    7    2    1
 [8,]    2    2    4    2    2
 [9,]    2    1    5    2    2
[10,]    3    2    1    1    1

Успех!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...