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

时间:2011-08-12 06:00:28

标签: r matrix sample weighted

并提前感谢您的帮助!

这个问题与我发布的before相关,但我认为它应该发表自己的帖子,因为这是一个单独的挑战。

上次我询问在添加矢量后从矩阵中随机选择值。在该示例中,矩阵和向量都是二进制的。现在我想在添加加权矢量后更改加权矩阵中的值。以下是一些可以使用的示例代码。

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

向量中的值是从零膨胀分布中采样的(感谢this question)。当我将向量绑定到矩阵时,我想从同一列中随机选择一个非零值,并从中减去向量值。如果向量值大于同一列中随机选择的值,我可以看到进一步的复杂化。在这种情况下,它只是将该值设置为零。

以下是来自早期问题的一些修改后的代码,这些代码不适用于此问题但可能会有所帮助。

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
}

有什么想法吗?再次感谢所有精彩的帮助!

编辑:

感谢下面的bnaul的帮助,我更接近答案,但我们遇到了上次遇到的同样问题。对于只有一个非零值的列,示例函数无法正常工作。我已经使用Gavin Simpson的if else语句(这是前一种情况下的解决方案)修复了这个问题。我已经调整矩阵,使列只有一个非零值。

 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)
    }
  )

再次感谢!

1 个答案:

答案 0 :(得分:2)

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)
    }
)

我做了几个简化;希望他们不会与你的想法发生冲突。首先,我忽略了你只对向量的非零元素进行操作的要求,因为从任何东西中减去0都不会改变它。其次,我绑定矩阵和向量,然后对结果进行逐列操作,因为这比跟踪两个独立数据结构中的索引然后再将它们组合起来要容易一些。