尽可能快,我想用一个存储在另一个向量中的值替换矩阵的某些行中的第一个零。
有一个数字矩阵,其中每一行都是带有一些零的向量。
我还有两个向量,一个包含行,在哪个被替换,另一个包含新值: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] )
现在我想要一些迭代索引向量的东西,但可能没有for循环:
matrix[replace.in.these.rows, corresponding.poz.of.the.1st.zero ] <- new.values
是否有比简单向量更多索引的技巧?它不能使用列表或数组(例如逐列)作为索引。
默认情况下,R矩阵是一组列向量。如果我以转置的形式存储数据,我会获得任何收益吗?这意味着要处理列而不是行。
上下文:
此矩阵存储网络的联系ID。这不是邻接矩阵n x n,而是n x max.number.of.partners(或n * = 30)矩阵。
网络默认使用edgelist,但我想将“来自X的所有链接”存储在一起。
我假设,但不确定这是否比始终从边缘列表中提取信息更有效(在模拟中每轮多次)
我还假设这种线性增长的矩阵形式比在同一格式化列表中存储相同的信息更快。
对这些背景假设的一些评论也是受欢迎的。
答案 0 :(得分:1)
编辑:如果只替换第一个零,则此方法有效:
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
编辑:我认为目标是替换所选行中的所有零,这就是方法。完全矢量化的方法:
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