如何获取mgcv中plot.gam中使用的值?


10

我想找出在mgcv软件包(x, y)中绘图所使用的值。有谁知道我如何提取或计算这些值?plot(b, seWithMean=TRUE)

这是一个例子:

library(mgcv) 
set.seed(0)
dat <- gamSim(1, n=400, dist="normal", scale=2) 
b   <- gam(y~s(x0), data=dat) 
plot(b, seWithMean=TRUE)

我对gam模型不熟悉,但是您检查了该对象的不同属性吗?您可以使用来查看对象的名称names(b)。我想您所追求的任何细节都将保留在该对象的某个位置。
大通

Answers:


19

mgcv1.8-6 开始,plot.gam不可见地返回其用于生成图的数据,即

pd <- plot(<some gam() model>)

在中列出了绘图数据pd


低于mgcv<= 1.8-5的答案:

我一再咒骂一个事实,因为plot函数mgcv不会返回他们正在绘制的内容-如下是难看的,但是它起作用了:

library(mgcv) 
set.seed(0)
dat <- gamSim(1, n = 400, dist = "normal", scale = 2)
b <- gam(y ~ s(x0) + s(x1) + s(x2) + s(x3), data = dat)

plotData <- list()
trace(mgcv:::plot.gam, at = list(c(27, 1)), 
  ## tested for mgcv_1.8-4. other versions may need different at-argument.
  quote({
    message("ooh, so dirty -- assigning into globalenv()'s plotData...")
    plotData <<- pd
    }))
mgcv::plot.gam(b, seWithMean = TRUE, pages = 1)

par(mfrow = c(2, 2))
for (i in 1:4) {
  plot(plotData[[i]]$x, plotData[[i]]$fit, type = "l", xlim = plotData[[i]]$xlim,
    ylim = range(plotData[[i]]$fit + plotData[[i]]$se, plotData[[i]]$fit -
      plotData[[i]]$se))
  matlines(plotData[[i]]$x, cbind(plotData[[i]]$fit + plotData[[i]]$se, 
    plotData[[i]]$fit - plotData[[i]]$se), lty = 2, col = 1)
  rug(plotData[[i]]$raw)  
}

非常感谢您的帮助。当我最多复制您的代码时 plotData <<- c(plotData, pd[[i]])})) ,会出现以下消息Error in fBody[[i]] : no such index at level 3。任何想法为什么它不起作用?

“跟踪”技巧曾经为我工作。但是,它最近使我失败了。我怀疑这与新版本的mgcv软件包有关(我当前使用的是1.8-3版本),这可能需要trace函数中使用不同的“ at”参数。谁能帮助我如何为跟踪函数的“ at”参数获取正确的向量?提前谢谢了!

@Pepijn看到我的编辑。
fabians 2015年

4

打包程序visreg可以制作类似于GAM的效果图(但可能不完全相同?),并且确实将图的组成部分也作为输出提供,并格式化为列表。使用plyr可以制作输出的数据帧。例:

plot <- visreg(model, type = "contrast")
smooths <- ldply(plot, function(part)   
  data.frame(x=part$x$xx, smooth=part$y$fit, lower=part$y$lwr, upper=part$y$upr))

3

这将不是一个完整的答案。所有gam对象的绘制都是通过function完成的plot.gam。您只需输入以下内容即可查看其代码

> plot.gam

在R控制台中。如您所见,代码非常庞大。我从中收集到的信息是,所有绘图都是通过在pd列表对象中收集相关信息来完成的。因此,可能的解决方案之一是plot.gam使用edit例如edit ,以使其返回该对象。pd在末尾之前添加}就足够了。我建议添加invisible(pd),以便仅在您要求时才返回此对象:

> pd <- plot(b,seWithMean = TRUE)

然后检查该对象,并在代码搜索plot.gam与线plotlines。然后,您将看到相关xy值中的哪一个出现在图中。


糟糕,我发布答案时没有看到您的。嗯,这是一个小更详细反正....
费边社

@fabians,不用担心,如果我看到你的,我也不会发布我的。我概述了总体思路,您已经提供了代码。由于问题要求提供代码,因此您的答案会更好。
mpiktas 2011年

0
## And this is the code for multiple variables!
require(mgcv)
n      = 100
N      = n
tt     = 1:n
arfun  = c(rep(.7,round(n/3)),rep(.3,round(n/3)),rep(-.3,ceiling(n/3)))
arfun2 = c(rep(.8,round(n/3)),rep(.3,round(n/3)),rep(-.3,ceiling(n/3)))
int    = .1*(tt-mean(tt))/max(tt)-.1*((tt-mean(tt))/(max(tt)/10))^2
y      = rep(NA,n)
s.sample <- N
x        <- 10*rnorm(s.sample)
z        <- 10*rnorm(s.sample)
for(j in 1:n){
  y[j]=int[j]+x[j]*arfun[j]+z[j]*arfun2[j]+rnorm(1)  
}

mod = gam(y ~ s(tt) + s(tt, by=x) + s(tt, by=z)) 
## getting the data out of the plot
plotData <- list()
trace(mgcv:::plot.gam, at=list(c(25,3,3,3)),
      # this gets you to the location where plot.gam calls 
      #    plot.mgcv.smooth (see ?trace)
      # plot.mgcv.smooth is the function that does the actual plotting and
      # we simply assign its main argument into the global workspace
      # so we can work with it later.....

      quote({
        # browser()
        print(pd)
        plotData <<- c(plotData, pd)
      }))

# test: 
mgcv::plot.gam(mod, seWithMean=TRUE)


# see if it succeeded
slct = 3
plot(plotData[[slct]]$x, plotData[[slct]]$fit, type="l", xlim=plotData$xlim, 
     ylim=range(plotData[[slct]]$fit + plotData[[slct]]$se, plotData[[slct]]$fit - 
                plotData[[slct]]$se))
matlines(plotData[[slct]]$x, 
         cbind(plotData[[slct]]$fit + plotData[[slct]]$se, 
               plotData[[slct]]$fit - plotData[[slct]]$se), lty=2, col=1)
rug(plotData[[slct]]$raw)
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.