Подтвердить что ты не робот

Ограничение диапазона переменных

Я пытаюсь написать функцию, которая ограничивает область переменных R. Например,

source("LimitScope.R")
y = 0
f = function(){
   #Raises an error as y is a global variable
   x = y
}

Я думал о тестировании переменной среды, но не был уверен в том, как это сделать.

Почему

Я учу R для подражания. В их первых двух практиках некоторые из них всегда забывают о переменном объеме, поэтому их поданные функции не работают. Например, я всегда получаю что-то вроде:

n = 10
f = function(x){
  #Raises an error
  #as I just source f and test it for a few test cases.
  return(x*n)
}

Я был после быстрой функции, которая бы "отключила" область. Как вы можете себе представить, это не должно быть особенно надежным, поскольку это можно было бы предложить только для нескольких практик.

4b9b3361

Ответ 1

Я не уверен, что вы хотите сделать это в целом, но функция local() должна помочь, как и библиотека codetools.

В вашем примере попробуйте

f = local( function() { ... }, baseenv())

Он не делает именно то, что вы хотите, но он должен приблизить вас.

Ответ 2

Вы можете заставить переменную локальную версию с этой функцией:

get_local <- function(variable)
{
  get(variable, envir = parent.frame(), inherits = FALSE)  
}

Сравните эти случаи

y <- 0    
f <- function()
{
  x <- y
}    
print(f())        # 0

y <- 0    
f <- function()
{
  y <- get_local("y")
  x <- y
}    
print(f())        # Error: 'y' not found

В зависимости от того, что вы делаете, вы также можете проверить, был ли y аргументом f, используя formalArgs или formals.

g  <- function(x, y = TRUE, z = c("foo", "bar"), ...) 0

formalArgs(g)
# [1] "x"   "y"   "z"   "..."

formals(g)
#$x
#
#
#$y
#[1] TRUE
#
#$z
#c("foo", "bar")
#
#$...

EDIT: более общая точка "как отключить лексическое охват без изменения содержимого функций" сложнее решить. Я вполне уверен, что правила определения области охвата довольно укоренены в R. Альтернативой может быть использование S-Plus, поскольку он имеет различные правила определения области видимости.

Ответ 3

Вы можете проверить, существует ли y в глобальной среде, используя exists('y',envir=.GlobalEnv)

Ответ 4

Что случается со мной, так это то, что у меня есть разделенный экран в ESS с файловым буфером R-кода слева и интерпретатором справа. Возможно, я установил некоторые значения в интерпретаторе, пока я отлаживаю код, над которым я работаю в буфере. Тогда возможно, что код в буфере случайно ссылается на то, что я установил в intrereter. Это трудно обнаружить, если я не буду оценивать свой буфер в новом интерпретаторе каждый раз, что не работает по умолчанию ESS.

Если это та проблема, которую вы часто видите, rm (list = ls (envir =.GlobalEnv)) в том, что вам может помочь источник, но это, конечно, создает другие проблемы, такие как стирание всего, что было использование для сохранения состояния при отладке и т.д.