Вычитание из случайных значений во взвешенной матрице в R

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

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

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

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

Еще раз спасибо!


person Laura    schedule 12.08.2011    source источник
comment
Хотя вы предоставляете образцы данных и даже свои попытки кода и ссылки на старые вопросы, я удивлен, что никто не взялся за это. Возможно, это потому, что не совсем понятно, что вы хотите сделать (Когда я привязываю вектор к матрице: что вы здесь имеете в виду?). Может быть, вы могли бы пояснить свои намерения и/или показать пример желаемых результатов?   -  person Nick Sabbe    schedule 12.08.2011
comment
Возможно, это связано с парой проблем с примером кода; вы не определяете m и не указываете, из какого пакета rZIP (gamlss). Однако сейчас я беру на себя удар.   -  person bnaul    schedule 12.08.2011
comment
Прости! Я отредактирую, чтобы было понятнее.   -  person Laura    schedule 13.08.2011


Ответы (1)


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

person bnaul    schedule 12.08.2011
comment
Потрясающе, спасибо... вы действительно проделали большую работу по очистке моего беспорядочного кода. - person Laura; 13.08.2011
comment
Извините, я столкнулся с проблемой, с которой мы столкнулись в прошлый раз. Если в столбце есть только одно значение для выборки, у функции выборки возникла проблема. ... (в) случае, когда в столбце есть только один 1 ... Если мы просто выбираем из вектора длины 1, R sample () будет обрабатывать его так, как если бы мы хотели сделать выборку из набора seq_len (n ) не из длины 1 набора n. Гэвин Симпсон справился с этим с помощью оператора if else. Я посмотрю, смогу ли я понять это. - person Laura; 15.08.2011