Почему предсказание на подмножестве исходных данных терпит неудачу с использованием gls, когда lm делает свое дело?

Проблема проиллюстрирована с помощью приведенного ниже кода. Если вы запустите его, вы увидите, что lm изящно обрабатывает прогноз, в то время как gls этого не делает. Это, скорее всего, проблема в predict.gls, но я не понимаю, почему. Это проблема только при использовании вызова фактора. Без него все работает нормально. Я вполне уверен, что predict.gls не работает, потому что в новом наборе данных нет всех уровней. Тем не менее, я с этим справился. Для меня это похоже на ошибку, но я недостаточно хорошо разбираюсь в коде gls, чтобы определить ее.

library(nlme)

# lm example
myfit<-lm(mpg~factor(cyl):disp+hp, data=mtcars)
mypred<-predict(myfit, mtcars[1:3, 1:7])

# gls example
myfit2<-gls(mpg~factor(cyl):disp+hp, data=mtcars)
mypred2<-predict(myfit2, mtcars[1:3, 1:7])

Вылетает с ошибкой:

# Error in X[, names(cf), drop = FALSE] : subscript out of bounds

Есть идеи?

Мой вывод R.version:

платформа x86_64-pc-linux-gnu
arch x86_64
os linux-gnu
система x86_64, linux-gnu
статус
основная 3
второстепенная 0.2
год 2013
месяц 09
день 25
svn rev 63987
язык R
version.string R версия 3.0.2 (25-09-2013) псевдоним Frisbee Sailing

Версия пакета nlme: «пакет ‘nlme’ версии 3.1-113"


person Dr. Mike    schedule 06.03.2014    source источник
comment
Я полагаю, что можно утверждать, что predict.gls должен использовать аргумент xlev в model.frame. Но авторы могут возразить, что вам действительно следует преобразовывать столбец так, чтобы он учитывал ваши данные заранее.   -  person joran    schedule 06.03.2014
comment
Я считаю, что ошибка вызвана отсутствием cyl==8 в newdata. mypred2<-predict(myfit2, mtcars[1:5, 1:7]) работает. Это можно считать ошибкой в ​​том, как predict.gls обрабатывает факторы.   -  person Roland    schedule 06.03.2014
comment
@joran Вы получаете ту же ошибку после mtcars$cyl <- factor(mtcars$cyl); myfit2<-gls(mpg~cyl:disp+hp, data=mtcars).   -  person Roland    schedule 06.03.2014
comment
@Roland Если это так, то это похоже на недосмотр в их использовании model.frame   -  person joran    schedule 06.03.2014
comment
@RScriv Я почти уверен, что, хотя в целом вы правы, это не является источником этой конкретной ошибки.   -  person joran    schedule 06.03.2014
comment
В коде я вижу, что флаг отбрасывания неиспользуемых уровней установлен в значение true в случае gls, как и в случае lm, так что мне кажется, что отсутствующие значения в факторе не должны вызывать проблем. Или я неверно истолковываю?   -  person Dr. Mike    schedule 07.03.2014
comment
@RScriv Вы не должны смотреть на полезность или качество предоставленной модели. Это просто фиктивный пример для иллюстрации проблемы. :)   -  person Dr. Mike    schedule 07.03.2014
comment
Я тоже столкнулся с этой ошибкой (очень поздно на вечеринку, но ошибка остается неисправленной). Быстрый и грязный обходной путь: привязать фрейм данных со всеми возможными значениями факторов к данным, которые вы передаете в качестве новых данных в функцию прогнозирования, а затем снова удалить его из результата.   -  person Erik A    schedule 12.08.2019


Ответы (1)


Поскольку я не являюсь автором predict.gls, я не могу точно ответить, почему это было написано именно так, но я не решаюсь предположить, что это ошибка в функции/пакете, которые были вокруг это долго.

В любом случае... причина, по которой это работает с lm, заключается в том, что когда predict.lm вызывает model.frame:

m <- model.frame(Terms, newdata, na.action = na.action, 
            xlev = object$xlevels)

он использует аргумент xlev и информацию об уровнях из самого подогнанного объекта модели. Я не верю, что объект gls вообще хранит эту информацию.

В predict.gls происходят две вещи. Во-первых, первоначальный вызов model.frame:

mfArgs <- list(formula = form, data = newdata, na.action = na.action)
mfArgs$drop.unused.levels <- TRUE
dataMod <- do.call("model.frame", mfArgs)

Обратите внимание, что здесь мы не используем аргумент xlev, и на самом деле мы явно говорим об удалении неиспользуемых уровней. Если вы создадите свою собственную версию predict.gls и прокомментируете нашу строку drop.unused.levels, она должна работать, если вы не вызываете factor в своей формуле!

Почему?

Потому что позже мы видим это:

X <- model.matrix(form, dataMod)

где ваша формула повторно применяется. Это означает, что factor вызывается для столбцов с несуществующими уровнями, заставляя их отбрасываться.

Поэтому, когда я использую версию predict.gls, которая комментирует строку drop.unused.levels, и я устанавливаю cyl в качестве коэффициента впереди во фрейме данных, он отлично генерирует прогнозы для меня.

Но я бы предложил спросить авторов пакетов, является ли это предполагаемым поведением или нет. Мне это кажется странным, но, как я уже сказал, для такого старого и хорошо используемого пакета кажется странным, что что-то подобное может быть непреднамеренным.

person joran    schedule 07.03.2014
comment
Я думаю, это ошибка. Сегодня я сообщил о чем-то похожем на ошибку: bugs.r-project.org /bugzilla3/show_bug.cgi?id=17228 - person Bill Denney; 22.02.2017