如何从 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
我还是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