2013-11-01 1 views
19

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

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) 

一般的なケース私は非常に感謝します。

+1

ggplotはこれだけやる 'メソッド= 'gam'' –

+0

、' 'geom_smooth'ためpredict'を使用していますそれはフィットを表示し、滑らかな用語を表示しません。だから私はこれが解決策だとは思わない。 – unique2

+0

データセットにリンクします(開始点と複製しようとしているプロットとして 'mgcv'の例を挙げてください)。 –

答えて

18

vislyパッケージと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 with residuals 色はhttp://colorbrewer2.org/から選ばれ

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 without residuals

+0

一時ファイルにプロットするのではなく、何も表示せずにプロットデータを返すために 'visreg'に' plot = FALSE'引数を使用できるようになりました。しかし、私は返されたオブジェクトがあなたが想定しているものから変更されていると思います。 – Spacedman

+0

投稿はおそらく更新が必要です。 'plyr :: ldply()'呼び出しで何か問題があるので、上のコードを実行するとオブジェクト 'smooths'が空に返されます。 –

+0

@ pat-sありがとう、そうです。投稿は更新され、うまくいくはずです。 –

2

FYI、visregをそのまま出力ggオブジェクトことができます:私はgeom_smoothを理解したよう

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

enter image description here

関連する問題