Играя с R средами - PullRequest
       28

Играя с R средами

1 голос
/ 20 марта 2019

У меня странная динамика окружения / области видимости, которую я пытался выяснить, и ищу правильный или рекомендуемый метод для достижения этой цели.

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

Текущий код функционирования:

master_function <- 
  function(x, iter = 100){
    x_p1 <- function(){ x <<- x + 1 }
    x_m1 <- function(){ x <<- x - 1 }

    path <- numeric(iter)
    for(i in 1:iter){
      next_step <- sample(c('p', 'm'), 1)
      if(next_step == 'p'){
        x_p1()
      } else { 
        x_m1()
      }
      path[i] <- x
    }
    path
  }

Проблема с этим кодом (особенно для действительно сложной проблемы) заключается в том, что он делает отладку x_p1, x_m1 содержимое функции с помощью утилиты отладки RStudio невозможно.

Надеясь реструктурировать код, чтобы он выглядел примерно так:

master_function <- 
  function(x, iter = 100){
    master_env <- environment()
    path <- numeric(iter)
    for(i in 1:iter){
      next_step <- sample(c('p', 'm'), 1)
      if(next_step == 'p'){
        x_p1(master_env)
      } else { 
        x_m1(master_env)
      }
      path[i] <- x
    }
    path
  }

x_p1 <- function(env){ assign('x', get('x', envir = env) + 1, envir = env) }
x_m1 <- function(env){ assign('x', get('x', envir = env) - 1, envir = env) }

Но это тоже довольно уродливо.Есть ли способ увеличить путь поиска, например, так, чтобы доступ к master_env был чище?

Редактировать: дополнительная информация, запрошенная @ MrFlick По сути, у меня есть симуляция смного движущихся частей.По мере продвижения, различные события (подфункции, на которые ссылаются) запускаются, изменяя состояние симуляции.Эти функции в настоящее время модифицируют множество различных объектов состояния для каждого вызова функции.Поскольку функции выполняются в вызове главной функции, я могу воспользоваться лексической областью видимости и оператором <<-, но я теряю возможность отладки в этих функциях.

Попытка выяснить, как создать эти функции вне мастер-симуляции.Если я правильно понимаю, если я сделаю функции такими, чтобы они потребляли состояние симуляции и возвращали модифицированную версию, это приводит к большим затратам памяти.

Ответы [ 2 ]

2 голосов
/ 20 марта 2019

1) trace Используйте trace для вставки debug операторов после определений x_p1 и x_m1, а затем можно пройти по ним при выполнении master_function.

trace(master_function, at = 4, quote({debug(x_p1); debug(x_m1) }))

untrace(master_function) выключает это. Используйте body(master_function)[4], чтобы увидеть, какая строка соответствует 4. Подробнее см. ?trace.

2) инструмент Другая возможность состоит в том, чтобы настроить вашу функцию таким образом, а затем вызвать ее с помощью master(function(x, DEBUG = TRUE), чтобы включить отладку.

master_function <- 
  function(x, iter = 100, DEBUG = FALSE){
    x_p1 <- function(){ x <<- x + 1 }
    x_m1 <- function(){ x <<- x - 1 }
    if (DEBUG) {
      debug(x_p1)
      debug(x_m1)
    }

    path <- numeric(iter)
    for(i in 1:iter){
      next_step <- sample(c('p', 'm'), 1)
      if(next_step == 'p'){
        x_p1()
      } else { 
        x_m1()
      }
      path[i] <- x
    }
    path
  }
1 голос
/ 20 марта 2019

Почему x должен вообще находиться в альтернативной среде?Следующее полностью усваивает и избегает нескольких сред.

x_p1 <- function(z){ z + 1 }
x_m1 <- function(z){ z - 1 }
master_function <- 
  function(x, iter = 100){
    new_x <- x


    path <- numeric(iter)
    for(i in 1:iter){
      next_step <- sample(c('p', 'm'), 1)
      if(next_step == 'p'){
        new_x <- x_p1(new_x)
      } else { 
        new_x <- x_m1(new_x)
      }
      path[i] <- new_x
    }
    path
  }
...