Можете ли вы включить функцию R для просмотра значений ее собственных формальных форм при оценке?

На языке R предположим, что у меня есть функция ff (jj, kk, mm). Я хотел бы, чтобы вызывающая функция (или вызывающий человек в интерактивном сеансе) могла заставить mm зависеть произвольным образом от jj и kk во время вызова.

Для конкретности предположим:

ff <- function(jj, kk, mm){
  xx <- jj + kk  
  out<- xx/mm   
  out
}

Затем во время выполнения я хочу установить mm <- jj*kk. то есть:

ff(2, 3, (jj*kk))

это дает:

Error in ff(2, 3, (jj * kk)) : object 'jj' not found

Эта ошибка не возникает до тех пор, пока не будет оценено mm, то есть после того, как jj и kk уже были успешно оценены. Затем они оцениваются во второй раз с другими правилами области видимости. Я так понимаю, что это R-стандартная область видимости. Я спрашиваю, могу ли я написать функцию таким образом, чтобы она позволяла мне передать mm простое число или функцию других формальных аргументов, при условии, что эти аргументы были или могут быть оценены до того, как потребуется mm?

Обратите внимание, что я не спрашиваю, должен ли я это делать. Я решительно сделаю вид, что буду вежливым с людьми, которые высказывают свое мнение по этому последнему вопросу.

Я также не спрашиваю, могу ли я предварительно вычислить jj и передать предварительно обработанное число. Я знаю, что это правдоподобный ответ, но он не работает по причинам, которые я упростил для решения проблемы.


person andrewH    schedule 11.07.2014    source источник
comment
Чтобы проиллюстрировать, почему вам не следует этого делать, это приводит к: jj=99; kk=101; ff(2,3,(jj*kk)) игнорированию значений jj и kk, которые вы только что установили, потому что они оцениваются внутри функции, когда они равны 2 и 3 соответственно. Это удивит любого пользователя R, который не читал документацию по _4 _...   -  person Spacedman    schedule 11.07.2014
comment
Я не уверен, что понимаю тебя. Если у меня есть функция f ‹-функция (x) {x ^ 2}, и я выполняю x‹ - 3, f (x), я ожидаю получить 9. Но если я выполняю f (2), я ожидаю получить 4 Подожди ... Думаю, я понял. Вы представляете, как эту функцию использует кто-то другой, кто не просто ее написал, да? Я почти уверен, что этот проект разовый, поэтому в моем случае проблем не возникает. Но я понимаю, как это могло быть.   -  person andrewH    schedule 12.07.2014
comment
Вы можете найти adv-r.had.co.nz/Computing -on-the-language.html полезно   -  person hadley    schedule 19.07.2014


Ответы (1)


В нынешнем виде ваша функция ff() не работает, потому что предоставленные аргументы оцениваются в контексте вызывающей среды, с которой ни jj, ни kk не являются" видимыми ".

Чтобы оценить оператор, предоставленный mm в контексте собственного фрейма оценки функции, используйте eval(substitute()), например:

ff <- function(jj, kk, mm){
  mm <- eval(substitute(mm))
  xx <- jj + kk  
  out<- xx/mm   
  out
}

ff(2, 3, (jj*kk))
## [1] 0.8333333
person Josh O'Brien    schedule 11.07.2014
comment
Кроме того, скобки вокруг (jj*kk) не обязательны - работают и без них. - person Spacedman; 11.07.2014
comment
Спасибо, Джош! Это точно выполняет свою работу. Возможно, это заслуживает отдельного вопроса, но у меня есть продолжение. Что, если вы хотите обратиться к собственному окружению функции, например: LookHere ‹- function (X) {eval (substitute (X), envir = parent.frame (n = 0))}; ff ‹- function (jj, kk, mm) {mm‹ - LookHere (mm) xx ‹- jj + kk out‹ - xx / mm out} ff (2, 3, (jj * kk)) Очевидно parent.frame ( n = 0) неверно. Что правильно? - person andrewH; 12.07.2014
comment
@andrewH - Привет. У меня нет времени объяснять это прямо сейчас, но похоже, что вам нужно что-то вроде LookHere <- function(X) eval(do.call(substitute, list(substitute(X), env=parent.frame(n=1))), env=parent.frame(n=1)) - person Josh O'Brien; 13.07.2014