如何遍历i:n和列中的矩阵行

时间:2015-01-06 15:52:27

标签: r loops

我还是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

任何人都可以帮助我。

提前致谢。同样比嵌套循环更容易理解。

2 个答案:

答案 0 :(得分:2)

据我所知,你的结果的元素(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

答案 1 :(得分:1)

这是与@josiber类似的方法,但使用dplyr(假设预期输出中存在错误)。第一个代码块,即创建&#34; df1&#34;基本上是创建&#34; 0&#34;分组变量的行&#34; ind&#34;。我们创建了一个&#34; a&#34;的复制品。 (rep(list(a), n))然后rbind形成矩阵&#34; a1&#34;,索引矩阵&#34; i1&#34; &#34; 1s&#34;尺寸与&#34; a1&#34;相同。 &#34; i1&#34;矩阵填充&#34; 0&#34;基于&#34; m1&#34;的行索引,并创建一个data.frame(&#34; df1&#34;),其中包含一个分组变量&#34; ind&#34;其他列将是&#34; a1 * i1&#34;的结果,因此&#34; i1&#34;中的元素那是&#34; 0&#34;将是&#34; 0&#34;在输出中。

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)

使用&#34; df1&#34;,我们使用&#34; ind&#34;作为分组变量(group_by)并使用summarise_each汇总列(&#34; X1:X5&#34;)。我们得到每列中累积和大于14的元素的索引,并将其作为索引来获取&#34; o&#34;的元素。 (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

或者,如果您需要矩阵输出,而不是&#34; dplyr&#34;,请创建&#34; indx&#34;使用Map并使用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