R package data not available when importing in ano

2019-05-11 05:06发布

问题:

I have one package "testing" with a data object "test_data" saved in data folder under file name "test_data.RData".

testing contains one function hello() that uses this data object

#' hello
#'
#' @return Prints hello "your_name"
#' @export
#'
#' @examples
#' hello()
hello <- function(your_name = "") {

    print(paste("test_data has", nrow(test_data), "rows"))
    print(sprintf("Hello %s!", your_name))
}

the following code works fine:

require(testing)
testing::hello()
[1] "test_data has 32 rows"
[1] "Hello !"

but this fails:

testing::hello()
Error in nrow(test_data) : object 'test_data' not found

Actually I do not use it directly but in another package testingtop that imports this function:

#' Title
#'
#' @export
#' @importFrom testing hello
hello2 <- function(){

    hello()
}

I have testing in the Imports section of DESCRIPTION and this fails.

require(testingtop)
testingtop::hello2()
Error in nrow(test_data) : object 'test_data' not found

If I put it in Depends it works if I load the package with library() otherwise it still fails:

> library(testingtop)
Loading required package: testing
> testingtop::hello2()
[1] "test_data has 32 rows"
[1] "Hello !"

Restarting R session...

> testingtop::hello2()
Error in nrow(test_data) : object 'test_data' not found

if it was a function instead of a data object Imports would be fine, why is it different with a data object and I need to load the imported package? Did I miss something? And is it related to LazyData and LazyLoad ?

Probably a duplicate of this question

回答1:

SO I think I've found the solution from the doc of the data function ?data

Use of data within a function without an envir argument has the almost always undesirable side-effect of putting an object in the user's workspace (and indeed, of replacing any object of that name already there). It would almost always be better to put the object in the current evaluation environment by data(..., envir = environment()). However, two alternatives are usually preferable, both described in the ‘Writing R Extensions’ manual. For sets of data, set up a package to use lazy-loading of data. For objects which are system data, for example lookup tables used in calculations within the function, use a file ‘R/sysdata.rda’ in the package sources or create the objects by R code at package installation time. A sometimes important distinction is that the second approach places objects in the namespace but the first does not. So if it is important that the function sees mytable as an object from the package, it is system data and the second approach should be used.

Putting the data in the internal data file made my function hello2() see it

> testingtop::hello2()
[1] "test_data has 32 rows"
[1] "Hello !"