如何检测函数的输出是否分配给R中的对象

时间:2019-02-17 09:21:44

标签: r

在R函数中,是否可以检测用户是否已将输出分配给对象?

例如,我只想在输出未分配给对象的情况下在控制台上打印一些信息,我正在寻找类似的东西

fun <- function(a){
           b <- a^2
           if(!<OUTPUT ASSIGNED>) cat('a squared is ', b)
           return(invisible(b))
} 

因此,无论是否分配函数输出,控制台上的结果都会有所不同,例如:

> fun(5)
> a squared is 25
>
> out <- fun(5)
>
>

4 个答案:

答案 0 :(得分:9)

不确定我是否已经完全考虑了这一点,但这似乎对您给出的示例有用。 (请注意,在您要接受此处理的=内使用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

reprex package(v0.2.1)于2019-02-17创建

答案 1 :(得分:5)

如果我正确理解了您的需求,最好使用自定义打印方法:

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

更新:

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")

答案 2 :(得分:1)

如果我理解得很好,这可以解决问题:

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))
} 

所以:

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,如果所有对象中的任何内容都不与您的函数的输出相同,那么...猫!

希望对您有所帮助! 最好!

答案 3 :(得分:0)

这是一种尝试:这样做的缺陷在于它假定变量始终命名为b。我目前无法想到一种在全局环境中将值与变量名匹配的方法。

ionic cordova emulate --livereload android -- --target="[TARGET]"