User-defined distribution in R package and R CMD check NOTE

29 views
Skip to first unread message

Miguel Ángel Beltrán Sánchez

unread,
Jul 10, 2026, 6:39:07 AM (3 days ago) Jul 10
to nimble-users
Dear NIMBLE users,

I am developing an R package that includes a custom NIMBLE distribution. The package defines two nimbleFunctions, dcar_leroux() and rcar_leroux(), for a Leroux CAR distribution.

In order for NIMBLE to find these functions when processing the model code, I currently have an internal helper function with the following lines:

assign("dcar_leroux", dcar_leroux, envir = globalenv())
assign("rcar_leroux", rcar_leroux, envir = globalenv())

This seems to be necessary so that both the density function and the corresponding random generation function are recognised by NIMBLE inside the model.

However, R CMD check gives me the following NOTE:

checking R code for possible problems ... NOTE
  Found the following assignments to the global environment:
  File ‘pNimble/R/load_leroux.R’:
    assign("dcar_leroux", dcar_leroux, envir = globalenv())
    assign("rcar_leroux", rcar_leroux, envir = globalenv())

0 errors ✔ | 0 warnings ✔ | 1 note ✖

Is there a recommended way to make user-defined NIMBLE distributions available inside model code from an R package without assigning them to the global environment?

In particular, I would like to know whether there is a better approach that avoids this R CMD check NOTE while still allowing NIMBLE to recognise both dcar_leroux() and rcar_leroux() when building the model.

Thank you very much for your help.

PierGianLuca

unread,
Jul 10, 2026, 7:54:04 AM (3 days ago) Jul 10
to Miguel Ángel Beltrán Sánchez, nimble...@googlegroups.com
Hi Miguel,

[I'm not an expert about these matters, so users with better knowledge may correct the thoughts that follow.]

A lot depends on how you're using Nimble, as well as those two functions, in your package.

– If you define those functions as "internal" (not exported) in your package, then Nimble should be able to see them *if it's called within any other function in your package*. I'm not 100% sure about this though.

– If those functions are exported (visible to the user), then Nimble should be able to see them.

– Depending on how you use Nimble, one possibility is to spawn an extra, non-interactive R process, for instance by means of parallel::parLapply(), and use Nimble there. If you define those two functions within such environment, Nimble should be able to see them. These functions will not be visible to the user, who interacts only with the main R process.

Cheers,
Luca

Chris Paciorek

unread,
Jul 10, 2026, 12:05:55 PM (3 days ago) Jul 10
to Miguel Ángel Beltrán Sánchez, PierGianLuca, nimble...@googlegroups.com
hi Miguel,

In the nimbleEcology package, there are various custom NIMBLE distributions, so I think that package is probably a good example for your package. So as a starting point, please look at the DESCRIPTION and NAMESPACE files for nimbleEcology and see if that helps you figure out what you need for your package. As Luca said, if you export those functions of yours, they should be found when R looks for them within the processing in `nimbleModel()`. If that doesn't work, please follow up here and we can discuss it more.

-chris

--
You received this message because you are subscribed to the Google Groups "nimble-users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to nimble-users...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/nimble-users/99460f7a-59f4-42f4-85d1-01cd88319ba8%40magnaspesmeretrix.org.

Miguel Ángel Beltrán Sánchez

unread,
Jul 11, 2026, 11:14:01 AM (2 days ago) Jul 11
to nimble-users
Dear Luca and Chris,

Thank you very much for your replies.

Following your suggestions, I tried to avoid assigning the NIMBLE distribution functions to the global environment. The solution that worked in my case was to register the distribution and, when running chains in parallel, explicitly export the two NIMBLE distribution functions to each worker. So my internal helper function now registers the distribution with NIMBLE, without using assign(..., envir = globalenv()):

registerDistributions(list(
  dcar_leroux = list(
    BUGSdist = "dcar_leroux(rho, sd, Lambda, from.to, zero_mean)",
    types = c(
      "value = double(1)",
      "rho = double(0)",
      "sd = double(0)",
      "Lambda = double(1)",
      "from.to = double(2)",
      "zero_mean = double(0)"
    ),
    pqAvail = FALSE
  )
))

Then, in the parallel version of my function, after creating the cluster and loading nimble in each worker, I added:

parallel::clusterExport(my.cluster,
                        varlist = c("dcar_leroux", "rcar_leroux"),
                        envir = environment(dcar_leroux))

This makes dcar_leroux() and rcar_leroux() available inside each worker, so NIMBLE can find them when processing the model code in parallel. This seems to solve the problem without assigning the functions to the user's global environment, and the R CMD check NOTE caused by those global assignments disappears.

Thanks again for pointing me in the right direction.

Best regards,
Miguel Ángel
Reply all
Reply to author
Forward
0 new messages