Làm thế nào để có được các giá trị được sử dụng trong lô.gam trong mgcv?


10

Tôi muốn tìm hiểu các giá trị (x, y)được sử dụng trong âm mưu plot(b, seWithMean=TRUE)trong gói mgcv . Có ai biết làm thế nào tôi có thể trích xuất hoặc tính toán các giá trị này?

Đây là một ví dụ:

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)

Tôi không quen thuộc với gamcác mô hình, nhưng bạn đã kiểm tra các thuộc tính khác nhau của đối tượng đó chưa? Bạn có thể nhìn vào tên của các đối tượng với names(b). Tôi đoán bất cứ chi tiết nào bạn có sau đó sẽ được giữ lại trong đối tượng đó ở đâu đó.
Đuổi theo

Câu trả lời:


19

Bắt đầu với mgcv1.8-6, plot.gamtrả về vô hình dữ liệu mà nó sử dụng để tạo các ô, tức là thực hiện

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

cung cấp cho bạn một danh sách với dữ liệu âm mưu pd.


TRẢ LỜI DƯỚI ĐÂY mgcv<= 1,8-5:

Tôi đã nhiều lần nguyền rủa sự thật rằng các chức năng cốt truyện mgcvkhông trả lại những thứ họ đang âm mưu - những gì tiếp theo là xấu nhưng nó hoạt động:

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)  
}

Rất cảm ơn vì sự giúp đỡ của bạn. Khi tôi sao chép mã của bạn lên đến plotData <<- c(plotData, pd[[i]])})) , thông báo sau xảy ra Error in fBody[[i]] : no such index at level 3. Bất cứ ý tưởng tại sao nó không hoạt động?

Thủ thuật "theo dõi" được sử dụng để làm việc cho tôi. Tuy nhiên, gần đây nó đã làm tôi thất bại. Tôi nghi ngờ nó phải thực hiện với phiên bản mới của gói mgcv (tôi hiện đang sử dụng phiên bản 1.8-3), có thể yêu cầu một đối số "tại" khác trong chức năng theo dõi. Ai đó có thể giúp tôi về cách lấy vectơ chính xác cho đối số "tại" của hàm theo dõi không? Rất cám ơn trước!

@Pepijn xem chỉnh sửa của tôi.
fabian

4

Gói visregcó thể tạo các ô hiệu ứng tương tự như GAM (nhưng có lẽ không giống nhau?) Và cũng cung cấp các thành phần cốt truyện như đầu ra, được định dạng như một danh sách. Sử dụng plyr người ta có thể tạo một khung dữ liệu của đầu ra. Thí dụ:

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

Đây sẽ không phải là một câu trả lời hoàn chỉnh. Tất cả các âm mưu cho gamcác đối tượng đang được thực hiện với chức năng plot.gam. Bạn có thể xem mã của nó bằng cách gõ

> plot.gam

trong bảng điều khiển R. Như bạn sẽ thấy mã là rất lớn. Những gì tôi đã lượm lặt được từ nó, rằng tất cả các âm mưu được thực hiện bằng cách thu thập thông tin liên quan trong pdđối tượng là một danh sách. Vì vậy, một trong những giải pháp khả thi sẽ là chỉnh sửa plot.gam, sử dụng editví dụ, để nó trả về đối tượng đó. Thêm pdtrước cuối cùng }sẽ là đủ. Tôi sẽ khuyên bạn thêm invisible(pd), để đối tượng này chỉ được trả về nếu bạn yêu cầu:

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

Sau đó kiểm tra đối tượng này và tìm kiếm trong mã của plot.gamcác dòng với plotlines. Sau đó, bạn sẽ thấy những gì có liên quan xygiá trị xuất hiện trong cốt truyện.


Rất tiếc, tôi đã không nhìn thấy bạn khi tôi đăng câu trả lời của mình. Chà, dù sao nó cũng chi tiết hơn một chút ....
fabians

@fabians, đừng lo lắng, tôi sẽ không đăng bài của tôi nếu tôi thấy bạn. Tôi vạch ra ý tưởng chung, bạn đã cung cấp mã. Vì câu hỏi yêu cầu mã, câu trả lời của bạn là tốt hơn.
mpiktas

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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.