Вычитание из случайных значений в весовой матрице в R - PullRequest
4 голосов
/ 12 августа 2011

и заранее спасибо за вашу помощь!

Этот вопрос связан с вопросом, который я опубликовал до , но я думаю, что он заслуживает отдельного поста, потому что это отдельная задача.

В прошлый раз я спрашивал о случайном выборе значений из матрицы после добавления вектора.В этом примере матрица и вектор были двоичными.Теперь я хотел бы изменить значения в взвешенной матрице после добавления взвешенного вектора.Вот пример кода, с которым можно поиграть.

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

Значения вектора взяты из раздуваемого нулями распределения (благодаря этот вопрос ).Когда я связываю вектор с матрицей, я хочу случайным образом выбрать ненулевое значение из того же столбца и вычесть из него векторное значение.Я могу видеть дальнейшее осложнение, возникающее, если значение вектора больше, чем случайно выбранное значение в том же столбце.В таком случае он просто установит это значение на ноль.

Вот некоторый модифицированный код из предыдущего вопроса, который не работает для этой проблемы, но, возможно, будет полезен.

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 внизу, я намного ближе к ответу, но мы побежалив ту же проблему мы попали в прошлый раз.Функция примера не работает должным образом для столбцов, где есть только одно ненулевое значение.Я исправил это, используя выражение Гэвина Симпсона 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 Ответ

2 голосов
/ 12 августа 2011
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 из чего-либо не изменит его.Во-вторых, я связываю матрицу и вектор, а затем выполняю операцию по столбцам для результата, поскольку это немного проще, чем отслеживание индексов в двух отдельных структурах данных и последующее их объединение.

...