Subtraction from random values ​​in a weighted matrix in R

and in advance for your help!

This question is related to the one I posted before , but I think it deserves its own message, because it is a separate challenge.

Last time I asked about a random selection of values ​​from a matrix after adding a vector. In this example, the matrix and the vector were binary. Now I would like to change the values ​​in the weighted matrix after adding the weighted vector. Here is a sample code to play.

require(gamlss.dist) mat1<-matrix(c(0,0,0,0,1,0, 0,10,0,0,0,5, 0,0,0,0,1,0, 0,0,3,0,0,0, 0,0,0,0,3,0, 0,0,2,0,0,0, 2,1,0,1,0,1, 0,0,0,0,37,0, 0,0,0,2,0,0, 0,0,0,0,0,1, 1,0,0,0,0,0, 0,1,1,0,0,0), byrow=T, ncol=6, nrow=12) vec1<-c(0,0,0,1,1,1) ones <- which(vec1 == 1L) temp=rZIP(sum(vec1)) #rZIP is a function from gamlss.dist that randomly selects values from a zero-inflated distribution vec1[ones]<-temp 

The values ​​in the vector are selected from a distributed one with a zero distribution (thanks to this question ). When I bind a vector to a matrix, I want to randomly select a nonzero value from the same column and subtract the value of the vector from it. I see an additional complication arising if the vector value is greater than the randomly selected value in the same column. In that case, he would simply set this value to zero.

Here is some modified code from an earlier question that does not work for this problem, but may be useful.

 foo <- function(mat, vec) { nr <- nrow(mat) nc <- ncol(mat) cols <- which(vec != 0) #select matrix columns where the vector is not zero rows <- sapply(seq_along(cols), function(x, mat, cols) { ones <- which(mat[,cols[x]] != 0) out <- if(length(ones) != 0) { ones } else { sample(ones, 1) } out }, mat = mat, cols = cols) ind <- (nr*(cols-1)) + rows #this line doesn't work b/c it is not binary mat[ind] <- 0 #here is where I would like to subtract the vector value mat <- rbind(mat, vec) rownames(mat) <- NULL mat } 

Any ideas? Thanks again for all the fantastic help!

EDIT:

Thanks to the help of bnaul below, I am much closer to the answer, but we faced the same problem that we encountered the last time. The sample function does not work properly in columns where there is only one nonzero value. I fixed this using the Gavin Simpson if else instruction (which was the solution in the previous case). I adjusted the matrix to have columns with only one nonzero value.

  mat1<-matrix(c(0,0,0,0,1,0, 0,0,0,0,0,5, 0,0,0,0,1,0, 0,0,0,0,0,0, 0,0,0,0,3,0, 0,0,2,0,0,0, 2,1,0,1,0,1, 0,0,0,0,37,0, 0,0,0,2,0,0, 0,0,0,0,0,1, 1,0,0,0,0,0, 0,0,0,0,0,0), byrow=T, ncol=6, nrow=12) vec1<-c(0,1,0,0,1,1) ones <- which(vec1 == 1L) temp=rZIP(sum(vec1)) vec1[ones]<-temp mat2 = rbind(mat1, vec1) apply(mat2, 2, function(col) { #Returns matrix of integers indicating their column #number in matrix-like object nonzero = which(head(col,-1) != 0); #negative integer means all but last # of elements in x sample_ind = if(length(nonzero) == 1){ nonzero } else{ sample(nonzero, 1) } ; #sample nonzero elements one time col[sample_ind] = max(0, col[sample_ind] - tail(col,1)); #take max of either 0 or selected value minus Inv return(col) } ) 

Thanks again!

+4
source share
1 answer
 mat2 = rbind(mat1, vec1) apply(mat2, 2, function(col) { nonzero = which(head(col,-1) != 0); sample_ind = sample(nonzero, 1); col[sample_ind] = max(0, col[sample_ind] - tail(col,1)); return(col) } ) 

I made a couple of simplifications; I hope they do not contradict what you had in mind. Firstly, I ignore the requirement that you only work with non-zero elements of the vector, since subtracting 0 from nothing will change it. Secondly, I link the matrix and the vector, and then perform the column-by-column operation based on the result, as this is a bit easier than tracking indexes in two separate data structures and then combining them later.

+2
source

All Articles