Пользовательская функция, основанная на step(), дает: Ошибка в eval (expr, envir, enclos): объект «X» не найден

Я пытаюсь создать функцию, которая охватывает функцию ordiR2step() из пакета vegan. Эта функция основана на функции step().

Это код, который отлично работает вне функции:

    install.packages("vegan")
    require(vegan)
    data(mite) 
    data(mite.env) #explanatory variables
    mite.hel = decostand(mite, "hel") #response variable
    mod0 <- rda(mite.hel ~ 1, mite.env)  # Model with intercept only 
    mod1 <- rda(mite.hel ~ ., mite.env)  # Model with all explanatory variables
    step.res <- ordiR2step(mod0, scope = formula(mod1), direction="forward") 
    step.res$anova 

Однако, если я попытаюсь обернуть это в функцию:

    forward <- function(X, Y) {
    intercept <- rda(X ~ 1, data = Y)  # Model with intercept only
    model <- rda(X ~ ., data = Y)  # Model with all explanatory variables
    # this is where debugging is stuck
    forStep <- ordiR2step(object=intercept, scope = formula(model), 
                    direction = "forward", trace = FALSE)
    list(forStep$anova)
    }
    forward(mite.hel, mite)

Я получаю следующую ошибку: Error in eval(expr, envir, enclos) : object 'X' not found

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

Насколько я понимаю это поведение, функция step() и, соответственно, ordiR2step() не могут читать из среды, определенной внутри функции, а только из среды рабочей области, потому что, если я определяю X перед вызовом функции, все работает хорошо. Однако это противоречит цели, поэтому я попробовал некоторые предлагаемые решения, такие как:

    forward2 <- function(X, Y) {
    intercept <- do.call("rda",list(X ~ 1, data = Y))  
    model <- do.call("rda", list(X ~ ., data = Y))  
    forStep <- ordiR2step(object=intercept, scope = formula(model), 
                    direction = "forward", trace = FALSE)
    list(forStep$anova)
    }
    forward2(mite.hel, mite.env)

Та же ошибка... Нет игральных костей... Есть предложения? Спасибо за ваше время!


person Xavier GB    schedule 15.05.2014    source источник
comment
Без распаковки внутренностей ordiR2step() я не думаю, что это будет возможно. Ошибка возникает из-за ordiParseFormula(), и вызов которого в этот момент скрыт довольно глубоко в стеке вызовов. Я имею в виду, что эти функции были написаны для интерактивной работы, и ставки сняты, когда вы затем начнете встраивать их в другие функции. Я посмотрю на оскорбительную функцию и посмотрю, сможем ли мы улучшить ее, чтобы помочь. На самом деле проблемы возникают, когда ordiParseFormula() начинает анализировать формулу для следующей модели в цепочке прямого выбора...   -  person Gavin Simpson    schedule 15.05.2014
comment
... он ищет X в нескольких местах, но не во фрейме выполнения вашей функции forward().   -  person Gavin Simpson    schedule 15.05.2014
comment
Стек вызовов действительно довольно глубокий. Похоже, что ordiParseformula(..., envdepth = 6) получит данные (по умолчанию envdepth = 2). Ошибка возникает, когда update() пытается изменить модель. Кажется, нет никакого способа изменить значение envdepth. Возможно, у вас есть какой-то секретный план, но для этой конкретной задачи нет необходимости заключать эти три команды в forward(): вы можете ввести их напрямую, и тогда анализ запустится без проблем.   -  person Jari Oksanen    schedule 16.05.2014
comment
Кажется, что с двумя разработчиками-веганами я в надежных руках! Спасибо за ваши комментарии здесь. Действительно, у меня есть тайная повестка дня, здесь я привел лишь простейший пример, воспроизводящий ошибку, которую пытаюсь обойти. Я пробую множество различных моделей rda, включающих dbMEM, поэтому их полезно автоматизировать исследование и визуализацию выбранной пространственной структуры. Хотя я также отследил ошибку до update(), я потерял след и даже не могу сказать, где/как вызывается ordiParseformula()... так что я достиг предела своих собственных навыков отладки (которые довольно скромны).   -  person Xavier GB    schedule 16.05.2014
comment
В любом случае, я поверю вам на слово, что не могу изменить значение envdepth, поэтому сейчас я просто определю объект в глобальной среде перед запуском моей функции. Если вы все же разберетесь с этим, я подозреваю, что могут быть другие благодарные исследователи, которые могут попытаться обернуть ordistep() для тестирования некоторых интересных приложений выбора модели с некоторыми другими связанными функциями. Здоровья и спасибо за помощь!   -  person Xavier GB    schedule 16.05.2014