anova.cca не может найти объект в пользовательской функции

Я хочу выполнить ту же последовательность анализа rda (подгонка модели, проверка значимости модели, оси и термина, построение данных) для подмножеств одних и тех же наборов данных. Поэтому я написал функцию. Теперь проблема в том, что вызов функции anova.cca не работает внутри функции, когда я хочу проверить ось. Он не может найти набор данных Y.sub

Ошибка в eval(expr, envir, enclos): объект 'RV.sub' не найден

Минимальный рабочий пример:

library(vegan)
data(dune)
data(dune.env)

rda.subsetfunc <- function(RV, Y){
  #RV.sub <- subset(RV, !Y$Use%in%c("BF"))
  #Y.sub  <- subset(Y, !Y$Use%in%c("BF"))
  RV.sub <- RV; Y.sub <- Y
  rda.mod <- rda(RV.sub ~ Manure, Y.sub)
  axis.test <- anova(rda.mod,  by = "axis")

  return(list(rda.mod, axis.test))
}

rda.subsetfunc(RV = dune, Y = dune.env)

Я нашел некоторые другие связанные вопросы, такие как здесь но это кажется намного сложнее, чем то, что я делаю. Я попытался реализовать подход do.call, как указано здесь, но Я не мог заставить его работать. Если это действительно невозможно сделать без глубокого изучения функций, я найду способ обойти это программированием. Но мне кажется, что я пытаюсь сделать что-то, что имеет смысл. Так что, вероятно, более вероятно, что я делаю что-то неправильное, чем то, что я делаю что-то невозможное.


person Nightingale    schedule 20.06.2017    source источник
comment
Я сделал глупую ошибку, набрав исходный вопрос. Я изначально поставил rda.subsetfunc(RV = dune, Y = Y.sub), который не работает по понятным причинам. Спасибо @chi-pak за то, что заставил меня осознать   -  person Nightingale    schedule 20.06.2017
comment
Это не проблема, потому что RV.sub — это матрица X, а не столбец Y. Так работает rda-функция. Моя функция работает нормально, если я опускаю анова-функцию. Это тот, кто вызывает проблемы. Кстати, я очень ценю вашу помощь!   -  person Nightingale    schedule 20.06.2017
comment
Со страницы справки rda. data(dune) data(dune.env) dune.Manure <- rda(dune ~ Manure, dune.env) Таким образом, RV.sub не находится в Y.sub, это правильно.   -  person Nightingale    schedule 20.06.2017
comment
Да, ты прав, но я все еще думаю, что это часть проблемы. Посмотрите на dune.Manure. Это показывает это: rda(formula = dune ~ Manure, data = dune.env). По какой-то причине этот dune.Manure ищет переменные в среде parent... Если вы объявите RV.sub <- dune в среде parent, функция не вернет ошибку.   -  person CPak    schedule 20.06.2017
comment
Причина, по которой я не хотел объявлять RV.sub <- dune в родительском элементе, заключается в том, что мой код немного сложнее, чем просто взять подмножество. Но тогда я просто сделаю два последовательных сценария. Один для создания подмножеств, а другой берет подмножества и выполняет rda. Хотя действительно жаль. И еще раз, я очень ценю, что вы нашли время, чтобы помочь мне.   -  person Nightingale    schedule 20.06.2017
comment
Это проблема области видимости в anova.cca(..., by="axis"), которая должна находить элементы из нескольких разных сред при обновлении формулы. Встраивание функции действительно может потерпеть неудачу. Однако переработанная функция на github.com/vegandevs/vegan, похоже, работает с этим примером.   -  person Jari Oksanen    schedule 20.06.2017
comment
Спасибо @jari за подтверждение того, что в настоящее время это действительно невозможно. На данном этапе я воздержусь от использования кода разработчика. Я намерен опубликовать свой код и данные вместе со своей статьей и чувствую, что использование этой обновленной функции слишком усложнит ситуацию. Тем не менее, это определенно хороший совет для тех, кто может столкнуться с той же проблемой. Если вы опубликуете это как ответ, я приму.   -  person Nightingale    schedule 21.06.2017


Ответы (1)


Это проблема области действия в anova.cca(..., by="axis"), которая должна находить элементы из нескольких разных сред при обновлении формулы (я не буду вдаваться в технические подробности). Вы действительно не можете встроить функцию для анализа значений осей. Это известная проблема. Мы решили эту проблему в разрабатываемой версии vegan. Переработанная функция в https://github.com/vegandevs/vegan, похоже, работала с этим пример. Там коренным образом изменены все функции ординации и значения, и они еще не до конца закончены. Мы планируем выпустить их в веганской версии 2.5-0 в последнем квартале 2017 года, но они еще не закончены.

Проблема в том, что anova.cca(..., by = "axis") должен найти элементы, которые он создает внутри функции, и, кроме того, он может найти элементы, которые были доступны при построении исходной модели, но не может найти элементы, которые вы создаете в функциях, встраивающих эту функцию. Вы должны обойти это, заставив свою функцию встраивания записывать свои объекты где-то, где их можно найти. Самое простое (но грязное) решение — записать их в родительскую среду с помощью <<-. Следующая версия вашей функции добавляет этот <<- и, похоже, работает в веганской версии 2.4-3.

rda.subsetfunc <- function(RV, Y){
  RV.sub <<- RV; Y.sub <- Y
  rda.mod <- rda(RV.sub ~ Manure, Y.sub)
  axis.test <- anova(rda.mod,  by = "axis")

  list(rda.mod, axis.test)
}

rda.subsetfunc(RV = dune, Y = dune.env)
person Jari Oksanen    schedule 22.06.2017
comment
Ого, это изящный (но немного опасный) трюк! Спасибо - person Nightingale; 22.06.2017