Warnings when run inside mutate, not when run separately

I must be missing something. I want to fit a particular distribution to subsets of my data. When I do it within a mutate() call, I end up with warnings about NaN produced, but if I run it outside of mutate() I see no such warning.

The output is the same, and I can't see where the NaN values are supposed to be.

library(tidyverse)
# fake data
dat <- tibble(grp = rep(c("A","B"), each = 100),
              vals = c(rnbinom(100, size = 1, prob = .5),
                       rnbinom(100, size = 10, prob = .2)))

# run within `mutate()`
fit1 <- dat |>
  group_by(grp) |>
  nest() |>
  mutate(model = map(data, ~ fitdistrplus::fitdist(data = .x[["vals"]],
                                                   distr = "nbinom"))) |>
  select(-data)
#> Warning: There were 4 warnings in `mutate()`.
#> The first warning was:
#> ℹ In argument: `model = map(data, ~fitdistrplus::fitdist(data = .x[["vals"]],
#>   distr = "nbinom"))`.
#> ℹ In group 1: `grp = "A"`.
#> Caused by warning in `dnbinom()`:
#> ! NaNs produced
#> ℹ Run `dplyr::last_dplyr_warnings()` to see the 3 remaining warnings.

# run outside of `mutate()`
nested <- dat |>
  group_by(grp) |>
  nest()
fit2 <- map(nested$data,
            ~ fitdistrplus::fitdist(data = .x[["vals"]], distr = "nbinom"))

all.equal(fit1$model, fit2)
#> [1] TRUE

Created on 2023-03-30 with reprex v2.0.2

Part of my question is whether I should be worried about those warnings, but I'm also just curious why running the same command within mutate() or not would change anything.

When looking inside the code of fitdistrplus::fitdist(), more specifically within the called function fitdistrplus:::testdpqfun(), there is this:

  op <- options()
  options(warn = -1)
  res <- some stuff
  options(op)
  res

So it looks like mutate() is ignoring the warn = -1 option. From the man page ?options:

If warn is negative all warnings are ignored. If warn is zero (the default) warnings are stored until the top–level function returns.

That means I can make this reprex:

f <- function(x){
  op <- options()
  options(warn = -1)
  message("The option is currently: ", options("warn"))
  warning("Oops")
  options(op)
  1
}

f(3)
#> The option is currently: -1
#> [1] 1

dplyr::mutate(data.frame(y = 0),
              x = f(3))
#> The option is currently: -1
#> Warning: There was 1 warning in `dplyr::mutate()`.
#> ℹ In argument: `x = f(3)`.
#> Caused by warning in `f()`:
#> ! Oops
#>   y x
#> 1 0 1

Created on 2023-03-30 with reprex v2.0.2

So it looks like mutate() is ignoring just the option and surfacing the warning anyway. This might be linked with issue #5512, although the situation is a bit different.

1 Like

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.