查找矩阵之间的公共值,并使用行列位置返回矩阵

时间:2018-11-29 15:01:48

标签: r matrix

我想在共享值之间求矩阵,并在matrix中返回位置(行列)。

set.seed(123)
m <- matrix(sample(4), 2, 2, byrow = T)
# m
#      [,1] [,2]
# [1,]    2    3
# [2,]    1    4
m2 <- matrix(sample(4), 2, 2, byrow = F)
# m2
#      [,1] [,2]
# [1,]    4    2
# [2,]    1    3

预期输出:

#    [,1]  [,2]
# [1,] NA    NA  
# [2,] "2-1" NA 

如果可以将其推广到不同的矩阵(不同的dim),则奖励。

4 个答案:

答案 0 :(得分:2)

大小相等

一个选项是

replace(m * NA, m == m2, paste(row(m), col(m), sep = "-")[m == m2])
#      [,1]  [,2]
# [1,] NA    NA  
# [2,] "2-1" NA  

不同的尺寸

我相信在这种情况下,无论采用哪种方法,您都首先需要将两个矩阵修整为相等的大小。

set.seed(12)
(m <- matrix(sample(6), 2, 3, byrow = TRUE))
#      [,1] [,2] [,3]
# [1,]    1    5    4
# [2,]    6    3    2
(m2 <- matrix(sample(6), 3, 2, byrow = FALSE))
#      [,1] [,2]
# [1,]    2    5
# [2,]    4    3
# [3,]    1    6

out <- matrix(NA, max(nrow(m), nrow(m2)), max(ncol(m), ncol(m2)))
mrow <- min(nrow(m), nrow(m2))
mcol <- min(ncol(m), ncol(m2))
mTrim <- m[1:mrow, 1:mcol]
m2Trim <- m2[1:mrow, 1:mcol]
out[1:mrow, 1:mcol][mTrim == m2Trim] <- paste(row(mTrim), col(mTrim), sep = "-")[mTrim == m2Trim]
out
#      [,1] [,2]  [,3]
# [1,] NA   "1-2" NA  
# [2,] NA   "2-2" NA  
# [3,] NA   NA    NA 

答案 1 :(得分:1)

此函数提供所需的输出,但在两个矩阵之间dim()相等的情况下起作用。

为了将其推广到不同的矩阵,解决方案是先将较大的矩阵子集化。

关键是which(mat1==mat2, arr.ind=T)以获取行列索引:

 which(m==m2, arr.ind=T)
     row col
[1,]   2   1

在函数内部:

find_in_matr <- function(mat1, mat2) {

  if (!all(dim(mat1) == dim(mat2))) {
    stop("mat1 and mat2 need to have the same dim()!")
  }

  m <- mat1 
  m[] <- NA # copy mat1 dim, and empty values

  loc <- which(mat1==mat2, arr.ind=T) # find positions (both indxs)

  m[loc] <- mapply(paste, sep="-", loc[, 1], loc[, 2]) # paste indxs
  return(m)
}

示例:

set.seed(123)
m <- matrix(sample(4), 2, 2, byrow = T)
# m
#      [,1] [,2]
# [1,]    2    3
# [2,]    1    4
m2 <- matrix(sample(4), 2, 2, byrow = F)
# m2
#      [,1] [,2]
# [1,]    4    2
# [2,]    1    3

find_in_matr(m, m2)
#    [,1]  [,2]
# [1,] NA    NA  
# [2,] "2-1" NA 

答案 2 :(得分:1)

傻瓜管道版本

library(magrittr)

(m == m2) %>% 
  `[<-`(!., NA) %>% 
  `[<-`((w <- which(., arr = T)), apply(w, 1, paste, collapse = '-'))

#      [,1]  [,2]
# [1,] NA    NA  
# [2,] "2-1" NA  

答案 3 :(得分:1)

我尝试用ifelse()来做到这一点:

x <- apply(which(m == m2, arr.ind = T), 1, paste, collapse = "-")
ifelse(m != m2, NA, x)

#     [,1]  [,2]
# [1,] NA    NA  
# [2,] "2-1" NA 

此方法可以处理任何尺寸。

例如

set.seed(999)
m1 <- matrix(sample(1:3, 12, replace = T), 3, 4)
m2 <- matrix(sample(1:3, 12, replace = T), 3, 4)

x <- apply(which(m1 == m2, arr.ind = T), 1, paste, collapse = "-")
ifelse(m1 != m2, NA, x)

#      [,1]  [,2]  [,3]  [,4] 
# [1,] NA    "1-4" NA    "3-4"
# [2,] NA    NA    "2-3" NA   
# [3,] "2-3" NA    NA    "1-2"