1
votes

I am a programming newbie attempting to compare two matrices. In case an element from first column in mat1 matches any element from first column in mat2, then I want that matching element in mat1 to be replaced with the neighboor (same row different column) to the match in mat2.

INPUT:

mat1<-matrix(letters[1:5])
mat2<-cbind(letters[4:8],1:5)

> mat1
     [,1]
[1,] "a" 
[2,] "b" 
[3,] "c" 
[4,] "d" 
[5,] "e" 

> mat2
     [,1] [,2]
[1,] "d"  "1" 
[2,] "e"  "2" 
[3,] "f"  "3" 
[4,] "g"  "4" 
[5,] "h"  "5" 

wished OUTPUT:

> mat3
     [,1]
[1,] "a" 
[2,] "b" 
[3,] "c" 
[4,] "1" 
[5,] "2" 

I have attempted the following without succeeding:

> for(x in mat1){mat3<-ifelse(x==mat2,mat2[which(x==mat2),2],mat1)}
> mat3
     [,1] [,2]
[1,] "a"  "a" 
[2,] "2"  "b" 
[3,] "c"  "c" 
[4,] "d"  "d" 
[5,] "e"  "e" 

Any advice will be very appreciated. Have spent a whole day without making it work. It doesn't matter to me if the elements are in a matrix or a data frame.

Thanks.

3

3 Answers

2
votes

ifelse is vectorized so, we can use it on the whole column. Create the test logical condition in ifelse by checking whether the first column values of 'mat1' is %in% the first column of 'mat2', then , get the index of the corresponding values with match, extract the values of the second column with that index, or else return the first column of 'mat1'

mat3 <- matrix(ifelse(mat1[,1] %in% mat2[,1],
         mat2[,2][match(mat1[,1], mat2[,1])], mat1[,1]))
mat3
#     [,1]
#[1,] "a" 
#[2,] "b" 
#[3,] "c" 
#[4,] "1" 
#[5,] "2" 
1
votes

Here is another base R solution

v <- `names<-`(mat2[,2],mat2[,1])
mat3 <- matrix(unname(ifelse(is.na(v[mat1]),mat1,v[mat1])))

which gives

> mat3
     [,1]
[1,] "a" 
[2,] "b" 
[3,] "c" 
[4,] "1" 
[5,] "2" 
1
votes

An option just using logical operation rather than a function

mat3 <- mat1
mat3[mat1[,1] %in% mat2[,1], 1] <- mat2[mat2[,1] %in% mat1[,1], 2]

Subsetting the values to find those that occur in both and replacing them where they do