当循环内一个值大于另一个值时停止循环函数

Posted

技术标签:

【中文标题】当循环内一个值大于另一个值时停止循环函数【英文标题】:Stop a looping function when one value is greater than another within loop 【发布时间】:2015-12-07 04:16:06 【问题描述】:

我一直在尝试编写while 命令来在循环生成的一个值超过另一个值时停止循环函数。但是,我没有找到正确的方法。

for 循环运行 30 天,但我希望它在parasite_l.A 的最后一个值小于parasite_l.B 时立即停止。

我已经包含了用于生成数据和 for 循环的工作代码。

对循环没有限制的替代解决方案也将不胜感激。

# Subject A, initially 400 parasites, growing by 10 %
subA = 400
infA = 1.1

# Subject B, initially 120 parasites, growing by 20 %
subB = 120
infB = 1.2

# How many days to model
days = 30

days_seq = seq(1, days, 1)

# Parasite load for A
parasite_l.A = rep(NA, days)
parasite_l.A[1] = subA

# Parasite load for B
parasite_l.B = rep(NA, days)
parasite_l.B[1] = subB

# Loop for subject A and B
for(i in 1:(days))
    parasite_l.A[i+1] = parasite_l.A[i]*(infA)
    parasite_l.B[i+1] = parasite_l.B[i]*(infB)
  

parasite_l.A
parasite_l.B

【问题讨论】:

“for 循环运行 30 天” - 与现有的 for 循环相比,可能值得考虑一种不同的、更有效的方法。顺便说一句 附带说明,parasite_l.A 可以用subA * (infA ^ (0:days)) 创建;虽然在这种情况下,许多不需要的值将被计算出来,因为在计算之前不能有“中断”条件。 感谢@alexis_laz 的替代方案!这对于在时间跨度内生成我想要的值要高效得多。 您说,“for 循环运行了 30 天,但我希望它在 parasite_l.A 的最后一个值大于 parasite_l.B. 时立即停止”。但是您的意思是“小于”,否则该函数将在第一个值处停止。 A = 400; B = 120 @PierreLafortune。感谢您发现错误。我会解决的。 【参考方案1】:
if (parasite_l.A < parasite_l.B)  // if parasite a is less than b, do the following // 
    for(i in 1:(days))
       parasite_l.A[i+1] = parasite_l.A[i]*(infA)
       parasite_l.B[i+1] = parasite_l.B[i]*(infB)
    

【讨论】:

【参考方案2】:

对于您所指的内容,有一个名为while 的内置控制流函数。只要满足条件,它就会继续循环。

i <- 1    
while (parasite_l.A[i] > parasite_l.B[i]) 
      parasite_l.A[i+1] = parasite_l.A[i]*(infA)
    parasite_l.B[i+1] = parasite_l.B[i]*(infB)
    i <- i + 1


# parasite_l.A
#  [1]  400.0000  440.0000  484.0000  532.4000  585.6400  644.2040  708.6244
#  [8]  779.4868  857.4355  943.1791 1037.4970 1141.2467 1255.3714 1380.9085
# [15] 1518.9993        NA        NA        NA        NA        NA        NA
# [22]        NA        NA        NA        NA        NA        NA        NA
# [29]        NA        NA
#  parasite_l.B
#  [1]  120.0000  144.0000  172.8000  207.3600  248.8320  298.5984  358.3181
#  [8]  429.9817  515.9780  619.1736  743.0084  891.6100 1069.9321 1283.9185
# [15] 1540.7022        NA        NA        NA        NA        NA        NA
# [22]        NA        NA        NA        NA        NA        NA        NA
# [29]        NA        NA

【讨论】:

这不起作用,因为您在while 循环的condition 中使用向量。它将测试 A 的总和与 B 的总和。 @PaulJames 它只需要条件中的i。在条件中使用向量没有问题。附带说明一下,OP在他们的描述中倒退了。他们希望 B 大于 A,而不是描述的相反。 你是对的,你可以在while 循环中使用一个向量,但我是对的,它会对向量求和。当您使用索引引用向量中的元素时,您使用的是该特定元素作为条件,而不是整个向量。 @PaulJames 这也不是真的。它不会自动求和。试试c(1:5) &lt;= 4。向量的总和永远不会与第二个进行比较。第二个值被回收。 感谢@PierreLafortune 提供解决方案,并在我的描述中发现错误,同时从我的编码中找出我真正想要的东西。这真是太棒了。我选择你的代码作为答案,因为它比 PauiJames 提供的更有效。【参考方案3】:

使用一个索引值 (i)、几个计数器 (A.index.valueB.index.value) 和一个 while 循环:

# Subject A, initially 400 parasites, growing by 10 %
subA <- A.index.value <- 400
infA <- 1.1

# Subject B, initially 120 parasites, growing by 20 %
subB <- B.index.value <- 120
infB <- 1.2

# How many days to model
days <- 30

days_seq <- seq(1, days, 1)

# Parasite load for A
parasite_l.A <- rep(NA, days)
parasite_l.A[1] <- subA

# Parasite load for B
parasite_l.B <- rep(NA, days)
parasite_l.B[1] <- subB

# While Loop for subject A and B
i <- 1
while (A.index.value > B.index.value) 
    parasite_l.A[i+1] <- A.index.value <- parasite_l.A[i]*(infA)
    parasite_l.B[i+1] <- B.index.value <-  parasite_l.B[i]*(infB)
    i <- i + 1


parasite_l.A
parasite_l.B

结果是:

> parasite_l.A
 [1]  400.00  440.00  484.00  532.40  585.64  644.20  708.62  779.49  857.44 943.18 1037.50
[12] 1141.25 1255.37 1380.91 1519.00      NA      NA      NA      NA      NA      NA      NA
[23]      NA      NA      NA      NA      NA      NA      NA      NA
> parasite_l.B
 [1]  120.00  144.00  172.80  207.36  248.83  298.60  358.32  429.98  515.98  619.17  743.01
[12]  891.61 1069.93 1283.92 1540.70      NA      NA      NA      NA      NA      NA      NA
[23]      NA      NA      NA      NA      NA      NA      NA      NA
> 

【讨论】:

感谢您的回答。我不知道在 R 中使用计数器的可能性。它解决了问题,我只是标记了 Pierre 的解决方案,因为它更有效。【参考方案4】:

在循环内使用类似:

    if (parasite_l.A > parasite_l.B) 
      break

【讨论】:

如果使用for(...)... 循环,这是正确的答案。 对不起,如果我不清楚。我意识到我需要使用带有条件的break 语句。但是,我一定是写错了我的代码,因为我无法让它工作。 您是否将此语句放入带有索引的 for 循环中? 这就是我尝试的方式if (parasite_l.A &lt; parasite_l.B) for(i in 1:(days)) parasite_l.A[i+1] = parasite_l.A[i]*(infA) parasite_l.B[i+1] = parasite_l.B[i]*(infB) break

以上是关于当循环内一个值大于另一个值时停止循环函数的主要内容,如果未能解决你的问题,请参考以下文章

for循环循环取值的时候,当出现了与以前循环出的值有重复的值时就只取出重复之前的值, 比如整个循环

如何从文件中获取随机结构?

在必须传回值时避免循环包含

SwiftUI:如何在函数计算 @State 值时同时更新视图?

MySQL 使用游标触发并循环更新错误值

数组中有一个数字出现的次数超过数组长度的一半