强制不发生 R 会话在 RStudio 中中止

Force do not occur R Session Aborted in RStudio

提问人:Leprechault 提问时间:11/4/2023 最后编辑:Leprechault 更新时间:11/4/2023 访问量:63

问:

我想为多个 GLMM 模型创建一个循环,但我知道某些因素无法拟合。我创建了一些参数来避免错误,例如 、 和最小点限制 ()。 尽管有所有这些步骤,我总是有,但我找不到任何方法可以忽略不太适合的因素。skip_to_next <- FALSEtryCatchif(length(unique(NEW_DS_F_pred_sub$DATE))>=4)R Session Aborted

在我的例子中:

library("glmmTMB")
library("dplyr")
library("ggeffects")
library("ggplot2")

NEW_DS_F_pred <- NULL
STAND <- c(rep("A",5),rep("B",3),rep("C",6),rep("D",4))
stands <- unique(STAND)
DATE <- c("2022-01-01","2022-02-12","2022-03-01","2022-04-05","2022-06-01",
"2022-01-01","2022-02-12","2022-03-01",
"2022-01-01","2022-02-12","2022-03-01","2022-04-05","2022-06-01","2022-06-20",
"2022-01-01","2022-02-12","2022-03-01","2022-04-05")
B2_MAX <- runif(n=length(DATE))
B3_MAX <- runif(n=length(DATE))
B4_MAX <- runif(n=length(DATE))
NEW_DS_F_pred <- cbind(STAND,DATE,B2_MAX,B3_MAX,B4_MAX) %>% as.data.frame()

for (i in 1:length(stands)){
        skip_to_next <- FALSE
        tryCatch(print(stands[i]), error = function(e) { skip_to_next <<- TRUE})

NEW_DS_F_pred_sub <- NEW_DS_F_pred%>%filter(STAND==stands[i])

if(length(unique(NEW_DS_F_pred_sub$DATE))>=4){

NEW_DS_F_pred_sub$DATE_TIME <- as.numeric(difftime(NEW_DS_F_pred_sub$DATE, as.Date("2022-06-30"), units = "days"))
NEW_DS_F_pred_sub$DATE_TIME <- as.numeric(NEW_DS_F_pred_sub$DATE_TIME)
NEW_DS_F_pred_sub$B2_MAX <- as.numeric(NEW_DS_F_pred_sub$B2_MAX)
NEW_DS_F_pred_sub$B3_MAX <- as.numeric(NEW_DS_F_pred_sub$B3_MAX)
NEW_DS_F_pred_sub$B4_MAX <- as.numeric(NEW_DS_F_pred_sub$B4_MAX)
NEW_DS_F_pred_sub<-as.data.frame(NEW_DS_F_pred_sub)

# Fit the model B2_MAX
glmm_fit_B2_MAX <- glmmTMB(B2_MAX ~ poly(DATE_TIME,3) + (1|DATE_TIME), data=NEW_DS_F_pred_sub, family=tweedie(link = "log"))
ggeffects::ggpredict(glmm_fit_B2_MAX, terms = "DATE_TIME [all]") %>% plot(add.data = TRUE) + 
  xlab('Time in days') +
  ylab('VI 1')

# Predict the values
glmm_fit_B2_MAX_new <- NULL
glmm_fit_B2_MAX_new$DATE_TIME <- seq(-180,1)
glmm_fit_B2_MAX_new$B2_MAX <- predict(
  glmm_fit_B2_MAX,
  newdata = glmm_fit_B2_MAX_new,
  type = c("response"))
glmm_fit_B2_MAX_new$STAND <- rep(stands[i], length(glmm_fit_B2_MAX_new$DATE_TIME)) 
glmm_fit_B2_MAX_new <- as.data.frame(glmm_fit_B2_MAX_new)
glmm_fit_B2_MAX_new <- glmm_fit_B2_MAX_new%>%dplyr::select(STAND,DATE_TIME,B2_MAX)

# Fit the model B3_MAX
glmm_fit_B3_MAX <- glmmTMB(B3_MAX ~ poly(DATE_TIME,3) + (1|DATE_TIME), data=NEW_DS_F_pred_sub, family=tweedie(link = "log"))

# Predict the values
glmm_fit_B3_MAX_new <- NULL
glmm_fit_B3_MAX_new$DATE_TIME <- seq(-180,1)
glmm_fit_B3_MAX_new$B3_MAX <- predict(
  glmm_fit_B3_MAX,
  newdata = glmm_fit_B3_MAX_new,
  type = c("response"))
glmm_fit_B3_MAX_new$STAND <- rep(stands[i], length(glmm_fit_B3_MAX_new$DATE_TIME)) 
glmm_fit_B3_MAX_new <- as.data.frame(glmm_fit_B3_MAX_new)

# Fit the model B4_MAX
glmm_fit_B4_MAX <- glmmTMB(B4_MAX ~ poly(DATE_TIME,3) + (1|DATE_TIME), data=NEW_DS_F_pred_sub, family=tweedie(link = "log"))

# Predict the values
glmm_fit_B4_MAX_new <- NULL
glmm_fit_B4_MAX_new$DATE_TIME <- seq(-180,1)
glmm_fit_B4_MAX_new$B4_MAX <- predict(
  glmm_fit_B4_MAX,
  newdata = glmm_fit_B4_MAX_new,
  type = c("response"))
glmm_fit_B4_MAX_new$STAND <- rep(stands[i], length(glmm_fit_B4_MAX_new$DATE_TIME)) 
glmm_fit_B4_MAX_new <- as.data.frame(glmm_fit_B4_MAX_new)

if(skip_to_next) { next }     
}
}
#
#

boomRstudio

有没有办法在不中止 R 会话的情况下强制循环连续?

提前致谢!

R 循环 RSdiodio glmmTMB

评论

1赞 Ben Bolker 11/4/2023
我无法复制这个问题。我收到很多警告,但 R 没有崩溃。我不明白为什么它会有所不同,但是您可以尝试在 RStudio 之外的命令行上运行它吗?
0赞 Leprechault 11/4/2023
对不起,教授@BenBolker现在我更正了代码。如果没有崩溃,请偶尔重复。比。
1赞 Ben Bolker 11/4/2023
同样,当我运行此代码(即您编辑后的新版本)时,它不会停止。(我不确定“如果没有崩溃,请有时重复”是什么意思......
0赞 Leprechault 11/4/2023
“请有时重复”表示导致随机值,有时循环崩溃,有时不崩溃。我在两台不同的机器上发现了相同的结果,无论是 w11 还是 R4.1.3。runif
0赞 Phil 11/4/2023
在 R Studio 外部运行脚本时,是否可以重现崩溃?

答:

2赞 Ben Bolker 11/4/2023 #1

如果可以通过以下方式安装最新的 TMB 开发版本

remotes::install_github("kaskr/adcomp/TMB")

(需要安装开发工具),这将应用错误修复并阻止 R 崩溃。


我用你的代码做了一个函数,形式如下:

do <- function(seed=NULL) {
    if (!is.null(seed)) {   
          cat("seed ", seed, "\n")
          set.seed(seed)
    }
    ## ... all of your code
}

然后跑了

for (i in 1:200) { 
   do(i+100)
}

在它终止了我的 R 会话i==11

在抛出 'std::length_error' 实例后调用 terminate;what(): 无法创建大于 max_size() 的 std::vector 进程 R 于 2023 年 11 月 3 日星期五 20:17:28 中止(核心转储)

现在我可以运行并让它立即崩溃。do(111)

现在,我可以/将单步执行代码和/或运行该函数,以查看此随机数种子的数据的哪些方面使问题爆炸。debug()


通过(和)后,我找到了崩溃发生的地方(在第四步(D展台),在第一个模型B2上)。我用过debug()

saveRDS(NEW_DS_F_pred_sub, file = "SO77422084_bad.rds")

保存“坏”数据框(我试过了,但似乎不起作用......dput()

现在,这个最小的代码将使 R 崩溃:

library(glmmTMB)
NEW_DS_F_pred_sub <- readRDS("SO77422084_bad.rds")
## trim data set to make it even more minimal
bad <- NEW_DS_F_pred_sub[c("DATE_TIME", "B2_MAX")]
glmm_fit_B2_MAX <- glmmTMB(B2_MAX ~ poly(DATE_TIME,3) + 
                                   (1|DATE_TIME), data=bad,
                               family=tweedie(link = "log"))

将使 R 崩溃。

一个包含更多代码的最小示例,但它从头开始运行(即不需要我们运行一堆代码并将结果保存到外部文件):

set.seed(111)
dd <- data.frame( STAND = rep(LETTERS[1:4], c(5,3,6,4)),
   DATE = c("2022-01-01","2022-02-12","2022-03-01","2022-04-05",
    "2022-06-01","2022-01-01","2022-02-12","2022-03-01",
    "2022-01-01","2022-02-12","2022-03-01","2022-04-05",
    "2022-06-01","2022-06-20","2022-01-01","2022-02-12",
                              "2022-03-01","2022-04-05"))
    dd$B2_MAX <- runif(n=nrow(dd))
    dd_sub <- subset(dd, STAND == "D")
    dd_sub$DATE_TIME <-as.numeric(difftime(dd_sub$DATE, as.Date("2022-06-30"), units = "days"))
glmmTMB(B2_MAX ~ poly(DATE_TIME,3) + 
                (1|DATE_TIME), data=dd_sub,
            family=tweedie(link = "log"))

奇怪的是,继续运行并重新定义该值:dput()badbad

bad <- structure(list(DATE_TIME = c(-179.791666666667, -137.791666666667, 
                 -120.791666666667, -85.8333333333333),
         B2_MAX = c(0.156202515820041, 0.446427763439715, 
    0.171443687053397, 0.9665342932567)),
                     row.names = c(NA, -4L), class = "data.frame")

不会使 R 崩溃 — 以二进制格式存储的数据集与创建 ASCII 表示时发生的情况之间一定存在一些非常微妙的差异......

然后我做了,并逐步完成了.当 R 尝试运行优化时,崩溃发生,此时在代码中debug(glmmTMB)glmmTMB

进一步调试,进入,我发现崩溃发生在这里:nlminb

.Call(C_port_nlminb, obj, grad, hess, rho, low, upp, d = rep_len(as.double(scale), 
    length(par)), iv, v)

值得一提的是,如果我使用

control=glmmTMBControl(optimizer=optim, optArgs=list(method="BFGS"))

所以一定不是优化器的错,而是优化过程中遇到的一些参数组触发了崩溃。

接下来我要做的(不是今晚!)是找出一种适当的方法来跟踪优化器正在尝试的参数,这样我们就可以找出导致崩溃的确切参数(并希望修复看起来像glmmTMB)

有关此错误的更多大惊小怪,请参阅此处

评论

0赞 Leprechault 11/5/2023
惊人的解释,@BenBolker!!!教授现在,我采用了一种基于模型参数的新方法。谢谢!!
0赞 Leprechault 11/5/2023
嗨,教授@BenBolker我发现了一种姑息性解决方案,可以避免减少很多崩溃的值,非常丑陋,但直到现在仍然有效。badcontrol = glmmTMBControl(optimizer=nlminb, optCtrl = list(iter.max=9, eval.max=9))
1赞 Ben Bolker 11/5/2023
但是,如果我理解正确,这意味着您通常会在优化器到达解决方案之前很久就停止它。你能应用我建议的错误修复吗,这能解决问题吗?
0赞 Leprechault 11/6/2023
嗨,@BenBolker教授感谢您在 中的解决方案和代码实现。现在我正在使用我们建议的解决方案。glmmTMB