我还是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
任何人都可以帮助我。
提前致谢。同样比嵌套循环更容易理解。
答案 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