4

そして、あなたの助けを前もって感謝します!

この質問は、以前に投稿した質問に関連していますが、別の課題であるため、独自の投稿に値すると思います。

前回は、ベクトルを追加した後に行列から値をランダムに選択することについて質問しました。その例では、行列とベクトルは両方ともバイナリでした。重み付きベクトルを追加した後、重み付きマトリックスの値を変更したいと思います。ここで、いくつかのコード例を示します。

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の助けのおかげで、私は答えにかなり近づいていますが、前回と同じ問題に遭遇しました. サンプル関数は、ゼロ以外の値が 1 つしかない列では正しく機能しません。Gavin Simpson の if else ステートメントを使用してこれを修正しました (これは前のケースの解決策でした)。ゼロ以外の値が 1 つだけの列を持つように行列を調整しました。

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

再度、感謝します!

4

1 に答える 1

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 を減算しても変化しないためです。次に、行列とベクトルをバインドし、結果に対して列単位で操作を実行します。これは、2 つの別々のデータ構造でインデックスを追跡し、後でそれらを結合するよりも少し簡単だからです。

于 2011-08-12T17:42:42.350 に答える