R - 在为每行找到值后循环并中断
R - loop and break after value found for each Rows
我有一个 0-1 的矩阵。
我想做的是循环进入这个矩阵并搜索 1。
每次找到 1 时,简单地 跳转 或传递该行,以便每行只记录 1 个值。
我想知道该序列的第一集是否是 1。
我在想
可能有一个解决方案
break
但我不确定如何正确使用它。
所以这是我的第一个矩阵
SoloNight = structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 0), .Dim = 10:11)
这是我的空矩阵-记录1。
matSolo = matrix(0, nrow = nrow(SoloNight), ncol = ncol(SoloNight) )
这是我尝试循环
for(i in 1:nrow(matSolo)){
for(j in 1:ncol(matSolo)){
if(SoloNight[i,j] == 1) break
{matSolo [i,j] <- 1}
}
}
在找到每行的值 1 后,如何 中断?
有什么建议吗?
(预期矩阵)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
[1,] 0 0 0 0 0 0 0 0 0 0 0
[2,] 0 0 0 0 0 0 0 0 0 0 0
[3,] 0 0 0 0 0 0 0 0 0 0 0
[4,] 0 0 0 0 0 0 0 0 0 0 0
[5,] 0 0 0 0 0 0 0 0 0 0 0
[6,] 0 0 0 0 0 0 0 0 0 0 0
[7,] 0 0 0 0 0 0 0 0 0 0 0
[8,] 0 0 0 1 0 0 0 0 0 0 0
[9,] 0 1 0 0 0 0 0 0 0 0 0
[10,] 0 0 0 0 0 0 0 0 0 0 0
你可以试试
indx <- max.col(SoloNight, 'first')*(rowSums(SoloNight)!=0)
matSolo[cbind(1:nrow(matSolo), indx) ] <- 1
基准
set.seed(24)
m1 <- matrix(sample(c(0,1), 5000*5000, replace=TRUE), ncol=5000)
khashaa <- function(){
matSolo <- rowCumsums(m1)
matSolo[matSolo!=1] <- 0
}
khashaa2 <- function(){matSolo <- 1*(rowCumsums(m1)==1)}
roland <- function() firstOne(m1)
akrun <- function() {
indx <- max.col(m1, 'first')*(rowSums(m1)!=0)
matSolo <- m1*0
matSolo[cbind(1:nrow(matSolo), indx) ] <- 1
}
system.time(akrun())
#user system elapsed
#0.349 0.044 0.395
system.time(roland())
# user system elapsed
# 0.144 0.021 0.166
system.time(khashaa())
# user system elapsed
# 0.555 0.055 0.611
system.time(khashaa2())
# user system elapsed
#0.265 0.054 0.319
library(microbenchmark)
microbenchmark(akrun(), khashaa(),khashaa2(), roland(), unit='relative', times=20L)
#Unit: relative
# expr min lq mean median uq max neval cld
# akrun() 2.383404 2.453934 2.298975 2.283178 2.304992 1.993665 20 c
#khashaa() 3.542353 3.601232 3.420879 3.429367 3.476025 2.898632 20 d
#khashaa2() 1.900968 2.029436 1.909676 1.923457 1.948551 1.693583 20 b
# roland() 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 20 a
您似乎喜欢 for
循环,而这些似乎是这里的自然选择。只需将您的代码更改为:
for(i in 1:nrow(matSolo)){
for(j in 1:ncol(matSolo)){
if(SoloNight[i,j] == 1) {
matSolo [i,j] <- 1
break
}
}
}
但是,这对于大矩阵来说会很慢。幸运的是,它很容易翻译成 Rcpp:
library(Rcpp)
cppFunction(
'IntegerMatrix firstOne(const IntegerMatrix mat) {
IntegerMatrix res(mat.nrow(), mat.ncol());
for (int i=0; i<mat.nrow(); i++) {
for (int j=0; j<mat.ncol(); j++) {
if (mat(i,j) == 1) {
res(i,j) = 1;
break;
}
}
}
return res;
}
')
firstOne(SoloNight)
你也可以试试
library(matrixStats)
matSolo <- 1*(rowCumsums(SoloNight)==1)
我有一个 0-1 的矩阵。 我想做的是循环进入这个矩阵并搜索 1。 每次找到 1 时,简单地 跳转 或传递该行,以便每行只记录 1 个值。
我想知道该序列的第一集是否是 1。 我在想
可能有一个解决方案break
但我不确定如何正确使用它。
所以这是我的第一个矩阵
SoloNight = structure(c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 1, 0, 0), .Dim = 10:11)
这是我的空矩阵-记录1。
matSolo = matrix(0, nrow = nrow(SoloNight), ncol = ncol(SoloNight) )
这是我尝试循环
for(i in 1:nrow(matSolo)){
for(j in 1:ncol(matSolo)){
if(SoloNight[i,j] == 1) break
{matSolo [i,j] <- 1}
}
}
在找到每行的值 1 后,如何 中断?
有什么建议吗?
(预期矩阵)
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11]
[1,] 0 0 0 0 0 0 0 0 0 0 0
[2,] 0 0 0 0 0 0 0 0 0 0 0
[3,] 0 0 0 0 0 0 0 0 0 0 0
[4,] 0 0 0 0 0 0 0 0 0 0 0
[5,] 0 0 0 0 0 0 0 0 0 0 0
[6,] 0 0 0 0 0 0 0 0 0 0 0
[7,] 0 0 0 0 0 0 0 0 0 0 0
[8,] 0 0 0 1 0 0 0 0 0 0 0
[9,] 0 1 0 0 0 0 0 0 0 0 0
[10,] 0 0 0 0 0 0 0 0 0 0 0
你可以试试
indx <- max.col(SoloNight, 'first')*(rowSums(SoloNight)!=0)
matSolo[cbind(1:nrow(matSolo), indx) ] <- 1
基准
set.seed(24)
m1 <- matrix(sample(c(0,1), 5000*5000, replace=TRUE), ncol=5000)
khashaa <- function(){
matSolo <- rowCumsums(m1)
matSolo[matSolo!=1] <- 0
}
khashaa2 <- function(){matSolo <- 1*(rowCumsums(m1)==1)}
roland <- function() firstOne(m1)
akrun <- function() {
indx <- max.col(m1, 'first')*(rowSums(m1)!=0)
matSolo <- m1*0
matSolo[cbind(1:nrow(matSolo), indx) ] <- 1
}
system.time(akrun())
#user system elapsed
#0.349 0.044 0.395
system.time(roland())
# user system elapsed
# 0.144 0.021 0.166
system.time(khashaa())
# user system elapsed
# 0.555 0.055 0.611
system.time(khashaa2())
# user system elapsed
#0.265 0.054 0.319
library(microbenchmark)
microbenchmark(akrun(), khashaa(),khashaa2(), roland(), unit='relative', times=20L)
#Unit: relative
# expr min lq mean median uq max neval cld
# akrun() 2.383404 2.453934 2.298975 2.283178 2.304992 1.993665 20 c
#khashaa() 3.542353 3.601232 3.420879 3.429367 3.476025 2.898632 20 d
#khashaa2() 1.900968 2.029436 1.909676 1.923457 1.948551 1.693583 20 b
# roland() 1.000000 1.000000 1.000000 1.000000 1.000000 1.000000 20 a
您似乎喜欢 for
循环,而这些似乎是这里的自然选择。只需将您的代码更改为:
for(i in 1:nrow(matSolo)){
for(j in 1:ncol(matSolo)){
if(SoloNight[i,j] == 1) {
matSolo [i,j] <- 1
break
}
}
}
但是,这对于大矩阵来说会很慢。幸运的是,它很容易翻译成 Rcpp:
library(Rcpp)
cppFunction(
'IntegerMatrix firstOne(const IntegerMatrix mat) {
IntegerMatrix res(mat.nrow(), mat.ncol());
for (int i=0; i<mat.nrow(); i++) {
for (int j=0; j<mat.ncol(); j++) {
if (mat(i,j) == 1) {
res(i,j) = 1;
break;
}
}
}
return res;
}
')
firstOne(SoloNight)
你也可以试试
library(matrixStats)
matSolo <- 1*(rowCumsums(SoloNight)==1)