R - 内部函数检查对象是不是存在
Posted
技术标签:
【中文标题】R - 内部函数检查对象是不是存在【英文标题】:R - Inside function check if object existsR - 内部函数检查对象是否存在 【发布时间】:2019-07-17 18:06:24 【问题描述】:我有四个功能:
f1 <- function(x)if(exists(x))return(2*x)
f2 <- function(x)if(exists("x"))return(2*x)
f3 <- function(x)if(!missing(x))return(2*x)
f4 <- function(x)if(!missing("x"))return(2*x)
但是,exists
和 missing
不适用于上述任何格式,并且我收到以下错误消息:
f1(x)
Error in exists(x) : object 'x' not found
f2(x)
Error in f2(x) : object 'x' not found
f3(x)
Error in f3(x) : object 'x' not found
f4(x)
Error in f4(x) : object 'x' not found
当x
未定义时,有什么方法可以修复函数不崩溃?
【问题讨论】:
您是否尝试检查x
的 值 是否为 NA 或 参数 本身是否存在(在调用函数时提供) ?
如果 x
未定义,当有人调用 f(x)
时,我希望该函数什么都不做(或者只是打印一条消息,指出 x
未定义)!基本上,如果f(x)
被调用并且x
尚未定义,我想阻止我的代码崩溃!
我认为您交替引用参数x
和对象x
(正在传递)可能有点令人困惑。如我错了请纠正我。您要检查是否存在传入的任意对象,但不检查参数x
。
【参考方案1】:
可以在函数内部检查全局环境中是否存在对象,但我们感兴趣的不是x
的值,而是调用函数时传递给x
的对象。在这里我们可以使用rlang
中的enquo
将传入的表达式转换为quosure,然后quo_name
将其转换为字符串:
library(rlang)
f1 <- function(x)
arg <- quo_name(enquo(x))
if(exists(arg, where = .GlobalEnv))
return(2*x)
else
cat('variable ', '`', arg, '`', ' does not exist', sep = "")
输出:
> x <- 2
> f1(x)
[1] 4
> f1(y)
variable `y` does not exist
假设y
不存在。
【讨论】:
当我在我的机器上运行你的代码时,我得到的是:f(2)
variable '2' does not exist
f(x)
Error in f(x) : object 'x' not found
@Mahmoud 我已经向exists
添加了一个where
参数,它应该可以解决第二种情况,对于第一种情况,这是因为它正在检查全局环境中名为2
的对象,这是不存在的。如果您将2
分配给x
然后运行f(x)
,它可以工作。【参考方案2】:
R 解释器首先评估f(x)
行,然后评估函数中的内容。解释器发现未知元素x
并立即停止评估其余代码。
因此,它不适用于您给出的任何场景,因为问题出现在函数评估之前。
你必须把支票放在函数之外:
if(exists("x"))
f(x)
或者,根据您的需要,您可以这样做:
f <- function(x)
if(!missing("x")) return(x * 2)
f() // do nothing
f(2) // return 4
【讨论】:
你的第一句话不太对!如果我将函数定义为f <- function(x)cat("Function started...");if(exists("x"))2*x
并为未定义的x
运行它;它仍然进入函数内部并运行它并打印消息"Function started..."
。这是输出:Function started...Error in f(x) : object 'x' not found
如果我们事先知道要传递给f
的变量名,第一种方法很好,但如果我们希望f
动态检查传入的对象是否存在于调用它的环境。如果对象不存在,第二种方法根本不起作用。
确实,你是对的。这是因为参数被延迟评估,如幻灯片 9 和 10 中的 here 所述以上是关于R - 内部函数检查对象是不是存在的主要内容,如果未能解决你的问题,请参考以下文章