2

I'm working with the package wpp2019 which has a lot of demographic datasets. I want to be able to use these datasets within some functions in my package. Unfortunately, these datasets cannot be referred to with get (or wpp2019::) but only through data.

Since the whole point of wpp2019 is to be a data package, I'm hesitant to save the data internally and refer to it locally. Although this question hints at what I want, the OP didn't have the problem of only being able to export the data through data.

I've been using data("name of data", package = "wpp2019) through out my code but devtools::check() screams through no visible binding for global variable 'name of data'.

Anyone know a workaround to this?

cimentadaj
  • 1,414
  • 10
  • 23
  • 1
    You can set global variables in your package using `globalVariables` as discussed here https://stackoverflow.com/questions/9439256/how-can-i-handle-r-cmd-check-no-visible-binding-for-global-variable-notes-when often contained in a separate file called globals.r – Greg Oct 12 '20 at 15:58
  • `no visible binding for global variable` usually refers to an issue with variables which are not defined. It happens with non-standard evaluation in packages a lot. In your case this shouldn't be an issue though. – JBGruber Oct 12 '20 at 16:39

1 Answers1

2

I'm not sure why you get this error. I created a small test package with only the function below and checks run without any issues:

#' Loads random dataset from wpp2019
#'
#' @export
#'
#' @importFrom utils data
load_random_data <- function() {
  # check if package is installed
  if (requireNamespace("wpp2019", quietly = TRUE)) {
    # get name of random dataset
    rand <- sample(data(package = "wpp2019")[["results"]][, 3], 1)
    x <- utils::data(list = rand, package = "wpp2019", envir = environment())
    return(get(x))
  } else {
    stop("Install package from https://github.com/PPgp/wpp2019 first.")
  }
}

I found the way in which data evaluates the name of the dataset a little confusing. So maybe the example functions helps to clear things up.

@user2554330 nudged me to write a more general function to load datasets from packages. So here it is with some extra bells and whistles:

#' Load dataset from from a package
#'
#' @param title character. Title of a dataset in the package
#' @param package character. Name of a package in which the dataset is present.
#'   
#' @export
#'
#' @importFrom utils data
load_data <- function(title, package = "wpp2019") {
  # check if package is installed
  if (requireNamespace(package, quietly = TRUE)) {
    # check if dataset is in the package
    if (title %in% data(package = package)[["results"]][, 3]) {
      return(get(utils::data(list = title,
                             package = package,
                             envir = environment())))
    } else {
      stop("Dataset '", title, "' not found in package ", package, ".")
    }
  } else {
    stop("Package '", package, "' not installed.")
  }
}

And a quick test if this works:

dat <- load_data("UNlocations")
ncol(dat)
#> 32

load_data("UNLocations")
#> Error in load_data("UNLocations"): Dataset 'UNLocations' not found in package wpp2019.

load_data("UNLocations", "not_installed")
#> Error in load_data("UNLocations", "not_installed"): Package 'not_installed' not installed.

As you can see, the functions fails with more comprehensible error messages.

JBGruber
  • 11,727
  • 1
  • 23
  • 45
  • That's a nice function. It would also be nice if it wasn't random, i.e. it took arguments similar to `data()`, but instead of loading the dataset, returns it as the function value. – user2554330 Oct 12 '20 at 16:58
  • Returning a random dataset was just for demonstration purposes. It wouldn't make sense as a function. I added one that returns a requested dataset as a `data.frame` directly. – JBGruber Oct 12 '20 at 21:32
  • 1
    Yes, I understood that it was just a demo. But it seems like a general purpose function would be useful to lots of people to answer the title of this question. – user2554330 Oct 12 '20 at 23:37
  • Thanks for the answer @JBGruber. Unfortunately, `load_named_data` gives an error. If I run `res <- load_named_data("UNLocations")` I get `Error in get(utils::data(list = title, package = "wpp2019", envir = environment())) : object 'UNLocations' not found`. – cimentadaj Oct 13 '20 at 06:39
  • I think there is a typo in there. Should be `res <- load_named_data("UNlocations")` – JBGruber Oct 13 '20 at 07:19
  • 1
    You are totally right! Thanks a lot for this, it works like a charm. – cimentadaj Oct 13 '20 at 07:45