简体   繁体   English

从 R 中的加权矩阵中的随机值中减去

[英]Subtracting from random values in a weighted matrix in R

and thanks in advance for your help!并提前感谢您的帮助!

This question is related to one I posted before , but I think it deserves its own post because it is a separate challenge.这个问题与我之前发布的问题有关,但我认为它值得单独发布,因为它是一个单独的挑战。

Last time I asked about randomly selecting values from a matrix after adding a vector.上次我询问了在添加向量后从矩阵中随机选择值的问题。 In that example, the matrix and the vector were both binary.在那个例子中,矩阵和向量都是二进制的。 Now I would like to change the values in a weighted matrix after adding a weighted vector.现在我想在添加加权向量后更改加权矩阵中的值。 Here is some example code to play with.这是一些可以使用的示例代码。

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 sampled from a zero-inflated distribution (thanks to this question ).向量中的值是从零膨胀分布中采样的(感谢这个问题)。 When I bind the vector to the matrix, I want to randomly select a non zero value from the same column, and subtract the vector value from it.当我将向量绑定到矩阵时,我想从同一列随机 select 一个非零值,并从中减去向量值。 I can see a further complication arising if the vector value is greater than the randomly selected value in the same column.如果向量值大于同一列中随机选择的值,我会看到更复杂的情况。 In such an instance, it would simply set that value to zero.在这种情况下,它只会将该值设置为零。

Here is some modified code from the earlier question that does not work for this problem but maybe will be helpful.这是早期问题中的一些修改后的代码,这些代码不适用于此问题,但可能会有所帮助。

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 of the fantastic help!再次感谢所有出色的帮助!

EDIT:编辑:

Thanks to help from bnaul down below, I am a lot closer to the answer, but we have run into the same problem we hit last time.感谢下面 bnaul 的帮助,我离答案更近了,但我们遇到了上次遇到的同样问题。 The sample function doesn't work properly on columns where there is only one nonzero value.示例 function 在只有一个非零值的列上无法正常工作。 I have fixed this using Gavin Simpson's if else statement (which was the solution in the previous case).我已经使用 Gavin Simpson 的 if else 语句解决了这个问题(这是前一个案例中的解决方案)。 I've 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!再次感谢!

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;我做了一些简化; hopefully they don't conflict with what you had in mind.希望它们不会与您的想法相冲突。 First, I ignore the requirement that you only operate on the nonzero elements of the vector, since subtracting 0 from anything will not change it.首先,我忽略了只对向量的非零元素进行操作的要求,因为从任何东西中减去 0 都不会改变它。 Second, I bind the matrix and vector and then perform the operation column-wise on the result, since this is a bit easier than tracking the indices in two separate data structures and then combining them afterward.其次,我绑定矩阵和向量,然后对结果按列执行操作,因为这比在两个单独的数据结构中跟踪索引然后将它们组合起来要容易一些。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM