如何跳过R';对于';环

如何跳过R';对于';环,r,algorithm,for-loop,R,Algorithm,For Loop,我需要在一个数值向量中找到大于0的值,其中每个区域中至少有10个成员。我不想检查每个位置,因为这将是非常耗时的(向量超过1000万) 以下是我试图做的(非常初步,因为我不知道如何在for循环中跳过增量): 1。检查x[i](起始位置)是否为正。 a) 如果为正,检查x[i+10](结束位置)是否为正(因为我们需要至少10个正整数的长度) *如果为阳性,检查两者之间的每个位置是否为阳性 *如果为负,则移动到x[i+11],跳过起始位置和结束位置之间的位置(例如,新的起始位置为x[i+12]),因为

我需要在一个数值向量中找到大于0的值,其中每个区域中至少有10个成员。我不想检查每个位置,因为这将是非常耗时的(向量超过1000万)

以下是我试图做的(非常初步,因为我不知道如何在for循环中跳过增量):

1。检查x[i](起始位置)是否为正。
a) 如果为正,检查x[i+10](结束位置)是否为正(因为我们需要至少10个正整数的长度)
*如果为阳性,检查两者之间的每个位置是否为阳性
*如果为负,则移动到x[i+11],跳过起始位置和结束位置之间的位置(例如,新的起始位置为x[i+12]),因为如果包含负结束位置,我们将不会获得>10个成员。
x0){#如果开始位置为正
标志=1
打印(粘贴0(i,“:开始大于1”))
如果(x[i+10]>0{#如果结束位置为正,则检查两者之间的所有位置
对于(i+1中的j:i+9){
如果(x[j]>0{#如果位置为正,则检查下一个位置是否为正
打印(粘贴0(j,“:表示j1”))
}否则{#如果位置为负,则跳过检查并设置新的开始位置
打印(粘贴0(j,“:用于j2”))

这里有一个解决方案,它可以在一个1000万长度的向量中找到十个正数的延伸。它不使用OP中建议的循环方法

这里的想法是取逻辑表达式
vec>0
的累积和。只有当n-10和n之间的向量的所有值都为正值时,位置n和n-10之间的差值才会为10

filter
是计算这些差异的一种简单且相对快速的方法

#generate random data
vec   <- runif(1e7,-1,1)

#cumulative sum
csvec <- cumsum(vec>0)   

#construct a filter that will find the difference between the nth value with the n-10th value of the cumulative sign vector
f11   <- c(1,rep(0,9),-1)

#apply the filter
fv    <- filter(csvec, f11, sides = 1) 

#find where the difference as computed by the filter is 10
inds  <- which(fv == 10)

#check a few results
> vec[(inds[1]-9):(inds[1])]
 [1] 0.98457526 0.03659257 0.77507743 0.69223183 0.70776891 0.34305865 0.90249491 0.93019927 0.18686722 0.69973176
> vec[(inds[2]-9):(inds[2])]
 [1] 0.0623790 0.8489058 0.3783840 0.8781701 0.6193165 0.6202030 0.3160442 0.3859175 0.8416434 0.8994019
> vec[(inds[200]-9):(inds[200])]
 [1] 0.0605163 0.7921233 0.3879834 0.6393018 0.2327136 0.3622615 0.1981222 0.8410318 0.3582605 0.6530633

#check all the results
> prod(sapply(1:length(inds),function(x){prod(sign(vec[(inds[x]-9):(inds[x])]))}))
[1] 1
#生成随机数据
vec-prod(sapply(1:length(inds),function(x){prod(sign(vec[(inds[x]-9:(inds[x])))}))
[1] 1

我使用
system.time()
来查看各个步骤需要多长时间。在我功能不太强大的笔记本电脑上,最长的一步是
filter()
,对于长度为1000万的向量只需要半秒钟。

这里有一个解决方案,可以在长度为1000万的向量中找到十个正数的延伸。它不使用OP中建议的循环方法

这里的想法是取逻辑表达式
vec>0
的累积和。只有当n-10和n之间的向量的所有值都为正值时,位置n和n-10之间的差值才会为10

filter
是计算这些差异的一种简单且相对快速的方法

#generate random data
vec   <- runif(1e7,-1,1)

#cumulative sum
csvec <- cumsum(vec>0)   

#construct a filter that will find the difference between the nth value with the n-10th value of the cumulative sign vector
f11   <- c(1,rep(0,9),-1)

#apply the filter
fv    <- filter(csvec, f11, sides = 1) 

#find where the difference as computed by the filter is 10
inds  <- which(fv == 10)

#check a few results
> vec[(inds[1]-9):(inds[1])]
 [1] 0.98457526 0.03659257 0.77507743 0.69223183 0.70776891 0.34305865 0.90249491 0.93019927 0.18686722 0.69973176
> vec[(inds[2]-9):(inds[2])]
 [1] 0.0623790 0.8489058 0.3783840 0.8781701 0.6193165 0.6202030 0.3160442 0.3859175 0.8416434 0.8994019
> vec[(inds[200]-9):(inds[200])]
 [1] 0.0605163 0.7921233 0.3879834 0.6393018 0.2327136 0.3622615 0.1981222 0.8410318 0.3582605 0.6530633

#check all the results
> prod(sapply(1:length(inds),function(x){prod(sign(vec[(inds[x]-9):(inds[x])]))}))
[1] 1
#生成随机数据
vec-prod(sapply(1:length(inds),function(x){prod(sign(vec[(inds[x]-9:(inds[x])))}))
[1] 1

我用
system.time()
查看了各种步骤需要多长时间。在我功能不太强大的笔记本电脑上,最长的一步是
filter()
,对于一个长度为1000万的向量,这只需半秒多。

我不知道这种方法是否和Curt F的方法一样有效,但是如何

runs <- rle(x>0) 
运行0)

然后使用
运行$length>10并运行$values==TRUE

所定义的区域,我不知道这种方法是否与Curt F的方法一样有效,但是

runs <- rle(x>0) 
运行0)

然后使用
运行$length>10并运行$values==TRUE

仅使用基本命令定义的区域:

x <- runif(1e7,-1,1)  # generate random vector

y <- which(x<=0)  # find boundaries i.e. negatives and zeros
dif <- y[2:length(y)] - y[1:(length(y)-1)]  # find distance in boundaries
drange <- which(dif > 10)  # find distances more than 10

starts <- y[drange]+1  # starting positions of sequence
ends <- y[drange+1]-1  # last positions of sequence

仅使用基本命令的矢量化解决方案:

x <- runif(1e7,-1,1)  # generate random vector

y <- which(x<=0)  # find boundaries i.e. negatives and zeros
dif <- y[2:length(y)] - y[1:(length(y)-1)]  # find distance in boundaries
drange <- which(dif > 10)  # find distances more than 10

starts <- y[drange]+1  # starting positions of sequence
ends <- y[drange+1]-1  # last positions of sequence

x这不起作用,如果第8位到第18位的数字是正数,那么你就在11位(也就是在第1位是负数之后结束)21处的数字是负数?你不会检测到正确的拉伸。我没有包括这一点,因为我没有机会处理它。如果开始是负数,结束是正数,那么就需要从结束位置回溯以找到正拉伸的开始。矢量化方法可能比for循环更快,即使是wi大数据。类似于
rle(x>0)
会很快。如果你坚持使用循环,你处理事情的方式更像是
while
循环。
循环的
的要点是预先设置
i
的所有可能值,然后一次只检查一个。尝试跳转并操纵
i
会很困难。也许你可以使用
而不是
循环吗?
我很欣赏你的洞察力。谢谢你,@gregor这不起作用,如果第8位到第18位的数字是正数,那么你就在第11位了(在第1位是负数之后你就到了第11位了)21处的数字是负数?你不会检测到正确的拉伸。我没有包括这一点,因为我没有机会处理它。如果开始是负数,结束是正数,那么就需要从结束位置回溯以找到正拉伸的开始。矢量化方法可能比for循环更快,即使是wi大数据。类似于
rle(x>0)
会很快。如果你坚持使用循环,你处理事情的方式更像是
while
循环。
循环的
的要点是预先设置
i
的所有可能值,然后一次只检查一个。尝试跳转并操纵
i
会很困难。也许你可以用
而不是
循环吗?
我很感激你的洞察力。谢谢你,@Gregor