【问题标题】:R: How to print only the first 5 TRUE conditions in a loop without limiting the range of the loopR:如何在不限制循环范围的情况下仅打印循环中的前 5 个 TRUE 条件
【发布时间】:2021-06-22 10:08:50
【问题描述】:

假设我有一个数字列表。

x <- c(10,12,5,23,40,27,11,4,7,25,21,7,99,45,2,10)

我想在 for 循环内使用 if 条件打印前 5 个大于 20 的数字,原因是这是一个简单的可重现示例,实际场景需要 for 循环内的 if 条件。有没有办法在不限制范围的情况下获得大于 20 的前 5 个数字?找到所有大于 20 的数字的方法是这样的

for(i in 1:length(x)){
if(x[i]>20){
print(x[i])
}
}

也可以将问题视为将打印语句限制为前 5 个实例。 有人可以帮忙吗? 请注意,for循环的范围不能被限制得出一个解决方案。

要求的答案是

23,40,27,25,21

使用for循环,if条件和打印语句/cat/writeLines是必须的

【问题讨论】:

  • 当有 5 次点击时是否可以退出循环,或者在未简化的循环中发生了其他需要为其余部分完成的事情。
  • 最好用例应该成功地遍历整个值列表并返回满足条件的前 5 个值。即使条件没有评估为 5 个 TRUE 条件,它也应该返回 TRUE 条件。例如,逻辑应该是前 5 个,但即使我们只得到 2 个条件而不是最多 5 个,那么应该打印这 2 个。关于你的问题,我假设在这个用例中,当满足前 5 个条件时迭代整个循环会浪费内存?
  • 谢谢。好的,但也可以有一个解决方案,它已经限制了for 循环的范围
  • 我也想过。你能告诉我你到底在想什么吗?
  • 例如:for(i in which(cumsum(x &gt; 20) &lt;= 5)) {...

标签: r


【解决方案1】:

这行得通吗:

x[x > 20][1:5]
[1] 23 40 27 25 21
 

使用 for 循环:

v <- vector()
for(i in 1:length(x)){
  if(x[i] > 20){
    v <- c(v,x[i])
  }  
  if(length(v) == 5){
    print(v)
    break
  }
}
[1] 23 40 27 25 21

【讨论】:

  • 如果结果少于 5 个,这将产生不稳定的结果。
  • 这在这种情况下有效。但是用例需要在 for 循环内的 if 条件内使用 print 语句。我试图尽可能简单地表达出来!
  • @Nil_07,已添加for 循环,请检查是否有效
  • 我会为我的案例@Karthik S 试试这个。同时,您的解决方案和下面的 GKi 解决方案看起来相似且很有帮助。
  • @Nil_07,它基本上是创建一个空向量并根据我们的条件填充它。
【解决方案2】:

事实证明限制for循环的范围是允许的,这可以通过cumsum(x &gt; 20) &lt;= 5来完成:

for(i in seq_len(match(5, cumsum(x > 20), length(x)))) {
  if(x[i] > 20) {
    print(x[i])
  }
}
#[1] 23
#[1] 40
#[1] 27
#[1] 25
#[1] 21

或者添加一个计数器:

5 次点击后会中断的变体(感谢 @sindri-baldur):

n <- 0L
for(i in 1:length(x)){
  if(x[i]>20) {
    print(x[i])
    n <- n+1L
    if(n == 5L) break
  }
}

将构成完整循环的变体。

n <- 0L
for(i in 1:length(x)){
  if(x[i]>20 & n<5) {
    n <- n+1L
    print(x[i])
  }
}

要获得前 5 个,您可以使用 head:

head(x[x > 20], 5)
#[1] 23 40 27 25 21

请注意,这也适用于点击次数少于 5 次的情况。然后它将返回命中数。例如。试试看:

x <- c(10,12,5,23,40,27,11,4,7,25,2,7,9,4,2,10)

【讨论】:

  • 如果x 很长,我会改为添加if (n == 5L) break
  • @sindri_baldur 我不知道在未简化循环中会发生其他情况。在这个问题中,我可以阅读而不限制范围。但也许可以使用break,但它会限制范围。
  • @sindri_baldur 感谢您的提示。实际上,事实证明限制范围是允许的。因此,我根据您的建议添加了一个变体。
猜你喜欢
  • 2017-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-23
相关资源
最近更新 更多