在R函数内部,是否可以检测用户是否已将输出分配给对象?
例如,我想在控制台上打印一些信息,只要输出没有分配给一个对象,我正在寻找这样的东西
fun <- function(a){
b <- a^2
if(!<OUTPUT ASSIGNED>) cat('a squared is ', b)
return(invisible(b))
}
Run Code Online (Sandbox Code Playgroud)
因此无论函数输出是否已分配,控制台上的结果都会不同,例如:
> fun(5)
> a squared is 25
>
> out <- fun(5)
>
>
Run Code Online (Sandbox Code Playgroud)
不确定我是否已经完全考虑过这个,但这似乎适用于你给出的例子.(注意要使用它的重要=或assign或.Primitive("<-") 里面的fun要经受这种治疗.)
fun <- function(a){
b = a^2 # can't use <- here
if (!identical(Sys.getenv("R_IS_ASSIGNING"), "true")) cat('a squared is ', b)
return(invisible(b))
}
`<-` <- function(a, b) {
Sys.setenv("R_IS_ASSIGNING" = "true")
eval.parent(substitute(.Primitive("<-")(a, b)))
Sys.unsetenv("R_IS_ASSIGNING")
}
fun(5)
#> a squared is 25
out <- fun(6)
out
#> [1] 36
Run Code Online (Sandbox Code Playgroud)
由reprex包创建于2019-02-17 (v0.2.1)
如果我正确理解你需要什么,最好使用自定义打印方法:
print.squared_value = function(x, ...){
cat('a squared is', x, "\n")
x
}
fun = function(a){
b = a^2
class(b) = union("squared_value", class(b))
b
}
fun(2)
# a squared is 4
Run Code Online (Sandbox Code Playgroud)
更新:
fun = function(a){
b = a^2
invisible(b)
}
h = taskCallbackManager()
# add a callback
h$add(function(expr, value, ok, visible) {
# if it was a call 'fun' without assinment
if(is.call(expr) && identical(expr[[1]], quote(fun))){
cat('a squared is', value, "\n")
}
return(TRUE)
}, name = "simpleHandler")
fun(2)
# a squared is 4
b = fun(2)
b
# [1] 4
# remove handler
removeTaskCallback("R-taskCallbackManager")
Run Code Online (Sandbox Code Playgroud)
如果我理解得好,这可以解决问题:
fun <- function(a){
b <- a^2
if(sum(unlist(lapply(lapply(ls(envir = .GlobalEnv), get), function(x){ identical(x,a^2)})))==0) cat('a squared is ', b)
return(invisible(b))
}
Run Code Online (Sandbox Code Playgroud)
所以:
ls(envir=.GlobalEnv)将返回全局环境中的所有对象
lapply(ls(envir = .GlobalEnv), get):将返回一个列表,其中包含全局环境中所有对象的内容
lapply(lapply(ls(envir = .GlobalEnv), get), function(x){ identical(x,a^2)}):将返回一个逻辑列表,检查全局环境中所有对象的内容是否与函数的输出相同
sum(unlist(lapply(lapply(ls(envir = .GlobalEnv), get), function(x){ identical(x,a^2)})))==0如果所有对象的内容都不与函数的输出相同,那么......猫!
我希望这可以帮助你!最好的!