Namespace specifier on gam package does not work

假装没事ソ 提交于 2019-12-10 23:07:59

问题


I don't understand why the below two gam models produce different results. The only difference is in one of the models I added the namespace specifier gam:: before the functions gam and s.

I want to do this because I am exploring the differences between running the gam function in the gam package and in the mgcv package.

library(ISLR)  
library(gam) 
gam.m3 <- gam::gam(wage ~ gam::s(year,4) + gam::s(age,5) + education,data=Wage) 
gam.m3.orig <- gam(wage ~ s(year,4) + s(age,5) + education, data=Wage)

#Coefficients are different
coef(gam.m3)[1]; coef(gam.m3.orig)[1] 

#Models are different
gam.m3$df.residual; gam.m3.orig$df.residual

Here is the output. It seems like the coefficients and degrees of freedom should not be different; in fact the two models should be exactly the same. But, they are different and I don't understand why. Any suggestions welcome, I'm kind of at a loss right now.

> library(ISLR)  
> library(gam) 
Loading required package: splines
Loading required package: foreach
Loaded gam 1.16

> gam.m3 <- gam::gam(wage ~ gam::s(year,4) + gam::s(age,5) + education,        data=Wage) 
Warning message:
In model.matrix.default(mt, mf, contrasts) :
  non-list contrasts argument ignored
> gam.m3.orig <- gam(wage ~ s(year,4) + s(age,5) + education, data=Wage)
Warning message:
In model.matrix.default(mt, mf, contrasts) :
  non-list contrasts argument ignored
> 
> #Coefficients are different
> coef(gam.m3)[1]; coef(gam.m3.orig)[1] 
(Intercept) 
  -2058.077 
(Intercept) 
  -2339.364 
> 
> #Models are different
> gam.m3$df.residual; gam.m3.orig$df.residual
[1] 2993
[1] 2986

回答1:


gam calls gam.fit and gam.fit has specific code for handling smoothers. This code only works correctly, if the model.frame's "terms" attribute has them correctly specified in its "specials" attribute. Otherwise, the smoothers are handled like any other function, which apparently gives a different result. If you want to know how exactly the smoothers are handled differently, you'll need to study the source code of gam.fit in detail.

Basically, this shows the crucial difference between your two calls to gam:

gam.smoothers()$slist
#[1] "s"      "lo"     "random"

attr(terms(wage ~ s(year,4) + s(age,5) + education, 
           specials = gam.smoothers()$slist), "specials")
#$s
#[1] 2 3
#
#$lo
#NULL
#
#$random
#NULL

attr(terms(wage ~  gam::s(year,4) + gam::s(age,5) + education, 
           specials = gam.smoothers()$slist), "specials")
#$s
#NULL
#
#$lo
#NULL
#
#$random
#NULL

Why do you need to use gam::s? Calling gam::gam should be sufficient to ensure that the correct smoother function is called (via the namespace lookup):

gam::gam(wage ~ s(year,4) + s(age,5) + education,data=Wage)  

Edit:

OK, mgcv::s actually masks gam::s on the search path. One approach to solve that problem can be found there.



来源:https://stackoverflow.com/questions/56437215/namespace-specifier-on-gam-package-does-not-work

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!