wahani / modules

Modules in R
https://cran.r-project.org/package=modules
Other
81 stars 3 forks source link

Importing datasets from packages #29

Closed wahani closed 3 years ago

wahani commented 3 years ago

Hi! I'm just seeing this thread now and while thinking about using modules::import() to replicate much of R's default attached package list (which is accessible, BTW, via options()$defaultPackages), I found this oddity: Let this be file mod.R:

modules::import("utils", attach = TRUE)
modules::import("datasets", attach = TRUE)
print(head(iris))

And in use():

modules::use("mod.R")

Gives this:

#> Error in head(iris) : object 'iris' not found

Changing the print statement to:

print(utils::head(datasets::iris))

... works. Perhaps I'm missing something about how attach = TRUE is supposed to work?

Originally posted by @mmuurr in https://github.com/wahani/modules/issues/13#issuecomment-716915769

wahani commented 3 years ago

I think your intuition is right. This is an issue on how we try to find the exported objects from a package. For that we utilize getNamespaceExports which usually lists all exported objects of a package. Some examples:

> getNamespaceExports("datasets")
character(0)
> ns <- getNamespace("datasets")
> str(ns)
<environment: namespace:datasets> 
  > ls("datasets")
Error in as.environment(pos) : 
  no item called "datasets" on the search list
> ls(envir = ns)
character(0)

which is surprising. Because the datasets must be exported somewhat differently. When you do not import the complete pkg, but iris explicitly, then your example works:

modules::module({
  modules::import("utils")
  modules::import("datasets", "iris")
  print(head(iris))
})
wahani commented 3 years ago

In addition to getNamespaceExports we apperently also have to call:

res <- data(package = "datasets")

and import all datasets. Seems I have missed completely that the import mechanism for data works complete different from everything else.

Thanks for bringing this up!

Note for fix:

# not trivial to get the names. maybe like this:
ds <- data(package = "datasets")
dsNames <- ds$results[, "Item"]
dsNames <- gsub(" .*", "", dsNames)
data(list = dsNames, package = "datasets")

# prints out warnings. as import the names may work however. Still confusing.
allDs <- lapply(dsNames, function(n) {
  expr <- paste0("datasets::", n)
  expr <- parse(text = expr)
  eval(expr)
})
wahani commented 3 years ago

@mmuurr should now be fixed.