Объем функций nls selfStart

Я создаю пакет, который:

  1. читать в наборе данных
  2. определить, какие компоненты необходимы для моделирования данных 1
  3. построить самозапускающуюся модель NLS, используя эти компоненты
  4. применить эту модель к данным

Результат сохраняется в списке, который содержит данные, модель и результат nls. Все работает до шага 4. Я сохранил свои построенные модели в списке, и R больше не распознает их как функции selfStart.

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

 Chick.1 <- ChickWeight[ChickWeight$Chick == 1, ]
 fm1 <- nls(weight ~ SSlogis(Time, Asym, xmid, scal), data = Chick.1)
 fm1

Модель нелинейной регрессии
model: weight ~ SSlogis (Time, Asym, xmid, scal) data: Chick.1
Asym xmid scal
937.02 35.22 11.41
остаточная сумма квадратов: 76.66

Количество итераций до сходимости: 0
Достигнутый допуск сходимости: 7.778e-07

Но когда я сохраняю функцию и данные вместе в списке, R больше не видит самозапускающуюся функцию как самозапускающуюся:

myobj <- list()
myobj$model <- SSlogis
myobj$data <- ChickWeight[ChickWeight$Chick == 1, ]

nls(weight ~ myobj$model(Time, Asym, xmid, scal), data = myobj$data)

Ошибка в getInitial.default (func, data, mCall = as.list (match.call (func,:
) для объектов «функция» не найден метод getInitial.

Мой рабочий процесс в конечном итоге будет включать обработку десятков наборов данных, поэтому я хотел бы сохранить каждый набор данных и связанную с ним модель в своем собственном объекте (и эти объекты, вероятно, окажутся в списке объектов). Есть ли способ сохранить или восстановить среду моих функций selfStart даже после того, как они сохранены в другом списке?

ОБНОВИТЬ

В ответ на предложение Грегора я попробовал следующее:

nls(as.formula(sprintf("weight ~ %s(Time, Asym, xmid, scal)",
                       "myobj$model")), data = myobj$data)

Ошибка в nls (as.formula (sprintf ("weight ~% s (Time, Asym, xmid, scal))",:
сингулярный градиент Дополнительно: Предупреждающее сообщение:
In nls (as.formula (sprintf ( "weight ~% s (Time, Asym, xmid, scal)",:
Для некоторых параметров не указаны начальные значения.
Инициализация 'Asym', 'xmid', 'scal' на '1.'. < br> Рассмотрите возможность указания start или использования модели selfStart

Обновление 2

Вдохновленный @Gregor, я нашел обходной путь:

nlsDispatch <- function(obj){
  GLOBAL_NLS <<- obj$model
  nls(weight ~ GLOBAL_NLS(Time, Asym, xmid, scal), data = myobj$data) 
}

nlsDispatch(myobj)

Модель нелинейной регрессии
model: weight ~ GLOBAL_NLS (Time, Asym, xmid, scal)
data: myobj $ data
Asym xmid scal
937.02 35.22 11.41
остаточная сумма квадратов: 76,66

Количество итераций до сходимости: 0
Достигнутый допуск сходимости: 6.621e-07

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

1: В моем приложении это в основном вопрос подсчета пиков и определения количества нормальных кривых, необходимых для их моделирования.


r nls
person Tyler    schedule 13.04.2016    source источник
comment
Вы обрабатываете правую часть формулы как аргумент ... но это не так. Возможно, есть лучший способ, но я бы предложил построить вашу формулу в виде строки sprintf("weight ~ %s(Time, Asym, xmid, scal)", "SSlogis"), а затем использовать на ней as.formula().   -  person Gregor Thomas    schedule 14.04.2016
comment
@Gregor спасибо - я попробовал и получил немного другую ошибку. Обратите внимание, что я использовал модель myobj $ вместо SSlogis. SSlogis уже работает как есть.   -  person Tyler    schedule 14.04.2016
comment
Я бы подумал, что моя версия будет работать так: sprintf("weight ~ %s(Time, Asym, xmid, scal)", myobj$model), если myobj$model имеет строковое имя функции, а не фактический объект функции.   -  person Gregor Thomas    schedule 14.04.2016
comment
@Gregor Это работает для моего примера. Но для пакета я не собираюсь использовать предварительно созданные модели, такие как SSlogis, я создаю новые модели для каждого набора данных. Я надеялся сохранить каждый набор данных вместе с его моделью в объекте. Это будет удобно при просмотре десятков файлов в каталоге. Но, возможно, это больше работы, чем опираться на ваше предложение, я не уверен.   -  person Tyler    schedule 14.04.2016


Ответы (1)


1) Это работает:

Model <- myobj$model
nls(weight ~ Model(Time, Asym, xmid, scal), data = myobj$data)

давая

Nonlinear regression model
  model: weight ~ Model(Time, Asym, xmid, scal)
   data: myobj$data
  Asym   xmid   scal 
937.02  35.22  11.41 
 residual sum-of-squares: 76.66

Number of iterations to convergence: 0 
Achieved convergence tolerance: 6.621e-07

2) Похоже, что определение объема самозапуска запутано. Проблема появляется в getInitial.formula, в котором используется эта строка:

func <- get(as.character(object[[2L]][[1L]]))

Обратите внимание, что нет второго аргумента для get (среда), поэтому он не обращает внимания на среды.

Таким образом, если вы хотите поместить решение, указанное выше, в функцию, вам нужно будет обойти это следующим образом:

f <- function() {
  myobj <- list()
  myobj$model <- SSlogis
  myobj$data <- ChickWeight[ChickWeight$Chick == 1, ]
  Model <<- myobj$model
  nls(weight ~ Model(Time, Asym, xmid, scal), data = myobj$data)
}
f()

3) Другой способ - прикрепить Модель. Это не позволит ему попасть в глобальное рабочее пространство. Обратите внимание, что мы отсоединяем его после, чтобы функция не оставила следов.

f2 <- function() {
  on.exit(detach())
  if (any(grepl("list", search()))) stop("list already on search path")
  myobj <- list()
  myobj$model <- SSlogis
  myobj$data <- ChickWeight[ChickWeight$Chick == 1, ]
  attach(list(Model = myobj$model))
  nls(weight ~ Model(Time, Asym, xmid, scal), data = myobj$data)
}
f2()

Обратите внимание, что если detach не возникает, то в следующий раз, когда будет выполнено attach, в список поиска будут добавлены два элемента (тогда как в предыдущем подходе он всегда перезаписывал глобальную переменную, поэтому этого не могло произойти), поэтому мы проверяем, что там нет такого списка на пути поиска и остановитесь с ошибкой, если он есть.

person G. Grothendieck    schedule 14.04.2016
comment
Спасибо вам за разъяснение! - person Tyler; 14.04.2016
comment
Дело принято. Возможно, стоит добавить шаг, чтобы подтвердить, что параметры, оцененные в результате nls, соответствуют параметрам в модели. Если что-то пойдет не так с подключением / отсоединением, вполне вероятно, что это все равно «сработает» с неправильной моделью. - person Tyler; 14.04.2016
comment
Добавили отметку в (3). - person G. Grothendieck; 14.04.2016