В версии R 3.6.3 моя функция Predict.gam дает результат. Когда я использую R 4.x, я получаю ошибки для некоторых типов прогнозов, но не для других.
Моя цель — иметь возможность использовать этот код в R4.
library(gam)
gm1 <- predCol ~ s(VCF_nontree) + s(VCF_nonvegt) + s(VCF_treecov) +
s(CCI_URBAN) + s(GPW_POP)
gm2 <- predCol ~ offset(offset) + s(ACC) + s(EARS) + s(MAT) + s(PTA) +
s(SLP) + s(SOC) + s(TWI)
set.seed(42)
c2 <- data.frame(
predCol = abs(rnorm(677072, 0.022, 0.03)),
VCF_nontree = rnorm(677072, 6533, 16.3),
VCF_nonvegt =rnorm(677072, 15.9, 12.03),
VCF_treecov = rnorm(677072, 18.1, 18.3),
CCI_URBAN = rnorm(677072, 0.00412, 0.013),
GPW_POP = rnorm(677072, 2.23, 1.28),
offset = rep(NA, 677072),
ACC = rnorm(677072, 612.6, 456.5),
EARS = rnorm(677072, 731.88, 291.4),
MAT = rnorm(677072, 22.69, 2.56),
PTA = rnorm(677072, 124.13, 307.9),
SLP = rnorm(677072, 2.41, 3.71),
SOC = rnorm(677072, 0.609, 0.33),
TWI = rnorm(677072, 118.2, 15.35)
)
fitModel1.1 <- gam::gam(gm1,
data = c2,
family = quasibinomial)
c2$offset <- as.numeric(predict(fitModel1.1,
type = "link"))
fitModel1 <- gam::gam(gm2,
data = c2,
family=quasibinomial)
fm1 <- predict(fitModel1,
se.fit = TRUE,
type = "response")
в R3 получаю результат, в R4 получаю такую ошибку:
Error in NextMethod("predict") : no method to invoke
R3, игра 1.20, R4 игра 1.22-2
в R4 этот вызов прогнозирования работает:
fm2 <- predict(fitModel1,
se.fit = TRUE,
type = "link")
если вы установите se.fit = FALSE, то это сработает. Кажется, проблема с se.fit? Кто-нибудь знает обходной путь?
mgcv::gam
у меня отлично работает. Возможно, стоит связаться с сопровождающим игры.
Похоже, это потому, что predict.Gam
вызывает predict.Gam
прямо в операторе switch
. Если он просто вызвал predict()
с обновленными аргументами (чтобы сначала получить SE по шкале ссылок), то все работает.
@GavinSimpson Думаю, я не понимаю твой ответ. Знаете ли вы, как я могу явно вызвать предикат(), чтобы он работал?
@jay.sf да, я также могу заставить работать mgcv::gam, но время стены намного выше, и для воспроизводимости я бы предпочел gam::gam. В моем рабочем коде я вызываю функцию gam() много раз итеративно, а затраты времени на mgcv::gam слишком велики по сравнению с gam::gam для моего вычислительного оборудования. Возможно, есть способ ускорить mgcv::gam. Пока mgcv::bam у меня не работает.
@weeedaMat.Stat. что ж, если вы знаете, как редактировать код в пространстве имен (fixInNamespace()
), вы можете найти оператор switch()
и решить проблему. Вы также можете отправить Тревору электронное письмо с отчетом об ошибке и указать конкретную проблему. Вы не можете исправить это самостоятельно (кроме временного использования fixInNamespace()
), но нужны ли вам стандартные ошибки, поскольку это работает с se.fit = FALSE
Действительно ли mgcv::gam()
медленнее, чем gam::gam()
, если вы установите fx = TRUE
на каждом сглаживании (в версии mgcv), чтобы соответствовать сопоставимым моделям?
Я не знаю, как это правильно отформатировать: fitModel1 <- gam::gam(gm2, data = c2, Family = квазибиномиальный) fitModel1mgcv <- mgcv::gam(gm2, data = c2, Family = квазибиномиальный, fx = TRUE ) mb <- microbenchmark( "gam::gam" = gam::gam(gm2, data = c2, семейство = квазибиномиальное), "mgcv::gam" = mgcv::gam(gm2, data = c2, семейство = квазибиномиальное) , fx = ИСТИНА), раз = 3) expr min lq mean median uq max neval gam::gam 25.48137 25.51025 28.30767 25.53912 29.72081 33.90251 3 mgcv::gam 426.72876 432.04498 474.16970 437.36121 497.89018 558.41914 3
Это выглядит довольно странно. Почему бы вам не написать разработчику игры электронное письмо, вы можете дать ссылку на этот вопрос.
fx = TRUE
должен идти на каждом сглаживании, а не как аргумент для gam()
. Вы можете просто отредактировать свой вопрос, а не пытаться форматировать вывод в комментарии.
обновлять Разработчик пакета устранил проблему, и новая версия gam on cran больше не нуждается в обходном пути и работает так, как задумано!
Следуя совету @GavinSimpson, я нашел обходной путь: специальную функцию Predict.gam(), которую можно вызвать в Rscript, используя
source("custom_predict_Gam.R")
Я сохраняю приведенный ниже скрипт в своем рабочем каталоге, затем в R 4 использую source()
, а затем вызываю функцию следующим образом:
fm1 <- custom_predict_Gam(fitModel1,
se.fit = TRUE,
type = "response")
и получите результаты, идентичные результатам R 3.
Спасибо за вклад каждого. Это сделало меня счастливым. гам::счастлив...
На случай, если это кому-нибудь пригодится, вот функция, которую я сохраняю как custom_predict_Gam.R:
# custom_predict_Gam.R
# this file replaces the predict.gam on line 18 with predict. The reason is because predict.gam is broken in R 4.
custom_predict_Gam <- function (object, newdata, type = c("link", "response", "terms"),
dispersion = NULL, se.fit = FALSE, na.action = na.pass, terms = labels(object),
...)
{
type <- match.arg(type)
if (missing(newdata)) {
if (inherits(object, "Gam") && !is.null(object$smooth)) {
if (se.fit)
switch(type,
response = {
out <- predict(object, type = "link", se.fit = TRUE, ...)
famob <- family(object)
out$se.fit <- drop(out$se.fit * abs(famob$mu.eta(out$fit)))
out$fit <- fitted(object)
out
},
link = {
out <- NextMethod("predict")
out$fit <- object$additive.predictors
TS <- out$residual.scale^2
TT <- ncol(object$var)
out$se.fit <- sqrt(out$se.fit^2 + TS * object$var %*%
rep(1, TT))
out
},
terms = {
out <- NextMethod("predict")
TT <- dimnames(s <- object$smooth)[[2]]
TT = intersect(terms, TT)
out$fit[, TT] <- out$fit[, TT] + s[, TT]
TS <- out$residual.scale^2
out$se.fit[, TT] <- sqrt(out$se.fit[, TT]^2 +
TS * object$var[, TT])
out
})
else switch(type,
terms = {
out <- NextMethod("predict")
TT <- dimnames(s <- object$smooth)[[2]]
TT = intersect(terms, TT)
out[, TT] <- out[, TT] + s[, TT]
out
},
link = object$additive.predictors,
response = object$fitted)
}
else {
if (inherits(object, "Gam")) {
if (type == "link" && !se.fit)
object$additive.predictors
else NextMethod("predict")
}
else UseMethod("predict")
}
}
else newdata.predict.Gam(object, newdata, type, dispersion,
se.fit, na.action, terms, ...)
}
* Забыл добавить, я также написал письмо сопровождающему пакета игры.
Интересно, вы уже получили ответ от сопровождающего?
да! Я только что отредактировал ответ, указав, что сопровождающий это исправил! вперед за наукой! Спасибо @jay.sf
Подтверждено с игрой 1.22-3 R 4.4.1 на Linux.