26

パッケージgamからを使用してモデルをフィッティングし、結果を に保存します。これまでのところ、 を使用して滑らかなコンポーネントを見てきました。私は最近 ggplot2 の使用を開始し、その出力が気に入っています。ggplot2 を使用してこれらのグラフをプロットすることは可能ですか?mgcvmodelplot(model)

次に例を示します。

x1 = rnorm(1000)
x2 = rnorm(1000)
n = rpois(1000, exp(x1) + x2^2)

model = gam(n ~ s(x1, k=10) + s(x2, k=20), family="poisson")
plot(model, rug=FALSE, select=1)
plot(model, rug=FALSE, select=2)

そして、私はフィット感ではなく、興味がs(x1, k=10)あります。s(x2, k=20)

部分的な答え:

私はより深く掘り下げてplot.gammgcv:::plot.mgcv.smooth滑らかな成分から予測効果と標準誤差を抽出する独自の関数を構築しました。すべてのオプションとケースを処理するわけではないplot.gamので、部分的な解決策としか考えていませんが、私にとってはうまく機能します。

EvaluateSmooths = function(model, select=NULL, x=NULL, n=100) {
  if (is.null(select)) {
    select = 1:length(model$smooth)
  }
  do.call(rbind, lapply(select, function(i) {
    smooth = model$smooth[[i]]
    data = model$model

    if (is.null(x)) {
      min = min(data[smooth$term])
      max = max(data[smooth$term])
      x = seq(min, max, length=n)
    }
    if (smooth$by == "NA") {
      by.level = "NA"
    } else {
      by.level = smooth$by.level
    }
    range = data.frame(x=x, by=by.level)
    names(range) = c(smooth$term, smooth$by)

    mat = PredictMat(smooth, range)
    par = smooth$first.para:smooth$last.para

    y = mat %*% model$coefficients[par]

    se = sqrt(rowSums(
      (mat %*% model$Vp[par, par, drop = FALSE]) * mat
    ))

    return(data.frame(
      label=smooth$label
      , x.var=smooth$term
      , x.val=x
      , by.var=smooth$by
      , by.val=by.level
      , value = y
      , se = se
    ))
  }))
}

これにより、滑らかなコンポーネントを含む「溶融」データ フレームが返されるため、ggplot上記の例で使用できるようになりました。

smooths = EvaluateSmooths(model)

ggplot(smooths, aes(x.val, value)) + 
  geom_line() + 
  geom_line(aes(y=value + 2*se), linetype="dashed") + 
  geom_line(aes(y=value - 2*se), linetype="dashed") + 
  facet_grid(. ~ x.var)

一般的なケースでこれを可能にするパッケージを誰かが知っていれば、私は非常に感謝しています。

4

3 に答える 3

21

visreg パッケージを plyr パッケージと組み合わせて使用​​できます。visreg は基本的に、predict() を使用できるすべてのモデルをプロットします。

library(mgcv)
library(visreg)
library(plyr)
library(ggplot2)

# Estimating gam model:
x1 = rnorm(1000)
x2 = rnorm(1000)
n = rpois(1000, exp(x1) + x2^2)
model = gam(n ~ s(x1, k=10) + s(x2, k=20), family="poisson")

# use plot = FALSE to get plot data from visreg without plotting
plotdata <- visreg(model, type = "contrast", plot = FALSE)

# The output from visreg is a list of the same length as the number of 'x' variables,
#   so we use ldply to pick the objects we want from the each list part and make a dataframe: 
smooths <- ldply(plotdata, function(part)   
  data.frame(Variable = part$meta$x, 
             x=part$fit[[part$meta$x]], 
             smooth=part$fit$visregFit, 
             lower=part$fit$visregLwr, 
             upper=part$fit$visregUpr))

# The ggplot:
ggplot(smooths, aes(x, smooth)) + geom_line() +
  geom_line(aes(y=lower), linetype="dashed") + 
  geom_line(aes(y=upper), linetype="dashed") + 
  facet_grid(. ~ Variable, scales = "free_x")

全体を関数に入れ、モデルからの残差を表示するオプションを追加できます (res = TRUE):

ggplot.model <- function(model, type="conditional", res=FALSE, 
                       col.line="#7fc97f", col.point="#beaed4", size.line=1, size.point=1) {
  require(visreg)
  require(plyr)
  plotdata <- visreg(model, type = type, plot = FALSE)
  smooths <- ldply(plotdata, function(part)   
    data.frame(Variable = part$meta$x, 
             x=part$fit[[part$meta$x]], 
             smooth=part$fit$visregFit, 
             lower=part$fit$visregLwr, 
             upper=part$fit$visregUpr))
  residuals <- ldply(plotdata, function(part)
    data.frame(Variable = part$meta$x, 
               x=part$res[[part$meta$x]], 
               y=part$res$visregRes))
  if (res)
    ggplot(smooths, aes(x, smooth)) + geom_line(col=col.line, size=size.line) +
      geom_line(aes(y=lower), linetype="dashed", col=col.line, size=size.line) +
      geom_line(aes(y=upper), linetype="dashed", col=col.line, size=size.line) +
      geom_point(data = residuals, aes(x, y), col=col.point, size=size.point) +
      facet_grid(. ~ Variable, scales = "free_x")
  else
    ggplot(smooths, aes(x, smooth)) + geom_line(col=col.line, size=size.line) +
      geom_line(aes(y=lower), linetype="dashed", col=col.line, size=size.line) +
      geom_line(aes(y=upper), linetype="dashed", col=col.line, size=size.line) +
      facet_grid(. ~ Variable, scales = "free_x")
  }

ggplot.model(model)
ggplot.model(model, res=TRUE)

残差のないggplot 残差のあるggplot 色はhttp://colorbrewer2.org/から選択されます。

于 2014-01-17T09:59:32.363 に答える
5

参考までに、オブジェクトvisregを直接出力できます。gg

visreg(model, "x1", gg=TRUE)

ここに画像の説明を入力

于 2017-06-20T16:44:28.923 に答える