Как я могу создать пользовательское назначение, используя функцию замены? - PullRequest
4 голосов
/ 22 сентября 2011

Я определил функцию с именем once следующим образом:

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

Идея состоит в том, что value отнимает много времени для оценки, и я хочу назначить его только для x при первом запуске сценария.

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

Мне бы очень хотелось, чтобы использование было once(x) <- value, а не once(x, value), но если я напишу функцию once<-, то расстроится, что переменная не существует:

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

У кого-нибудь есть способ обойти это?

пс: есть имя для описания таких функций, как once<- или вообще f<-?

Ответы [ 2 ]

7 голосов
/ 22 сентября 2011

Если вы хотите немного изменить свои требования, чтобы использовать квадратные скобки, а не круглые скобки, тогда вы можете сделать это:

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
6 голосов
/ 22 сентября 2011

Согласно пункту 3.4.4 в справочнике по языку R, что-то вроде замены имен оценивается следующим образом:

 `*tmp*` <- x
 x <- "names<-"(`*tmp*`, value=c("a","b"))
 rm(`*tmp*`)

Это плохие новости для вашего требования, потому чтоназначение не будет выполнено в первой строке (так как x не найден), и даже если это сработает, ваш deparse(substitute) вызов никогда не будет соответствовать тому, что вы хотите.

Извините, что разочаровал вас

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