如何通过另一个矩阵的值来筛选矩阵

4

I have 2 matrices: m1 and m2.

m1:

    1   2   3   4   5
1  v11 v12 v13 v14 v15
2  v21 v22 v23 v24 v25
3  v31 v32 v33 v34 v35 
4  v41 v42 v43 v44 v45
5  v51 v52 v53 v54 v55

m2:

 x1, x2
 1   1
 1   2
 1   4
 2   2
 2   3    
 2   5    

如果行名和列名在m2中找到,则只保留m1,否则将“NA”写入该位置。

例如,结果应为:

m1:

    1   2   3   4   5
1  v11 v12 NA  v14  NA
2  NA  v22 v23  NA v25
3  NA  NA  NA  NA  NA 
4  NA  NA  NA  NA  NA
5  NA  NA  NA  NA  NA

到目前为止,我尝试使用了以下内容:

m1[!(rownames(m1) %in% m2$x1 & colnames(m1) %in% m1$x2)]<-NA

结果不正确?有什么建议吗?

1
你能澄清一下 m2 中的值是索引还是数据的 dimnames 吗?(不幸的是,在这个例子中,它们是相同的。) - A5C1D2H2I1M1N2O1R2T1
2个回答

2

在我之前的回答中,我认为OP想要根据m2m1选择特定的元素。如果m1的dimnames与行列索引对齐,并且m2包含整数而不是字符值,则Hong Ooi的答案非常有效。如果它们不一定对齐,这里是一个粗略的解决方案。

m1 <- matrix(c("V11","V21","V12","V22","V13","V23"),nrow=2,ncol=3)
dimnames(m1) <- list(c("r2","r1"),c("c1","c2","c3"))
m2 <- matrix(c("r1","r1","r2","c1","c3","c3"),nrow=3,ncol=2)

> m1
   c1    c2    c3   
r2 "V11" "V12" "V13"
r1 "V21" "V22" "V23"

> m2
     [,1] [,2]
[1,] "r1" "c1"
[2,] "r1" "c3"
[3,] "r2" "c3"

temp <- matrix(TRUE,nrow=nrow(m1),ncol=ncol(m1))

for(i in 1:nrow(m2)){
  temp[which(rownames(m1)==m2[i,1]),which(colnames(m1)==m2[i,2])] <- FALSE
}

m1[temp] <- NA

> m1
   c1    c2 c3    
r2 NA    NA "V13"
r1 "V21" NA "V23"

旧答案:

m1 <- matrix(c("V11","V21","V12","V22","V13","V23"),nrow=2,ncol=3)

> m1
     [,1]  [,2]  [,3] 
[1,] "V11" "V12" "V13"
[2,] "V21" "V22" "V23"

m2 <- matrix(c(1,1,2,1,3,3),nrow=3,ncol=2)

> m2
     [,1] [,2]
[1,]    1    1
[2,]    1    3
[3,]    2    3

keep <- paste(paste0(m2[,1],m2[,2]),collapse="|")
m1[!grepl(keep,m1)] <- NA

> m1
     [,1]  [,2] [,3] 
[1,] "V11" NA   "V13"
[2,] NA    NA   "V23"

或者作为一行代码:
m1[!grepl(paste(paste0(m2[,1],m2[,2]),collapse="|"),m1)] <- NA

感谢分享一些可供使用的数据,但您的结果似乎不正确。 - A5C1D2H2I1M1N2O1R2T1
@AnandaMahto请查看编辑。我相信现在是正确的。我错误地初始化了m1 - dayne
有趣的答案。我没有想到“m2”中的数字代表名称的一部分。我以为它们是行和列的索引来匹配(或者作为他们尝试解决方案中所指示的行名和列名)。 - A5C1D2H2I1M1N2O1R2T1
@AnandaMahto 哦!我明白你的意思了。我的答案确实忽略了dimnames。从某种意义上说,Hong Ooi提供的答案也是如此,因为他/她的答案只考虑了行/列索引。 - dayne
1
加1分鼓励额外努力 :). 另一种选择是创建一个新的“匹配”矩阵,如下所示 matches <- cbind(match(m2[, 1], rownames(m1)), match(m2[, 2], colnames(m1))),然后使用 @HongOoi 的方法(即,创建一个 NA 矩阵,然后使用 m3[matches] <- m1[matches])。 - A5C1D2H2I1M1N2O1R2T1
@AnandaMahto 我知道一定有更好的非for循环解决方案。谢谢! - dayne

2
我可以想出一个两行代码:

我能提供两句话:

m <- m1[NA,]
m[m2] <- m1[m2]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接