Подавить предупреждения о выходе значения JAGS за пределы допустимого диапазона в R

Я использую большое количество моделей JAGS в R, используя функцию jags пакета R2jags (который использует пакет rjags для запуска JAGS).

Я получаю много предупреждений в консоли:

value out of range in 'lgamma'

Печать этих предупреждений сильно сокращает время вычислений. Как мне это подавить?

Предупреждения печатаются как выходные, а не как предупреждение R.

Вещи, которые я пробовал, но которые не работают, включают:

  • Оборачиваю свой звонок в try(..., silent = TRUE), suppressWarnings, invisible или capture.output.

  • Изменение вызова jags.model в jags на jags.model(..., quiet = TRUE).

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

Какие-либо предложения?


Вот длинный, но воспроизводимый пример, основанный на примере той же проблемы на sourceforge. Приносим извинения за длину, но я не смог воспроизвести это в каких-либо меньших игрушечных моделях. Мне наплевать на эту конкретную модель, но она просто разумно воспроизводит проблему:

Модель

cat('
model {
    K <- 1.1

    K.mvhypgeom <- exp( logfact(sum(n[])) - logfact(nMissing) - logfact( sum(n[]) - nMissing))

    p ~ dunif(0,1)

    for (t in 1:N) {
    X.missing[t] ~ dpois( missRate )
    }     

    nMissing ~ dsum(X.missing[1],X.missing[2],X.missing[3],X.missing[4],X.missing[5],X.missing[6],X.missing[7],X.missing[8],X.missing[9],X.missing[10])

    for (t in 1:N) {
    pX.missing[t] <- exp(logfact(n[t]) - logfact( X.missing[t]) - logfact( n[t] - X.missing[t]))
    ones2[t] ~ dbern(pX.missing[t]/K.mvhypgeom)
    }

    for (t in 1:N) {
    X[t] <- X.obs[t] + X.missing[t]

    likX[t] <- dbin( X[t], p, n[t])
    ones1[t] ~ dbern( likX[t] / K)    
    }
    }
  ',
    file = {example.model <- tempfile()},
    sep = ''
)

Данные

simBinTS <- function(n, p , nMissing) {
  X.full <- X <- rbinom(N, size = n, prob = p)
  for (i in seq_len(nMissing)) {
    idx <- sample(1:N, size = 1, prob = X)
    X[idx] <- X[idx] - 1
  }
  return(data.frame(n = n, X = X, X.full = X.full))
}


N <- 10
p <- 0.3
set.seed(123)
n <- rpois(N, lambda = 30)
nMissing <- 10
missRate <- 1/10
ts <- simBinTS(p = p, n = n, nMissing = nMissing)
X.obs <- ts$X
n <- ts$n
X.full <- ts$X.full
ones1 <- rep(1,N)
ones2 <- rep(1,N)

jags.inits <- function(){
  list(X.missing = X.full-X.obs)
}

Позвонить

library("R2jags")

jags(data = list("X.obs", "n", "N", "nMissing", "ones1", "ones2", "missRate"),
     inits = jags.inits,
     parameters.to.save = "p",
     model.file = example.model,
     n.chains = 3,
     n.iter = 1000,
     n.burnin = 500,
     n.thin = 1,
     progress.bar = "none")

Вывод (обрезано большое количество повторов предупреждения - опять же, они печатаются как выходные данные функции, а не как предупреждающие сообщения)

value out of range in 'lgamma'
value out of range in 'lgamma'
value out of range in 'lgamma'
value out of range in 'lgamma'
value out of range in 'lgamma'
value out of range in 'lgamma'
Inference for Bugs model at "D:\Users\fish\AppData\Local\Temp\RtmpWufTIC\file1614244456e1", fit using jags,
 3 chains, each with 1000 iterations (first 500 discarded)
 n.sims = 1500 iterations saved
         mu.vect sd.vect    2.5%     25%     50%     75%   97.5%  Rhat
p          0.331   0.027   0.280   0.312   0.330   0.348   0.388 1.006
deviance 812.379   2.761 808.165 810.345 811.941 814.103 818.729 1.007
         n.eff
p         1300
deviance   670

For each parameter, n.eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor (at convergence, Rhat=1).

DIC info (using the rule, pD = var(deviance)/2)
pD = 3.8 and DIC = 816.2
DIC is an estimate of expected predictive error (lower deviance is better).

person QuishSwash    schedule 01.06.2018    source источник
comment
У вас есть пример кода, которым вы могли бы поделиться вместе с выводом на консоль?   -  person Technophobe01    schedule 08.06.2018
comment
Сделали это выше.   -  person QuishSwash    schedule 08.06.2018


Ответы (1)


Проблема связана с пакетом jags, который R2Jags полагается.

  • jags использует printf, а не fprintf для отображения предупреждений. Jags не отправляет предупреждение на stderr, он отправляет предупреждение на консоль, а не на stderr. Следовательно, консоль R не может фильтровать предупреждения.

R2Jags полагается на зазубрины приложения. Я скачал исходный код jags с Sourceforge для JAGS-4.3.0, скомпилировал и установил библиотеку. Это позволило мне проследить код и определить, что jags выдает предупреждение через:

  • src/jrmath/lgamma.c:74 через ML_ERROR(ME_RANGE, "lgamma");

это разрешается до

  • src/jrmath/nmath.h:138 через MATHLIB_WARNING(msg, s);

который решает

  • src/jrmath/nmath.h:81
  • #define MATHLIB_WARNING(fmt,x) printf(fmt,x)

проблема здесь в том, что printf используется, а не fprint(stderr,...), это можно исправить следующим образом:


Быстрое решение:

Если вы хотите быстро решить проблему, вы можете загрузить исходный код и применить следующее исправление:

$ diff nmath.h.orig nmath.h
81c81
< #define MATHLIB_WARNING(fmt,x)        printf(fmt,x)
---
> #define MATHLIB_WARNING(fmt,x)        fprintf(stderr,fmt,x)

теперь вы можете скомпилировать и установить библиотеку jags:

>./configure
>sudo make uninstall && sudo make install 

сделав это, мы можем удалить библиотеку R2jags, переустановить ее и репрессировать stderr, используя R CMD с перенаправлением stderr ...

R CMD ./50635735.R 2> /dev/null

Пример кода

#!/usr/bin/env Rscript

library("R2jags")

source("./model.R") # Source Model
source("./simbits.R") # Source simBinTS code...

jags.data <- list("X.obs", "n", "N", "nMissing", "ones1", "ones2", "missRate")

model <- jags(data = jags.data,
              inits = jags.inits,
              parameters.to.save = "p",
              model.file = example.model,
              n.chains = 3,
              n.iter = 1000,
              n.burnin = 500,
              n.thin = 1,
              progress.bar = "none")

model

Консольный вывод:

Неизмененные зазубрины

$ R CMD ./50635735.R 2> /dev/null
1 checking for pkg-config... /usr/local/bin/pkg-config
2 configure: Setting compile and link flags according to pkg-config
3 configure: Compile flags are -I/usr/local/include/JAGS
4 configure: Link flags are -L/usr/local/lib -ljags
5 checking for gcc... ccache clang
6 checking whether we are using the GNU C compiler... no
7 checking whether ccache clang accepts -g... no
8 checking for ccache clang option to accept ISO C89... unsupported
9 checking for jags_version in -ljags... yes
10 checking version of JAGS library... OK
11 configure: creating ./config.status
12 config.status: creating src/Makevars
13 configure: creating ./config.status
14 config.status: creating src/Makevars
15 config.status: creating R/unix/zzz.R
16 ccache clang++ -I"/usr/local/Cellar/r/3.5.0_1/lib/R/include" -DNDEBUG -I/usr/local/include/JAGS   -I/usr/local/opt/gettext/include -I/usr/
17 ccache clang++ -I"/usr/local/Cellar/r/3.5.0_1/lib/R/include" -DNDEBUG -I/usr/local/include/JAGS   -I/usr/local/opt/gettext/include -I/usr/
18 ccache clang++ -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/usr/loc
19 Compiling model graph
20    Resolving undeclared variables
21    Allocating nodes
22 Graph information:
23    Observed stochastic nodes: 21
24    Unobserved stochastic nodes: 11
25    Total graph size: 174
26
27 Initializing model
28
29 value out of range in 'lgamma'
30 value out of range in 'lgamma'
31 value out of range in 'lgamma'
32 value out of range in 'lgamma'
...
...
...
10089 value out of range in 'lgamma'
10090 Inference for Bugs model at "/var/folders/md/03gdc4c14z18kbqwpfh4jdfc0000gp/T//Rtmp3P3FrI/file868156b0697", fit using jags,
10091  3 chains, each with 1000 iterations (first 500 discarded)
10092  n.sims = 1500 iterations saved
10093          mu.vect sd.vect    2.5%     25%     50%     75%   97.5%  Rhat n.eff
10094 p          0.333   0.027   0.281   0.315   0.332   0.350   0.391 1.003   590
10095 deviance 812.168   2.720 808.036 810.199 811.778 813.737 818.236 1.036    66
10096
10097 For each parameter, n.eff is a crude measure of effective sample size,
10098 and Rhat is the potential scale reduction factor (at convergence, Rhat=1).
10099
10100 DIC info (using the rule, pD = var(deviance)/2)
10101 pD = 3.6 and DIC = 815.8
10102
10103
10104
10105
10106
10107
10108
10109 BDIC is an estimate of expected predictive error (lower deviance is better).

Модифицированный фреймворк Jags

$ R CMD ./50635735.R 2> /dev/null
checking for pkg-config... /usr/local/bin/pkg-config
configure: Setting compile and link flags according to pkg-config
configure: Compile flags are -I/usr/local/include/JAGS
configure: Link flags are -L/usr/local/lib -ljags
checking for gcc... ccache clang
checking whether we are using the GNU C compiler... no
checking whether ccache clang accepts -g... no
checking for ccache clang option to accept ISO C89... unsupported
checking for jags_version in -ljags... yes
checking version of JAGS library... OK
configure: creating ./config.status
config.status: creating src/Makevars
configure: creating ./config.status
config.status: creating src/Makevars
config.status: creating R/unix/zzz.R
ccache clang++ -I"/usr/local/Cellar/r/3.5.0_1/lib/R/include" -DNDEBUG -I/usr/local/include/JAGS   -I/usr/local/opt/gettext/include -I/usr/local/opt/readline/include -I/usr/local/include   -fPIC  -g -O2  -c jags.cc -o jags.o
ccache clang++ -I"/usr/local/Cellar/r/3.5.0_1/lib/R/include" -DNDEBUG -I/usr/local/include/JAGS   -I/usr/local/opt/gettext/include -I/usr/local/opt/readline/include -I/usr/local/include   -fPIC  -g -O2  -c parallel.cc -o parallel.o
ccache clang++ -dynamiclib -Wl,-headerpad_max_install_names -undefined dynamic_lookup -single_module -multiply_defined suppress -L/usr/local/opt/gettext/lib -L/usr/local/opt/readline/lib -L/usr/local/lib -L/usr/local/Cellar/r/3.5.0_1/lib/R/lib -L/usr/local/opt/gettext/lib -L/usr/local/opt/readline/lib -L/usr/local/lib -o rjags.so jags.o parallel.o -L/usr/local/lib -ljags -L/usr/local/opt/icu4c/lib -L/usr/local/lib -L/usr/local/Cellar/r/3.5.0_1/lib/R/lib -lR -lintl -Wl,-framework -Wl,CoreFoundation
Compiling model graph
   Resolving undeclared variables
   Allocating nodes
Graph information:
   Observed stochastic nodes: 21
   Unobserved stochastic nodes: 11
   Total graph size: 174

Initializing model

Inference for Bugs model at "/var/folders/md/03gdc4c14z18kbqwpfh4jdfc0000gp/T//RtmpI80TnH/file8e70516d6f34", fit using jags,
 3 chains, each with 1000 iterations (first 500 discarded)
 n.sims = 1500 iterations saved
         mu.vect sd.vect    2.5%     25%     50%     75%   97.5%  Rhat n.eff
p          0.333   0.027   0.281   0.315   0.332   0.350   0.391 1.003   590
deviance 812.168   2.720 808.036 810.199 811.778 813.737 818.236 1.036    66

For each parameter, n.eff is a crude measure of effective sample size,
and Rhat is the potential scale reduction factor (at convergence, Rhat=1).

DIC info (using the rule, pD = var(deviance)/2)
pD = 3.6 and DIC = 815.8
DIC is an estimate of expected predictive error (lower deviance is better).

Долгосрочное решение

Сообщите об ошибке и предложите исправление через SourceForge.

person Technophobe01    schedule 08.06.2018
comment
Большое спасибо за это. Он работает для подавления других предупреждений, но не в этом конкретном случае, потому что предупреждение, похоже, имеет форму вывода, а не предупреждения R. Например. если вы создаете произвольный объект, например. sdf <- 1 и включите его в список данных в вызове jags в приведенном выше примере кода (data = list(..., "sdf)), он выдаст предупреждающее сообщение о неиспользуемой переменной. options(warn = 0) подавит предупреждение о неиспользуемой переменной, но не все value out of range in 'lgamma' распечатывает перед выходом модели. - person QuishSwash; 08.06.2018
comment
@Mob Я обновил ответ, чтобы отразить решение, которое я принял для решения проблемы с jags. - person Technophobe01; 09.06.2018
comment
@mob В его нынешнем виде R CMD работает, я разбираюсь с настройкой пакетов rjags и R2jags, пытаясь найти, где подавить stderr. Цель состоит в том, чтобы позволить вам сделать это через RStudio. - person Technophobe01; 09.06.2018
comment
Намного больше и выше служебного долга! - person QuishSwash; 12.06.2018
comment
@mob Не беспокойтесь - рад помочь. - person Technophobe01; 12.06.2018