矩阵索引用另一个矩阵

时间:2017-06-02 01:44:42

标签: r matrix subset

什么是将两个矩阵(一个和两个)匹配在一起并提取匹配的矩阵二的索引的快速方法。矩阵二是大的(数百到数千行)。

one
[,1] [,2]
   9   11
  13    2


head(two)
   [,1][,2]
[1,] 9 11
[2,] 11 9
[3,]  2 3
[4,] 13 2
[5,]  2 4
[6,]  3 3

输出应该是(注意索引2不是输出值)

1 4  

4 个答案:

答案 0 :(得分:4)

这样做的一种方法:

a = apply(one, 1, paste0, collapse = "-")
b = apply(two, 1, paste0, collapse = "-")
match(a, b)

#[1] 1 4

我们将所有列按行逐行粘贴到两个矩阵中,然后匹配它们以获得相同的行。

仅供参考,

a
#[1] "9-11" "13-2"
b
#[1] "9-11" "11-9" "2-3"  "13-2" "2-4"  "3-3" 

答案 1 :(得分:1)

你可以编写一个C ++循环来快速完成它

library(Rcpp)

cppFunction('NumericVector matrixIndex(NumericMatrix m1, NumericMatrix m2){

int m1Rows = m1.nrow();
int m2Rows = m2.nrow();
NumericVector out;  

for (int i = 0; i < m1Rows; i++){
  for (int j = 0; j < m2Rows; j++){

    if(m1(i, 0) == m2(j, 0) && m1(i, 1) == m2(j, 1)){
        //out[j] = (j+1);
        out.push_back(j + 1);
    }
  }
}

return out;

}')

matrixIndex(m1, m2)
[1] 1 4

虽然我怀疑首先预先分配结果向量会更快,比如

cppFunction('NumericVector matrixIndex(NumericMatrix m1, NumericMatrix m2){

int m1Rows = m1.nrow();
int m2Rows = m2.nrow();
NumericVector out(m2Rows);  

for (int i = 0; i < m1Rows; i++){
  for (int j = 0; j < m2Rows; j++){

    if(m1(i, 0) == m2(j, 0) && m1(i, 1) == m2(j, 1)){
        out[j] = (j+1);
        //out.push_back(j + 1);
    }
  }
}

return out;

}')

matrixIndex(m1, m2)
[1] 1 0 0 4 0 0
## 0 == nomatch. 

答案 2 :(得分:1)

你不能说&#34; fast&#34;你的意思是计算时间或人的时间。如果它只需要做一次,那么如果你优化人的时间,整个时间可能是最短的,而且Ronak的答案将很难被击败,它的清晰和强大。

如果数字都小于某个数字(例如,100,如示例数据中所示),您可以执行类似的操作,但使用算术将两列组合在一起然后匹配。我怀疑(但尚未经过测试)这比转换为字符向量要快。当然,根据您的情况,还有其他算术选项。

a <- one[,1]*100 + one[,2]
b <- two[,1]*100 + two[,2]
match(a, b)

答案 3 :(得分:0)

我们可以使用%in%

which(do.call(paste, as.data.frame(two)) %in% do.call(paste, as.data.frame(one)))
#[1] 1 4