如何从 i:n 和列循环遍历矩阵行

How to loop through a matrix rows from i:n and columns

我还是r的初学者。我正在尝试遍历矩阵并计算从每一行(1:5)循环的总和,直到达到该行内的阈值(例如 14)。然后遍历所有列 (2:6)。我想要的是,我的矩阵 (b) 充满了数字 (91:95),其中行已达到阈值。我已经试过了。有谁知道我做错了什么。

a <- matrix(c(91:95,1:25), ncol=6)    
b <- matrix(NA,ncol=6,nrow=5)


for(i in 1:nrow(a)) {
    for(j in 2:ncol(a)) {
        for(n in 1:5) {
            if(sum(a[seq(i:n),j])>14) {
                b[i,j] <- a[n,1]
                break
            }
        }
    }
}

这是我的结果。

      [,1] [,2] [,3] [,4] [,5] [,6]
[1,]   NA   95   93   92   91   91
[2,]   NA   NA   94   91   91   91
[3,]   NA   NA   91   91   91   91
[4,]   NA   NA   91   91   91   91
[5,]   NA   91   91   91   91   91

我想要的结果应该是这样的。结果应在起点 (i) 上,并显示超过阈值 (14) 的行 (n)。

      [,1] [,2] [,3] [,4] [,5] [,6]
[1,]   NA   95   93   92   91   91
[2,]   NA   NA   93   93   91   91
[3,]   NA   NA   94   94   91   91
[4,]   NA   NA   95   95   91   91
[5,]   NA   NA   NA   95   91   91

谁能帮我解决这个问题。

提前致谢。也比嵌套循环更容易受到赞赏。

据我了解您的问题,结果的元素 (i, j) 应包含第一行的行标识符,其中累计和 (i, j) + (i+1, j) + (i+ 2, j) + ... 超过 14,如果累积和在到达输入矩阵底部之前从未超过 14,则它应该包含 NA。在这种情况下,您的预期输出包含一个错误——最右边的两列应该是 91、92、93、94、95,而不是 91、91、91、91、91。

对于输入矩阵的每一列(我们将使用边距 2 对 apply 进行操作)你可以做一个 for 循环(我在下面使用 sapply 作为更方便的替代方法),计算忽略您正在计算的元素上方的元素的列的累计总和:

a <- matrix(1:25, nrow=5)
o <- 91:95
apply(a, 2, function(x) sapply(1:length(x), function(p) {
    cs <- cumsum(x * c(rep(0, p-1), rep(1, length(x)-p+1)))
    if (max(cs > 14)) {
        return(o[min(which(cs > 14))])
    } else {
        return(NA)
    }
}))
#      [,1] [,2] [,3] [,4] [,5]
# [1,]   95   93   92   91   91
# [2,]   NA   93   93   92   92
# [3,]   NA   94   94   93   93
# [4,]   NA   95   95   94   94
# [5,]   NA   NA   95   95   95

这是与@josiber 类似的方法,但使用 dplyr(假设预期输出中存在错误)。第一个代码块,即创建 "df1" 之前,基本上是为分组变量 "ind" 创建“0”行的复制。我们创建一个 "a" (rep(list(a), n)) 的 n 个副本,然后 rbind 它以形成矩阵 "a1",一个相同维度的“1s”的索引矩阵 "i1"作为 "a1"。 "i1" 矩阵根据 "m1" 索引填充“0”行,并创建一个 data.frame("df1") 和一个分组变量 "ind" 和其他列将是 "a1*i1" 的结果,因此 "i1" 中的“0”元素在输出中将是“0”。

library(dplyr)
a1 <- do.call(rbind,rep(list(a),n))
i1 <- matrix(1,ncol=n,nrow=nrow(a1))
m1 <- matrix(seq(6,nrow(a1), by=n)+rep(0:3,each=4),ncol=4,byrow=TRUE)
i1[m1[upper.tri(m1,diag=TRUE)],] <- 0
df1 <- data.frame(ind=rep(1:n,each=n),a1*i1)

使用 "df1",我们使用 "ind" 作为分组变量 (group_by) 并使用 summarise_each 汇总列 ("X1:X5")。我们得到每一列中那些累计和大于14的元素的索引,并以此作为索引得到"o"(o[which(cumsum(.)>14)..)

的元素
df1 %>%
    group_by(ind)%>%
    summarise_each(funs(o[which(cumsum(.)>14)[1]]))
#  ind X1 X2 X3 X4 X5
#1   1 95 93 92 91 91
#2   2 NA 93 93 92 92
#3   3 NA 94 94 93 93
#4   4 NA 95 95 94 94
#5   5 NA NA 95 95 95

或者如果您需要矩阵输出,而不是 "dplyr",请使用 Map 创建 "indx" 并使用 tapply 获得结果。

indx <- do.call(rbind,Map(`+`,list(matrix(1:5,ncol=5,
                       nrow=5,byrow=TRUE)), seq(0,20, by=5)) )
res <- matrix(tapply(a1*i1, indx, FUN=function(x)
              o[which(cumsum(x) >14)[1]]),ncol=5,byrow=TRUE)
 res
 #     [,1] [,2] [,3] [,4] [,5]
 #[1,]   95   93   92   91   91
 #[2,]   NA   93   93   92   92
 #[3,]   NA   94   94   93   93
 #[4,]   NA   95   95   94   94
 #[5,]   NA   NA   95   95   95

数据

a <- matrix(1:25, nrow=5)
o <- 91:95
n <- 5