Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I create a custom assignment using a replacement function?

Tags:

r

I have defined a function called once as follows:

once <- function(x, value) {
    xname <- deparse(substitute(x))
    if(!exists(xname)) {
        assign(xname, value, env=parent.frame())
    }
    invisible()
}

The idea is that value is time-consuming to evaluate, and I only want to assign it to x the first time I run a script.

> z
Error: object 'z' not found
> once(z, 3)
> z
[1] 3

I'd really like the usage to be once(x) <- value rather than once(x, value), but if I write a function once<- it gets upset that the variable doesn't exist:

> once(z) <- 3
Error in once(z) <- 3 : object 'z' not found

Does anyone have a way around this?

ps: is there a name to describe functions like once<- or in general f<-?

like image 691
pete Avatar asked Dec 12 '22 09:12

pete


1 Answers

If you are willing to modify your requirements slightly to use square brackets rather than parentheses then you could do this:

once <- structure(NA, class = "once")
"[<-.once" <- function(once, x, value) {
    xname <- deparse(substitute(x))
    pf <- parent.frame()
    if (!exists(xname, pf)) assign(xname, value, pf)
    once
}


# assigns 3 to x (assuming x does not currently exist)
once[x] <- 3
x # 3

# skips assignment (since x now exists)
once[x] <- 4
x # 3
like image 105
G. Grothendieck Avatar answered Jan 31 '23 01:01

G. Grothendieck