Поведение предсказателя.gam выдает ошибку в R4, но работает в R3. полный репрекс включен

В версии 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")

Подтверждено с игрой 1.22-3 R 4.4.1 на Linux.

jay.sf 02.07.2024 08:47

если вы установите se.fit = FALSE, то это сработает. Кажется, проблема с se.fit? Кто-нибудь знает обходной путь?

we need a Mat. Stat. 03.07.2024 08:20
mgcv::gam у меня отлично работает. Возможно, стоит связаться с сопровождающим игры.
jay.sf 03.07.2024 09:41

Похоже, это потому, что predict.Gam вызывает predict.Gam прямо в операторе switch. Если он просто вызвал predict() с обновленными аргументами (чтобы сначала получить SE по шкале ссылок), то все работает.

Gavin Simpson 03.07.2024 11:22

@GavinSimpson Думаю, я не понимаю твой ответ. Знаете ли вы, как я могу явно вызвать предикат(), чтобы он работал?

we need a Mat. Stat. 03.07.2024 14:48

@jay.sf да, я также могу заставить работать mgcv::gam, но время стены намного выше, и для воспроизводимости я бы предпочел gam::gam. В моем рабочем коде я вызываю функцию gam() много раз итеративно, а затраты времени на mgcv::gam слишком велики по сравнению с gam::gam для моего вычислительного оборудования. Возможно, есть способ ускорить mgcv::gam. Пока mgcv::bam у меня не работает.

we need a Mat. Stat. 03.07.2024 14:52

@weeedaMat.Stat. что ж, если вы знаете, как редактировать код в пространстве имен (fixInNamespace()), вы можете найти оператор switch() и решить проблему. Вы также можете отправить Тревору электронное письмо с отчетом об ошибке и указать конкретную проблему. Вы не можете исправить это самостоятельно (кроме временного использования fixInNamespace()), но нужны ли вам стандартные ошибки, поскольку это работает с se.fit = FALSE

Gavin Simpson 03.07.2024 15:15

Действительно ли mgcv::gam() медленнее, чем gam::gam(), если вы установите fx = TRUE на каждом сглаживании (в версии mgcv), чтобы соответствовать сопоставимым моделям?

Gavin Simpson 03.07.2024 15:16

Я не знаю, как это правильно отформатировать: 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

we need a Mat. Stat. 03.07.2024 23:39

Это выглядит довольно странно. Почему бы вам не написать разработчику игры электронное письмо, вы можете дать ссылку на этот вопрос.

jay.sf 04.07.2024 02:47

fx = TRUE должен идти на каждом сглаживании, а не как аргумент для gam(). Вы можете просто отредактировать свой вопрос, а не пытаться форматировать вывод в комментарии.

Gavin Simpson 05.07.2024 07:42
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
11
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

обновлять Разработчик пакета устранил проблему, и новая версия 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, ...)
}

* Забыл добавить, я также написал письмо сопровождающему пакета игры.

we need a Mat. Stat. 05.07.2024 02:50

Интересно, вы уже получили ответ от сопровождающего?

jay.sf 17.07.2024 13:27

да! Я только что отредактировал ответ, указав, что сопровождающий это исправил! вперед за наукой! Спасибо @jay.sf

we need a Mat. Stat. 19.07.2024 03:20

Другие вопросы по теме