首页 > 解决方案 > 为什么 For 循环在 R 和循环索引中无效

问题描述

我正在 R-bloggers 网站上做 R 练习。这是我正在解决的问题:

如果给定整数在向量内,则创建一个返回 TRUE 的函数。

提供的解决方案代码为:

f.exists <- function (v, x) {
  exist <- FALSE
  i <- 1

  while (i <= length (v) & !exist) {

    if (v[i] == x) {
      exist <- TRUE
    }
  i <- 1 + i
  }
  exist
}

但是,我的尝试是:

isInside <- function(x, y) {
  i <- 1
  for (i in x) {
    print(i)
    if (x[i] == y) {
      return(TRUE)
    }
    else {
      return(FALSE)
    }
  }
} 

test <- c(1,2,3,4,5,6,7,8,9,10,10.25,100)
isInside(test,10.25)

这返回[1] 1 [1] False意味着它只循环一次,一旦命中假就退出。但它应该返回 true,因为 10.25 在 vector 中x。我不确定为什么该if语句不起作用,因为它应该循环遍历每个索引x以查看该数字是否在向量中。

此外,我在这篇文章中发现,说你应该使用while循环而不是for循环。为什么for循环如此糟糕的做法?我的循环是否存在固有问题for,使其无法正常工作?

标签: r

解决方案


避开首选使用 R 的%in%内联运算符,让我们分析一下您的函数。

  1. for (i in x)正在逐步遍历的每个x这意味着在第 11 次通过这样的循环(没有中断),i将是10.25而不是11。当您引用时,这将在逻辑上失败x[i]:它不会抛出错误(老实说,我认为这是 R 的失败),但它没有任何意义(什么是x[10.25]?下一次x[100]返回应该是什么?)。这应该是for (i in seq_along(x))或坚持使用for (i in x),然后替换x[i] == yi == y.

  2. 您选择return(TRUE)何时找到匹配项。return函数立即跳出for循环并跳出函数,返回值TRUE。如果未找到匹配项,youreturn(FALSE)也会立即跳出for循环和函数,返回 value FALSE。我认为你打算让循环继续,所以语句的else子句if是......不必要的。如果您删除该else声明,也许它会更好。

  3. 未成年人,您预先定义了i <- 1. 这不会伤害或改变任何事情,但在 R 中它是完全没有必要的。i在循环之外没有被引用,并且一旦for开始,i就被分配 的第一个值x。因此,您可以安全地删除i <- 1并且执行应该不受影响。(这不是代码风格,只是不必要的代码。)

一种方法的演示:

myany <- function(x, y) {
  for (el in x) {
    if (el == y) {
      return(TRUE)
    }
  }
  return(FALSE)
}
test <- c(1,2,3,4,5,6,7,8,9,10,10.25,100)
myany(test, 10.25)
# [1] TRUE

或者,

myany <- function(x, y) {
  for (ind in seq_along(x)) {
    if (x[ind] == y) {
      return(TRUE)
    }
  }
  return(FALSE)
}

我们可以在这个例子中看到一些错误:

myany <- function(x, y) {
  for (i in x) {
    message("Comparing ", sQuote(i), " (which is ", sQuote(x[i]), ") with ", sQuote(y))
    if (x[i] == y) {
      return(TRUE)
    }
  }
  return(FALSE)
}

myany(test, 10.25)
# Comparing '1' (which is '1') with '10.25'
# Comparing '2' (which is '2') with '10.25'
# Comparing '3' (which is '3') with '10.25'
# Comparing '4' (which is '4') with '10.25'
# Comparing '5' (which is '5') with '10.25'
# Comparing '6' (which is '6') with '10.25'
# Comparing '7' (which is '7') with '10.25'
# Comparing '8' (which is '8') with '10.25'
# Comparing '9' (which is '9') with '10.25'
# Comparing '10' (which is '10') with '10.25'
# Comparing '10.25' (which is '10') with '10.25'
# Comparing '100' (which is 'NA') with '10.25'
# Error in if (x[i] == y) { : missing value where TRUE/FALSE needed

这是我们看到正在发生的事情的地方。当iis时10,它看起来很好,因为 的第 10 个元素test确实是 10。但是,在下一次传递中,iis10.25而不是您预期的11。R 默默地截断x[10.25]x[10],这就是它说 的原因which is '10',因为第 10 个元素确实是 10。下一次是 where iis 100test[100]显然不存在。在 R 中,当您尝试检索超出向量定义长度的索引时,它将返回NA(其他语言在您尝试此操作时会给出错误或核心转储)。


推荐阅读