为什么exists()函数有效,但不适用于布尔语句?

时间:2014-04-25 00:09:06

标签: r debugging exists

我有一个快速函数,它只返回一个字符串变量,指示输入的树是否存在。

buildSpreadTotalDF = function(tree){
  if (exists(as.character(substitute(tree)))){
     ret = "The tree exists"
  }
  else{
     ret = "There tree does not exist"
  }
ret
}

似乎即使我这样做了

remove(tree)

并通过执行

检查对象树是否存在
tree
Error: object 'tree' not found

甚至可以与函数

分开检查布尔语句
> exists(as.character(substitute(tree)))
[1] FALSE

如果我将该功能作为

运行
ret = buildSpreadTotalDF(tree)

我会得到

ret
[1] "The tree exists"

这似乎违反直觉。当明显树不存在时,为什么它仍然会进入函数的第一个循环?

3 个答案:

答案 0 :(得分:2)

准确地查找变量的位置 - 您希望查看父框架,即调用函数的环境:

tree_exist <- function(var) {
  var_name <- as.character(substitute(var)) 
  if (exists(var_name, envir = parent.frame())){
    "The tree exists"
  }  else {
    "The tree does not exist"
  }
}
tree_exist(tree_exist)
tree_exist(var_name)

答案 1 :(得分:1)

这是因为您将函数参数命名为tree,因此"tree"将始终存在于函数的范围内。相反,选择一个不太可能用作变量名的参数名称,例如:

buildSpreadTotalDF = function(.argh){
   if (exists(as.character(substitute(.argh)))){
      ret = "The tree exists"
   } else{
      ret = "The tree does not exist"
   }
   ret
}

tree <- 1
buildSpreadTotalDF(tree)
# [1] "The tree exists"

remove(tree)
buildSpreadTotalDF(tree)
# "The tree does not exist"

答案 2 :(得分:-1)

问题是exists将首先在本地范围内查找(当您在函数外部调用exists(...)时,这是全局环境,但是当从那里调用时,它位于函数内部。自{{ 1}}是传递给你的函数的参数的名称,它总是存在里面函数。你可能想要做的是在全局环境中查找你的变量。你可以这样做例如,通过指定tree参数,在您的稍微修改过的示例中,如下所示:

where

更正:我认为我对buildSpreadTotalDF = function(treename){ if (exists(treename, where = globalenv())){ ret = "The tree exists" } else{ ret = "There tree does not exist" } ret } tree1 <- 1 buildSpreadTotalDF("tree1") # exists buildSpreadTotalDF("tree2") # does not exist 的默认范围是错误的,请参阅上面的答案,以获得关于通过使用不太可能的变量名修复问题的好建议以及下面的答案,以获取有关如何获取范围的详细信息右。