【问题标题】:Replace the first zero element of a row of a matrix,替换矩阵行的第一个零元素,
【发布时间】:2012-01-19 17:06:10
【问题描述】:

我想尽快将矩阵某些行中的第一个零替换为存储在另一个向量中的值。

有一个数字矩阵,其中每一行都是一个带有一些零的向量。 我还有两个向量,一个包含要替换的行,另一个包含新值:replace.in.these.rowsnew.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的所有链接”存储在一起。

我假设,但不确定这是否比总是从边缘列表中提取信息更有效(在模拟中每轮多次)

我还假设这种线性增长的矩阵形式比将相同的信息存储在相同的格式化列表中要快。

也欢迎一些关于这些上下文假设的 cmets。

【问题讨论】:

  • matrix[replace.in.these.rows + nrow(matrix)*(corresponding.poz.of.the.1st.zero-1)] &lt;- new.values

标签: r matrix indexing


【解决方案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

【讨论】:

  • 不错的答案和注释使逻辑很容易理解。 +1
  • ...但这会替换所有零值,而不仅仅是每列中的第一个值?!
  • 对。我以为这是要求的。如果需要不同的东西,那么它可以很容易地修改。也许我错过了编辑?
  • 是的,正如标题所述,第一个零旨在被替换。感谢您提供所有解决方案。为了找到第一个零,我的 sapply (corresponding.poz.of.1st.zero) 运行速度比 DWin 的 apply (first0s) 快 30%,并且 James 评论中的解决方案似乎与 @DWin 的运行速度相同。我没想到向量名称的长度(corresponding.poz.of.1st.zero vs. first0s)也会影响相当多的速度 - 在这个简单的矩阵上通过 10K 次迭代。
  • 对我的第二个问题 “默认情况下,R 矩阵是一组列向量。如果我以转置形式存储数据,我会得到什么吗?这意味着在列上工作而不是行。” 好像没什么区别。
猜你喜欢
  • 2017-02-10
  • 2013-03-14
  • 1970-01-01
  • 2014-05-05
  • 1970-01-01
  • 2017-05-09
  • 1970-01-01
  • 2013-07-29
  • 2016-11-13
相关资源
最近更新 更多