Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/r/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
R 提取用于在mgcv中生成平滑绘图的数据_R_Trace_Mgcv - Fatal编程技术网

R 提取用于在mgcv中生成平滑绘图的数据

R 提取用于在mgcv中生成平滑绘图的数据,r,trace,mgcv,R,Trace,Mgcv,描述了如何提取用于绘制拟合gam模型平滑组件的数据。它是有效的,但只有当存在一个平滑变量时才有效。我有不止一个平滑变量,不幸的是,我只能从序列的最后一个提取平滑。以下是一个例子: library(mgcv) a = rnorm(100) b = runif(100) y = a*b/(a+b) mod = gam(y~s(a)+s(b)) summary(mod) plotData <- list() trace(mgcv:::plot.gam, at=list(c(25,3,3,3)

描述了如何提取用于绘制拟合gam模型平滑组件的数据。它是有效的,但只有当存在一个平滑变量时才有效。我有不止一个平滑变量,不幸的是,我只能从序列的最后一个提取平滑。以下是一个例子:

library(mgcv)
a = rnorm(100)
b = runif(100)
y = a*b/(a+b)

mod = gam(y~s(a)+s(b))
summary(mod)

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()
                    plotData <<- c(plotData, pd[[i]])
                }))
plot(mod,pages=1)
plotData
库(mgcv)
a=rnorm(100)
b=runif(100)
y=a*b/(a+b)
mod=gam(y~s(a)+s(b))
摘要(mod)
mgcv>=1.8-6的plotData更新答案
从mgcv的1.8-6版开始,
plot.gam()
现在以不可见的方式(从更改日志)返回打印数据:

  • plot.gam现在以静默方式返回打印数据列表,以帮助高级 用户(Fabian Scheipl)制作托管地块
因此,使用原始答案中下面所示示例中的
mod
,您可以

> plotdata <- plot(mod, pages = 1)
> str(plotdata)
List of 2
 $ :List of 11
  ..$ x      : num [1:100] -2.45 -2.41 -2.36 -2.31 -2.27 ...
  ..$ scale  : logi TRUE
  ..$ se     : num [1:100] 4.23 3.8 3.4 3.05 2.74 ...
  ..$ raw    : num [1:100] -0.8969 0.1848 1.5878 -1.1304 -0.0803 ...
  ..$ xlab   : chr "a"
  ..$ ylab   : chr "s(a,7.21)"
  ..$ main   : NULL
  ..$ se.mult: num 2
  ..$ xlim   : num [1:2] -2.45 2.09
  ..$ fit    : num [1:100, 1] -0.251 -0.242 -0.234 -0.228 -0.224 ...
  ..$ plot.me: logi TRUE
 $ :List of 11
  ..$ x      : num [1:100] 0.0126 0.0225 0.0324 0.0422 0.0521 ...
  ..$ scale  : logi TRUE
  ..$ se     : num [1:100] 1.25 1.22 1.18 1.15 1.11 ...
  ..$ raw    : num [1:100] 0.859 0.645 0.603 0.972 0.377 ...
  ..$ xlab   : chr "b"
  ..$ ylab   : chr "s(b,1.25)"
  ..$ main   : NULL
  ..$ se.mult: num 2
  ..$ xlim   : num [1:2] 0.0126 0.9906
  ..$ fit    : num [1:100, 1] -0.83 -0.818 -0.806 -0.794 -0.782 ...
  ..$ plot.me: logi TRUE
现在生成预测数据

pdat <- with(dat,
             data.frame(a = c(seq(min(a), max(a), length = 100),
                              rep(mean(a), 100)),
                        b = c(rep(mean(b), 100),
                              seq(min(b), max(b), length = 100))))
pdat <- transform(pdat, fitted = pred$fit)
pdat <- transform(pdat, upper = fitted + (1.96 * pred$se.fit),
                        lower = fitted - (1.96 * pred$se.fit))
然后使用变量
a
的行
1:100
和变量
b的行
101:200
绘制平滑曲线

layout(matrix(1:2, ncol = 2))
## plot 1
want <- 1:100
ylim <- with(pdat, range(fitted[want], upper[want], lower[want]))
plot(fitted ~ a, data = pdat, subset = want, type = "l", ylim = ylim)
lines(upper ~ a, data = pdat, subset = want, lty = "dashed")
lines(lower ~ a, data = pdat, subset = want, lty = "dashed")
## plot 2
want <- 101:200
ylim <- with(pdat, range(fitted[want], upper[want], lower[want]))
plot(fitted ~ b, data = pdat, subset = want, type = "l", ylim = ylim)
lines(upper ~ b, data = pdat, subset = want, lty = "dashed")
lines(lower ~ b, data = pdat, subset = want, lty = "dashed")
layout(1)
layout(matrix(1:2, ncol = 2))
## plot 1
want <- 1:100
ylim <- with(pdat, range(fitted[want], upper[want], lower[want]))
plot(fitted ~ a, data = pdat, subset = want, type = "l", ylim = ylim)
lines(upper ~ a, data = pdat, subset = want, lty = "dashed")
lines(lower ~ a, data = pdat, subset = want, lty = "dashed")
## plot 2
want <- 101:200
ylim <- with(pdat, range(fitted[want], upper[want], lower[want]))
plot(fitted ~ b, data = pdat, subset = want, type = "l", ylim = ylim)
lines(upper ~ b, data = pdat, subset = want, lty = "dashed")
lines(lower ~ b, data = pdat, subset = want, lty = "dashed")
layout(1)
预测各个平滑项对拟合值的贡献 上面2中的想法几乎是以相同的方式实现的,但我们要求
type=“terms”

只需将
$fit
矩阵中的相关列与
pdat
中的同一协变量对应,再次仅使用第一组或第二组100行。再比如说

pdat <- transform(pdat, fitted = c(pred2$fit[1:100, 1], 
                                   pred2$fit[101:200, 2]))
pdat <- transform(pdat, upper = fitted + (1.96 * c(pred2$se.fit[1:100, 1], 
                                                   pred2$se.fit[101:200, 2])),
                        lower = fitted - (1.96 * c(pred2$se.fit[1:100, 1], 
                                                   pred2$se.fit[101:200, 2])))
这就产生了


注意这张图和之前绘制的图之间的细微差别。第一个图包括截距项的影响和
b
平均值的贡献。在第二个图中,只显示了
a
的平滑度值。

加文给出了一个很好的答案,但我想根据原始参考帖子提供一个答案(因为我刚刚花了很长时间弄清楚它是如何工作的:)

我直接使用了来自的代码,还发现我只返回了最后一个模型。这是因为跟踪代码片段被放置在mgcv::plot.gam函数中的位置。您需要确保代码被放置在迭代m的for循环中,并且您可以通过at参数来控制它

以下跟踪对我的mgcv版本非常有效::plot.gam

plotData <<- list()
trace(mgcv:::plot.gam, at=list(c(26,3,4,3)), 
quote({
       plotData[[i]] <<- pd[[i]]
  })
)
现在plotData的元素将对应于绘制的不同变量。我发现有两个函数非常有助于确定插入此跟踪调用的正确位置

edit(mgcv:::plot.gam)
as.list(body(mgcv::::plot.gam))

除了Gavin Simpson的精彩回答之外,现在还有一个名为R的软件包,它提供了几个用于可视化与mgcv匹配的GAM的功能

其中有绘图\u平滑(根据帮助“绘制总效果并选择性地删除随机效果”)。如果我正确理解文档,这接近Gavin Simpson提到的选项1


还有一个get_modelterm,它返回一个列表(或者可选的data.frame),其中包含所选平滑项的估计值。这似乎相当于选项2(或从plot.gam返回的值,但没有绘图)。

我现在添加了从最初显示的输出生成绘图的示例。如果可以,我会多次向上投票以获得如此详细的答复。
> lapply(pred2, head)
$fit
        s(a)       s(b)
1 -0.2509313 -0.1058385
2 -0.2422688 -0.1058385
3 -0.2344211 -0.1058385
4 -0.2282031 -0.1058385
5 -0.2243635 -0.1058385
6 -0.2233309 -0.1058385

$se.fit
      s(a)      s(b)
1 2.115990 0.1880968
2 1.901272 0.1880968
3 1.701945 0.1880968
4 1.523536 0.1880968
5 1.371776 0.1880968
6 1.251803 0.1880968
pdat <- transform(pdat, fitted = c(pred2$fit[1:100, 1], 
                                   pred2$fit[101:200, 2]))
pdat <- transform(pdat, upper = fitted + (1.96 * c(pred2$se.fit[1:100, 1], 
                                                   pred2$se.fit[101:200, 2])),
                        lower = fitted - (1.96 * c(pred2$se.fit[1:100, 1], 
                                                   pred2$se.fit[101:200, 2])))
layout(matrix(1:2, ncol = 2))
## plot 1
want <- 1:100
ylim <- with(pdat, range(fitted[want], upper[want], lower[want]))
plot(fitted ~ a, data = pdat, subset = want, type = "l", ylim = ylim)
lines(upper ~ a, data = pdat, subset = want, lty = "dashed")
lines(lower ~ a, data = pdat, subset = want, lty = "dashed")
## plot 2
want <- 101:200
ylim <- with(pdat, range(fitted[want], upper[want], lower[want]))
plot(fitted ~ b, data = pdat, subset = want, type = "l", ylim = ylim)
lines(upper ~ b, data = pdat, subset = want, lty = "dashed")
lines(lower ~ b, data = pdat, subset = want, lty = "dashed")
layout(1)
plotData <<- list()
trace(mgcv:::plot.gam, at=list(c(26,3,4,3)), 
quote({
       plotData[[i]] <<- pd[[i]]
  })
)
if (m > 0) 
    for (i in 1:m) if (pd[[i]]$plot.me && (is.null(select) || 
        i == select)) {
edit(mgcv:::plot.gam)
as.list(body(mgcv::::plot.gam))