Is there a way to use my own package's data (internal or external) as a default S4 class slot?
If I create some package data:
my_pkg_data <- sample(100)
usethis::use_data(my_pkg_data, internal=FALSE)
I can make functions taking the data as a default parameter:
#' Title
#'
#' @param x foo
#'
#' @return nout
#' @export
#'
foo <- function(x = test::my_pkg_data) {
print(x)
}
#run
foo()
[1] 407 184 13 994 933 322 214 784 502 396 903 ....
However, if creating S4 classes I get an error running devtools::check():
#' Title
#'
#' @slot some_slot ...
#' @return a s4class object
#' @export
#'
s4class <- setClass(
Class = "s4class",
slots = list(
some_slot = "ANY"
),
prototype = list(
some_slot = test::my_pkg_data
)
)
devtools::check()
* installing *source* package ‘test’ ...
** using staged installation
** R
** data
*** moving datasets to lazyload DB
** byte-compile and prepare package for lazy loading
Error : 'my_pkg_data' is not an exported object from 'namespace:test'
Error: unable to load R code in package ‘test’
Execution halted
ERROR: lazy loading failed for package ‘test’
* removing ‘/private/var/folders/62/n2yrhw752hn73nlbzp0r0_rr0000gq/T/RtmpvHbEA2/file36f3594c2270/test.Rcheck/test’
1 error ✖ | 0 warnings ✔ | 0 notes ✔
DESCRIPTION:
Package: test
Title: What the Package Does (One Line, Title Case)
Version: 0.0.0.9000
Authors@R:
person("First", "Last", , "first.last@example.com", role = c("aut", "cre"),
comment = c(ORCID = "YOUR-ORCID-ID"))
Description: What the package does (one paragraph).
License: MIT + file LICENSE
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
Depends:
R (>= 2.10)
LazyData: true
NAMESPACE:
# Generated by roxygen2: do not edit by hand
export(foo)
export(s4class)
exportClasses(s4class)
data.R file:
#' @title my data
#' @name my_pkg_data
"my_pkg_data"
Is this possible? Do I have to do this in an S4 initialise function instead? What's the reason behind this?
for example this works:
setMethod(
f = "initialize",
signature = "s4class",
definition = function(.Object, some_slot=test::my_pkg_data) {
.Object@some_slot <- some_slot
validObject(.Object)
return(.Object)
}
)
Thanks,
setClass
is called at install time and almost always evaluates its prototype
argument, hence the error. You'd encounter a similar error at install time if under the definition of foo
you tried to evaluate a call such as foo()
.
In your situation, I would simply define a method for initialize
:
> tools::assertError(Matrix::USCounties) # an error, as not lazy-loaded
> setClass("zzz", slots = c(x = "ANY"))
> setMethod("initialize", "zzz",
+ function(.Object, ...) {
+ .Object <- callNextMethod(.Object, ...)
+ if (all(...names() != "x")) {
+ data(USCounties, package = "Matrix", envir = environment())
+ .Object@x <- USCounties
+ }
+ .Object
+ })
> z1 <- new("zzz")
> data(USCounties, package = "Matrix")
> stopifnot(identical(z1, new("zzz", x = USCounties)))