简体   繁体   中英

replace matrix values in R with rownames another matrix

I have a question about matching two matrices in R to perform a very simple calculation. I have working code (below), but I feel like there must be a more efficient and 'R-like' way to do it. Any clues very welcome.

The Problem

I have two matrices with related information. m1 contains a bunch of references. m2 contains data on those references (zeros or ones). I want to know which rows of m1 have a '0' in the first column and a '1' in the second column when you look up the data from m2. Here's a toy example:

> m1 <- matrix(data = c(51,52,53,51,54,55,56,57), nrow = 4, ncol = 2)
> m1
     [,1] [,2]
[1,]   51   54
[2,]   52   55
[3,]   53   56
[4,]   51   57

> m2 <- matrix(data = c(0,0,1,0,0,1,1), nrow = 7, ncol = 1)
> rownames(m2) <- c(51,52,53,54,55,56,57)
> m2
   [,1]
51    0
52    0
53    1
54    0
55    0
56    1
57    1

General properties are that I can already guarantee that every entry in m1 has a corresponding row name in m2, and I need to do this many millions of times on much larger matrices, so speed is useful.

What I want to do is use m2 to figure out which rows of m1 have a zero in the first column, and a 1 in the second column. In this case, only the final row of m1 has that property.

My Solution

I have a relatively OK solution to this, which uses apply() and is not too bad:

> is.zero.one <- function(line, m2){
+    start = m2[as.character(line[1]),]
+    end   = m2[as.character(line[2]),]
+    if(start==0 && end==1){return(TRUE)}   
+    else{return(FALSE)}
+} 
> apply(m1, 1, is.zero.one, m2)
[1] FALSE FALSE FALSE  TRUE

This works fine. But it feels clunky.

My question

Does anyone know of a smarter/faster/more natural way to do this? I had a look at match() and related functions, but couldn't come up with a solution. Ditto for searching around related questions here. Part of the reason for my question is that I'm not a very good R programmer, so even if this turns out to be a decent solution, I'd be very interested to see how others would solve it.

Thanks for any help.

 matrix( m2[ match(m1, rownames(m2) )], ncol=2)
     [,1] [,2]
[1,]    0    0
[2,]    0    0
[3,]    1    1
[4,]    0    1

m3 <- matrix(m2[match(m1, rownames(m2) )], ncol=2)

 which( m3[,1]==0 & m3[,2]==1 )
#[1] 4

  m3[,1]==0 & m3[,2]==1 
# [1] FALSE FALSE FALSE  TRUE

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM