gpt4 book ai didi

r - 如何检查表达式是否是赋值? (在回调中传递给 `addTaskCallback` )

转载 作者:行者123 更新时间:2023-12-02 16:16:46 25 4
gpt4 key购买 nike

如何检查表达式是否是传递给 addTaskCallback 的回调中的赋值?回调有四个参数。传递给回调的第一个参数是“顶级任务的 S 语言表达式”。 Top-level Task Callbacks in R手册建议您可以“检查表达式并确定是否进行了任何分配”。但我如何才能在全局环境中始终如一地完成任何任务呢?我基本上想知道在全局环境中是否添加或更改了任何对象,并且仅在这种情况下才执行我的回调。很容易检查基本的赋值操作,例如 <-=但我不确定循环(这是一个顶级表达式)、if 使用 <<- 的条件或函数操作符或可能的其他方式来更改全局环境中的对象。以下是一些单个顶级操作的示例,其中包括全局环境中的分配

# loops
for (i in 1:10) x[i] <- i
for (i in 1:10) {
x[i] <- i
y[i] <- i
}
# if conditions
if(cond) x <- rnorm(1000)
if(cond) {
x <- rnorm(1000)
y <- rnorm(1000)
}
# global assignment in loop
fn = function() x <<- rnorm(1000)
fn()

最后是一个非常基本的示例,用于检查简单的 =<-运算符:

eventHandler = function(expr, value, ok, visible) {
if(class(expr) %in% c('=','<-'))
print('assignment!')
# as.character(expr)[2] should now reference the object that was changed
TRUE
}
addTaskCallback(eventHandler)

最佳答案

因此,您基本上想知道是否在全局环境,并且仅在这种情况下执行[您的]回调。

这是一个非常简单的解决方案,利用(当前处于实验阶段)base R 函数lockEnvironment,它可以防止给定环境中的任何更改。不幸的是,没有对应的 unlock* ,所以我们必须执行 this gist首先。

# source *https://gist.github.com/wch/3280369* first


globalChange <- function (expr, envir = parent.frame()) {
lockEnvironment(.GlobalEnv, TRUE)

..change <- FALSE
tryCatch({
eval(expr, envir=envir)
},
error=function(err) {
# you may want to check whether err is "cannot add bindings to a locked environment" here
..change <<- TRUE
})

unlockEnvironment(.GlobalEnv) # see https://gist.github.com/wch/3280369

# unlock all bindings (unlockEnvironment doesn't do that)
for (obj in ls(envir=.GlobalEnv, all=TRUE))
unlockBinding(obj, .GlobalEnv)

..change
}

如果在计算给定 expr 时出现错误,此函数将返回 TRUE。它在锁定全局环境的情况下运行,因此如果在全局环境中添加或更改了任何对象,您肯定会得到TRUE

一些例子:

globalChange({
x <- 100
})
## [1] TRUE
globalChange({
print("a")
})
## [1] "a"
## [1] FALSE
globalChange({
f <- function() { x <<- 100 }
f()
})
## [1] TRUE

关于r - 如何检查表达式是否是赋值? (在回调中传递给 `addTaskCallback` ),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23673582/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com