Как определить, назначен ли выход функции объекту в R - PullRequest
0 голосов
/ 17 февраля 2019

Внутри функции 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 голосов
/ 17 февраля 2019

Если я правильно понимаю, что вам нужно, лучше использовать пользовательский метод печати:

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")
0 голосов
/ 17 февраля 2019

Не уверен, что я полностью продумал это, но это похоже на пример, который вы привели.(Обратите внимание, что важно использовать = или 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

Создано в 2019-02-17 пакетом Представление (v0.2.1)

0 голосов
/ 17 февраля 2019

Вот попытка: недостаток в том, что предполагается, что переменная всегда называется b.В настоящее время я не могу придумать, как сопоставить значения с именами переменных в глобальной среде.

b<-49
fun <- function(a){
  b <- a^2
  ifelse(identical(b,get("b",.GlobalEnv)),print("Already Available"),
         print(paste0("The square is ",b)))
  #return(invisible(b)) #Commented out for testing
}



 fun(7)
[1] "Already Available"
0 голосов
/ 17 февраля 2019

Если я правильно понял, это может помочь:

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 если ни одно из содержимого любого из объектов не совпадает с выводом вашей функции, то ... cat!

Надеюсь, это поможет вам!Лучший!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...