Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replace matrix/dataframe values found in column i with i-th element of vector

Supose you have a 3 by 3 matrix m with one or more zeros and you want to replace each zero by a given number.

The replacement must follow this rule:

If a zero is found on first column of m, then it should be replaced with the first element of vector v, if a zero is found on second column of m, then it should be replaced with the second element of vector v, and the same for the third column/vector element.

The matrix and the vector are:

m <- matrix(c(0,2,3,4,0,6,0,8,0), 3, 3, byrow = TRUE)
v <- c(1,5,9)

Of course, the length of v must match the number of columns in m. So the matrix is like this:

0 2 3
4 0 6
0 8 0

I want that whenever R finds a zero in the first column of m it replaces it by the first element of vector v, and so on, so that the final result would be:

1 2 3
4 5 6
1 8 9

I have done a lot of research and havent found a solution for this problem. Can someone please help?

like image 577
Eduardo Avatar asked Mar 12 '23 20:03

Eduardo


2 Answers

m + t((t(m) == 0) * v)
#     [,1] [,2] [,3]
# [1,]    1    2    3
# [2,]    4    5    6
# [3,]    1    8    9

or

m + sweep(m == 0, 2, v, `*`)
#      [,1] [,2] [,3]
# [1,]    1    2    3
# [2,]    4    5    6
# [3,]    1    8    9
like image 98
Julius Vainora Avatar answered Mar 16 '23 00:03

Julius Vainora


I thought your proposed solution is wrong and here is a solution to thep problem described in your text. When which is called with .arr.ind=TRUE it returns a two column matrix which can be used for matrix or dataframe indexing as i,i reference. In this case you can also use its second column as an index to the v-object.

> m[ which(m==0, arr.ind=TRUE) ] <- v[ which(m==0, arr.ind=TRUE)[,2] ]
> m
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
[3,]    1    8    9
like image 39
IRTFM Avatar answered Mar 16 '23 00:03

IRTFM