そして、あなたの助けを前もって感謝します!
この質問は、以前に投稿した質問に関連していますが、別の課題であるため、独自の投稿に値すると思います。
前回は、ベクトルを追加した後に行列から値をランダムに選択することについて質問しました。その例では、行列とベクトルは両方ともバイナリでした。重み付きベクトルを追加した後、重み付きマトリックスの値を変更したいと思います。ここで、いくつかのコード例を示します。
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)
}
)
再度、感謝します!