2011-08-12 47 views
4

並提前感謝您的幫助!從加權矩陣中的隨機值中減去R

此問題與我發佈的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) 
    } 
) 

再次感謝!

+0

雖然您提供的樣本數據,甚至你的代碼的企圖,並鏈接到老的問題,我很驚訝,沒有人採取了這一個。也許這是因爲它不完全清楚你想要做什麼(「當我將矢量綁定到矩陣中時:你在這裏意味着什麼?」)。也許你可以澄清你的意圖和/或顯示你想要的結果的例子? –

+0

這可能是因爲示例代碼存在一些問題;你沒有定義m,並且你沒有指定rZIP來自哪個包(gamlss)。不過,我現在正在刺探它。 – bnaul

+0

對不起!我會編輯以使其更清楚。 – Laura

回答

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都不會改變它。其次,我將矩陣和向量綁定,然後對結果按列進行操作,因爲這比在兩個單獨的數據結構中跟蹤索引稍微簡單一些,然後再將它們組合起來。

+0

非常棒,謝謝...你真的在清理亂碼時做得很好。 – Laura

+0

對不起,我遇到了上次遇到的問題。如果列中只有一個值要採樣,則示例函數有問題。 」 ......(中),其中只有一列單1 ...如果我們只是從一個長1向量樣的情況下,R的樣本()將其當作如果我們想從集合seq_len採樣( n)不是來自長度爲1的一組n。「加文辛普森用「if else」聲明來處理它。我會看看我能否弄清楚。 – Laura