Search code examples
rdplyrr-sfterraroxygen

Examples failing during `devtools::check()`


Since this is not the first time I am experiencing issues with dplyr::filter() in combination with an sf object stored under /data/ when developing some little R package, I thought now might be the time to ask for some help. Last time there were issues with tests when executing devtools::check(), now there are issues with example execution. In both cases, tests and examples work fine without any problems when executed manually, so I'm pretty lost troubleshooting this at the moment.

The actual dataset holds about ~10k objects, so let me just head() |> dput() a snippet to provide a working example:

vg250_gem_bbox <- structure(list(GEN = c("Flensburg", "Kiel", "Lübeck", "Neumünster", 
"Brunsbüttel", "Heide"), geometry = structure(list(structure(list(
    structure(c(522975.97996175, 532592.93722135, 532592.93722135, 
    522975.97996175, 522975.97996175, 6067273.8071813, 6067273.8071813, 
    6075302.31489017, 6075302.31489017, 6067273.8071813), dim = c(5L, 
    2L))), class = c("XY", "POLYGON", "sfg")), structure(list(
    structure(c(567119.427353557, 579260.010241581, 579260.010241581, 
    567119.427353557, 567119.427353557, 6012042.07857579, 6012042.07857579, 
    6032320.76629453, 6032320.76629453, 6012042.07857579), dim = c(5L, 
    2L))), class = c("XY", "POLYGON", "sfg")), structure(list(
    structure(c(602333.177059654, 629300.017585839, 629300.017585839, 
    602333.177059654, 602333.177059654, 5958968.20793358, 5958968.20793358, 
    5984455.09177785, 5984455.09177785, 5958968.20793358), dim = c(5L, 
    2L))), class = c("XY", "POLYGON", "sfg")), structure(list(
    structure(c(560539.198262492, 569285.240089275, 569285.240089275, 
    560539.198262492, 560539.198262492, 5985883.77755599, 5985883.77755599, 
    6000652.74359173, 6000652.74359173, 5985883.77755599), dim = c(5L, 
    2L))), class = c("XY", "POLYGON", "sfg")), structure(list(
    structure(c(501147.356463151, 514098.898982973, 514098.898982973, 
    501147.356463151, 501147.356463151, 5970993.16041208, 5970993.16041208, 
    5978036.88939917, 5978036.88939917, 5970993.16041208), dim = c(5L, 
    2L))), class = c("XY", "POLYGON", "sfg")), structure(list(
    structure(c(503374.05476818, 513876.447792843, 513876.447792843, 
    503374.05476818, 503374.05476818, 6001455.96902488, 6001455.96902488, 
    6007835.67366924, 6007835.67366924, 6001455.96902488), dim = c(5L, 
    2L))), class = c("XY", "POLYGON", "sfg"))), class = c("sfc_POLYGON", 
"sfc"), precision = 0, bbox = structure(c(xmin = 501147.356463151, 
ymin = 5958968.20793358, xmax = 629300.017585839, ymax = 6075302.31489017
), class = "bbox"), crs = structure(list(input = "ETRS89 / UTM zone 32N", 
    wkt = "PROJCRS[\"ETRS89 / UTM zone 32N\",\n    BASEGEOGCRS[\"ETRS89\",\n        ENSEMBLE[\"European Terrestrial Reference System 1989 ensemble\",\n            MEMBER[\"European Terrestrial Reference Frame 1989\"],\n            MEMBER[\"European Terrestrial Reference Frame 1990\"],\n            MEMBER[\"European Terrestrial Reference Frame 1991\"],\n            MEMBER[\"European Terrestrial Reference Frame 1992\"],\n            MEMBER[\"European Terrestrial Reference Frame 1993\"],\n            MEMBER[\"European Terrestrial Reference Frame 1994\"],\n            MEMBER[\"European Terrestrial Reference Frame 1996\"],\n            MEMBER[\"European Terrestrial Reference Frame 1997\"],\n            MEMBER[\"European Terrestrial Reference Frame 2000\"],\n            MEMBER[\"European Terrestrial Reference Frame 2005\"],\n            MEMBER[\"European Terrestrial Reference Frame 2014\"],\n            ELLIPSOID[\"GRS 1980\",6378137,298.257222101,\n                LENGTHUNIT[\"metre\",1]],\n            ENSEMBLEACCURACY[0.1]],\n        PRIMEM[\"Greenwich\",0,\n            ANGLEUNIT[\"degree\",0.0174532925199433]],\n        ID[\"EPSG\",4258]],\n    CONVERSION[\"UTM zone 32N\",\n        METHOD[\"Transverse Mercator\",\n            ID[\"EPSG\",9807]],\n        PARAMETER[\"Latitude of natural origin\",0,\n            ANGLEUNIT[\"degree\",0.0174532925199433],\n            ID[\"EPSG\",8801]],\n        PARAMETER[\"Longitude of natural origin\",9,\n            ANGLEUNIT[\"degree\",0.0174532925199433],\n            ID[\"EPSG\",8802]],\n        PARAMETER[\"Scale factor at natural origin\",0.9996,\n            SCALEUNIT[\"unity\",1],\n            ID[\"EPSG\",8805]],\n        PARAMETER[\"False easting\",500000,\n            LENGTHUNIT[\"metre\",1],\n            ID[\"EPSG\",8806]],\n        PARAMETER[\"False northing\",0,\n            LENGTHUNIT[\"metre\",1],\n            ID[\"EPSG\",8807]]],\n    CS[Cartesian,2],\n        AXIS[\"(E)\",east,\n            ORDER[1],\n            LENGTHUNIT[\"metre\",1]],\n        AXIS[\"(N)\",north,\n            ORDER[2],\n            LENGTHUNIT[\"metre\",1]],\n    USAGE[\n        SCOPE[\"Engineering survey, topographic mapping.\"],\n        AREA[\"Europe between 6°E and 12°E: Austria; Belgium; Denmark - onshore and offshore; Germany - onshore and offshore; Norway including - onshore and offshore; Spain - offshore.\"],\n        BBOX[38.76,6,84.33,12]],\n    ID[\"EPSG\",25832]]"), class = "crs"), n_empty = 0L)), row.names = c(NA, 
-6L), sf_column = "geometry", agr = structure(c(GEN = NA_integer_), levels = c("constant", 
"aggregate", "identity"), class = "factor"), class = c("sf", 
"tbl_df", "tbl", "data.frame"))

I have this sf object stored under /data/ via usethis::use_data(vg250_gem_bbox) with LazyData: true in DESCRIPTION.

In order to quiet some concerns of R CMD check, I'm also making use of utils::globalVariables(c("vg250_gem_bbox", "GEN")).

The function of interest is pretty basic: The idea is to filter the dataset for a specific name and to return the bounding box of the object (of type SpatExtent from {terra}).

#' Title
#'
#' @param x character.
#'
#' @return SpatExtent.
#' @export
#'
#' @examples
#' get_bbox("Kiel")
get_bbox <- function(x = NULL) {

  e <- dplyr::filter(vg250_gem_bbox, GEN == x) |>
    terra::ext()

  e
}

Executing the example manually via console works without issues:

get_bbox("Kiel")
#> SpatExtent : 567119.427353557, 579260.010241581, 6012042.07857579, 6032320.76629453 (xmin, xmax, ymin, ymax)

Execution via devtools::check() returns the following error:

checking examples ... ERROR
  Running examples in 'klam21-Ex.R' failed
  The error most likely occurred in:
  
  > base::assign(".ptime", proc.time(), pos = "CheckExEnv")
  > ### Name: get_bbox
  > ### Title: Title
  > ### Aliases: get_bbox
  > 
  > ### ** Examples
  > 
  > get_bbox("Kiel")
  Error in (function (cond)  : 
    error in evaluating the argument 'x' in selecting a method for function 'ext': `x` must be a vector, not a <sfc_POLYGON/sfc> object.
  Calls: get_bbox ... abort -> signal_abort -> signalCondition -> <Anonymous>
  Execution halted

The error seems to suggest there might be some issues with terra::ext(<sfc_POLYGON/sfc>), if I get this correctly, but why does this work apart from devtools::check() then?

\dontrun{...} resolves this but I'd like not to exclude this example from being executed, if possible.

Thank you very much for your input in advance!


Solution

  • The problem is that method tables depend on the appropriate package being loaded. If I run your code with nothing preloaded, I get the same error as you saw. If I run library(sf) first, I don't. I don't actually need library(sf), it's enough to run requireNamespace("sf").

    So make sure your package loads sf. One way is to rewrite the function like this:

    get_bbox <- function(x = NULL) {
      if (!requireNamespace("sf"))
        stop("This function needs the sf package.")
      e <- dplyr::filter(vg250_gem_bbox, GEN == x) |>
        terra::ext()
    
      e
    }