Home > database >  In R how do I sample one non-zero element from each column of a matrix and then -1 from it
In R how do I sample one non-zero element from each column of a matrix and then -1 from it

Time:06-09

I have a matrix called MyMatrix:

a<-c(1,2,0)
b<-c(0,5,0)
c<-c(8,9,2)
d<-c(5,2,0)

MyMatrix<-cbind(a,b,c,d)

     a b c d
[1,] 1 0 8 5
[2,] 2 5 9 2
[3,] 0 0 2 0

From MyMatrix I would like to -1 from an element in every column, but only if the element is >0.

For example, the resulting matrix might be:

     a b c d
[1,] 0 0 8 5
[2,] 2 4 8 1
[3,] 0 0 2 0

How might I achieve this?

CodePudding user response:

Try this:

safeSample<-function(x) {if (length(x)==1) x else sample(x, 1)}
apply(MyMatrix, 2, 
      function(x) {
          ind<-safeSample(which(x>0)) 
          x[ind]<-x[ind]-1 
          x
      }
)

CodePudding user response:

Update

As per the feedback, I previously misunderstood the objective, but I guess the following apply way should work

apply(
    MyMatrix,
    2,
    function(v) {
        k <- which(v > 0)
        idx <- sample(seq_along(k), 1)
        replace(v, k[idx], v[k[idx]] - 1)
    }
)

which gives

     a b c d
[1,] 0 0 6 5
[2,] 1 4 9 1
[3,] 0 0 2 0

We can do like this using sample to generate the random indices that should be subtracted by 1 if its entry is greater than 0

idx <- cbind(
    sample(nrow(MyMatrix), ncol(MyMatrix), TRUE),
    1:ncol(MyMatrix)
)
MyMatrix[idx] <- MyMatrix[idx] - (MyMatrix[idx] > 0)
  • Related