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?
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
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With