R 替换矩阵行的第一个零元素,
尽可能快地,我想用存储在另一个向量中的值替换矩阵某些行中的第一个零 有一个数值矩阵,其中每一行是一个带有一些零的向量。 我还有两个向量,一个包含要替换的行,另一个包含新值:R 替换矩阵行的第一个零元素,,r,matrix,indexing,R,Matrix,Indexing,尽可能快地,我想用存储在另一个向量中的值替换矩阵某些行中的第一个零 有一个数值矩阵,其中每一行是一个带有一些零的向量。 我还有两个向量,一个包含要替换的行,另一个包含新值:replace.in.this.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 &l
replace.in.this.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] )
mat编辑:如果仅替换前零,则此方法有效:
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
first0s编辑:如果只替换前零,则此方法有效:
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
first0smatrix[replace.in.this.rows+nrow(matrix)*(对应的.poz.of.1st.zero-1)]matrix[replace.in.this.rows+nrow(matrix)*(对应的.poz.of.1st.zero-1)]答案很好,注释使得逻辑很容易理解+1…但这会替换所有零值,而不仅仅是每列中的第一个?!正确的。我以为这就是要求的。如果需要一些不同的东西,那么它可以很容易地修改。也许我错过了一次编辑?是的,正如标题所述,第一个零的目标是被替换。感谢您提供的所有解决方案。为了找到第一个零,我的sappy(对应的.poz.of.1st.zero)比DWin的apply(first0s)运行速度快30%,而James评论中的解决方案似乎与@DWin的运行速度相同。我没想到向量名称的长度(对应的.poz.of.1st.zero vs.first0s)也会对速度产生相当大的影响-在这个简单的矩阵上,通过10K次迭代“默认情况下,R矩阵是一组列向量。如果我以转置的形式存储数据,我会得到什么?这意味着要处理列而不是行。“看起来没什么区别。回答不错,注释让逻辑很容易理解+1…但这会替换所有零值,而不仅仅是每列中的第一个?!正确的。我以为这就是要求的。如果需要一些不同的东西,那么它可以很容易地修改。也许我错过了一次编辑?是的,正如标题所述,第一个零的目标是被替换。感谢您提供的所有解决方案。为了找到第一个零,我的sappy(对应的.poz.of.1st.zero)比DWin的apply(first0s)运行速度快30%,而James评论中的解决方案似乎与@DWin的运行速度相同。我没想到向量名称的长度(对应的.poz.of.1st.zero vs.first0s)也会对速度产生相当大的影响-在这个简单的矩阵上,通过10K次迭代“默认情况下,R矩阵是一组列向量。如果我以转置的形式存储数据,我会得到什么?这意味着要处理列而不是行。
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