2012-01-19 2 views
1

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

Существует числовая матрица, где каждая строка представляет собой вектор с некоторыми нулями. У меня также есть два вектора, один из которых содержит строки, в том, что нужно заменить, а другое - новые значения: replace.in.these.rows и new.values. Кроме того, я могу генерировать вектор первых нулей с sapply

mat <- matrix(1,5,5) 
mat[c(1,8,10,14,16,22,14)] <- 0 
replace.in.these.rows <- c(1,2,3) 
new.values <- c(91,92,93) 

corresponding.poz.of.1st.zero <- sapply(replace.in.these.rows, 
             function(x) which(mat [x,] == 0)[1]) 

Теперь я хотел бы что-то, что перебирает векторы индексов, но без цикл возможно:

matrix[replace.in.these.rows, corresponding.poz.of.the.1st.zero ] <- new.values 

Есть ли трюк с индексирование более простых векторов? Он не мог использовать список или массив (например, по столбцу) в качестве индекса.

По умолчанию матрицы R представляют собой набор векторов столбцов. Получать что-либо, если я храню данные в транспонированной форме? Это означало бы работать с столбцами вместо строк.


Контекст:

Этой матрица сохраняет контакт ID-ы сети. Это не матрица смежности n x n, а n x max.number.ofpartners (или n * = 30).

По умолчанию используется edgelist, но я хотел сохранить «все ссылки из X» вместе.

Я предполагал, но не уверен, что это более эффективно, чем всегда извлекать информацию из edgelist (несколько раз каждый раунд в симуляции)

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

Некоторые комментарии к этим контекстуальным предположениям также приветствуются.

+0

'матрица [replace.in.these.rows + nrow (матрица) * (corresponding.poz.of.the.1st.zero-1)] <- new.values' – James

ответ

1

Edit: Если только первые нули должны заменить этот подход работает:

first0s <-apply(mat[replace.in.these.rows, ] , 1, function(x) which(x==0)[1]) 
mat[cbind(replace.in.these.rows, first0s)] <- new.values 
> mat 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 91 1 1 0 1 
[2,] 1 1 1 1 92 
[3,] 1 93 1 1 1 
[4,] 1 1 0 1 1 
[5,] 1 0 1 1 1 

Edit: Я думал, что цель состояла в том, чтобы заменить все нули в выбранных строках, и это был подход. Полностью Векторизованный подход:

idxs <- which(mat==0, arr.ind=TRUE) 
# This returns that rows and columns that identify the zero elements 
# idxs[,"row"] %in% replace.in.these.rows 
# [1] TRUE TRUE FALSE FALSE TRUE TRUE 
# That isolates the ones you want. 
# idxs[ idxs[,"row"] %in% replace.in.these.rows , ] 
# that shows what you will supply as the two column argument to "[" 
#  row col 
#[1,] 1 1 
#[2,] 3 2 
#[3,] 1 4 
#[4,] 2 5 
chosen.ones <- idxs[ idxs[,"row"] %in% replace.in.these.rows , ] 
mat[chosen.ones] <- new.values[chosen.ones[,"row"]] 
# Replace the zeros with the values chosen (and duplicated if necessary) by "row". 
mat 
#---------  
[,1] [,2] [,3] [,4] [,5] 
[1,] 91 1 1 91 1 
[2,] 1 1 1 1 92 
[3,] 1 93 1 1 1 
[4,] 1 1 0 1 1 
[5,] 1 0 1 1 1 
+0

хороший ответ и аннотации делают логику довольно легко следовать. +1 –

+0

... но это заменяет ВСЕ нулевые значения, а не только первые в каждом столбце ?! – Tommy

+0

Справа. Я думал, это было то, о чем просили. Если что-то другое было необходимо, его можно было бы легко модифицировать. Может, я пропустил редактирование? –

Смежные вопросы