Building R Packages and Class Definitions / class defs are not found - r

I am building an R package and have several files containing only class definitions (R6Classes, but I'm sure this applies to any kind). On building the package, I get an error due to some definitions not being found - e.g. the files are not loaded in the necessary order:
Error in R6Class("MyChildClass", inherit = DataSource,
public = list(initialize = function(...) {
(from MyChildClass.R#1) :
object 'DataSource' not found
Calls: <Anonymous> ... source_many -> source_one
-> eval -> eval -> R6Class
Execution halted
Exited with status 1.
I know about the Collate: field in DESCRIPTION, but there I have to write down every single .R file in the package. This is very cumbersome as the project grows in size...
Two other options occur to me:
Either put the starting-function in a file at the lexical end of the line (Z_Evaluate.R)
or wrap all class definition file (<FileName>) contents inside their own load function (LoadClassDefinitionsFrom<FileName>()) and call them at the beginning of the startup function in correct order.
Both don't really seem very convenient to me. If I'm not mistaken, the Latex compiler goes through the source twice in order to get everything right. That's probably not doable within R.
What's the best practise to deal with such a problem?

Related

Need to have the source created with Rmarkdown otherwise error message

Hello StackOverflow community,
I have been trying over the last few weeks using R Markdown to Knit HTML file.
While it use to run smoothly the previous time, over the last week I keep on getting the following error
Quitting from lines 43-92 (Vizualisation.Rmd)
Error in eval(lhs, parent, parent) :
object 'processed.feedback' not found
Calls: <Anonymous> ... withCallingHandlers -> withVisible -> eval -> eval -> %>% -> eval -> eval
Execution halted
The thing is that my source 'processed.feedback' is loaded within my Global environment. But is not created with the .rmd but before in a script file.
If I do the wrangling as well in the same Rmarkdown the it works fine (no error). But I would love to keep the wrangling part in a separate file.
Any suggestion.
Thanks in advance for your feedback and help!
If you are at the Rstudio conference - enjoy!
The usual model is that R Markdown files do not see objects that are in your workspace: they start with a blank workspace, so that anyone can reproduce the computation. (There are ways to work in an existing workspace, but you shouldn't use them.)
If it takes too long to create an object in the Rmd code, then there are at least two options: turn on caching (so it only happens when necessary), or save the object in a separate file using save() and load it in your document using load(). Remember to distribute the save file along with the .Rmd file if you want to give this document to someone else.

Where to define generics in an R package

I want to write a package using S4 objects and need to register new generic functions. I want to split my code into several files - each class gets its own .R file. However their methods share of course common generic functions. Where do I need to call setGeneric() such that I can use setMethod() in any .R file of the package? Currently I get an error of the type
Error in setMethod("XXX", signature(yyy = "YYY"), definition = function(yyy, :
no existing definition for function 'XXX'
Organize your code however you see fit (e.g., an AllGenerics.R file, or a XXX-methods.R file that starts with the generic). Use the 'Collate:' field in the DESCRIPTION file to ensure that the generics are available before methods defined.

Changing the load order of files in an R package

I'm writing a package for R in which the exported functions are decorated by a higher-order function that adds error checking and some other boilerplate code.
However, because this code is at the top-level it is evaluated after parsing. These means that
the load order of the package files is important.
To give an equivalent but simplified example, suppose I have a package with two files (Negate2 and Utils), and I require Negate2.R to be loaded first for the function 'isfalse( )' to be defined without throwing an error.
# /Negate2.R
Negate2 <- Negate
# -------------------
# /Utils.R
istrue <- isTRUE
isfalse <- Negate2(istrue)
Is it possible to structure NAMESPACE, DESCRIPTION (collate) or another package file in order to change the load order of files? The internal working of the R package structure and CRAN are still black magic to me.
It is possible to get around this problem using awkward hacks, but the least repetitive way of solving this problem. The wrapper function must be a higher-order function, since it also changes the function call semantics of its input function. The package is code heavy (~6000 lines, 100 functions) so repetition would be...problematic.
Solution
As #Manetheran points out, to change the load order you just change the order of the file names in the DESCRIPTION file.
# /DESCRIPTION
Collate:
'Negate2.R'
'Utils.R'
The Collate: field of the DESCRIPTION file allows you to change the order files are loaded when the package is built.
I stumbled across the answer to this question yesterday while reading up on Roxygen. If you've been documenting your functions with Roxygen, it can try to intelligently order your R source files in the Collate: field (based on where S4 class and method definitions are). This can be done by adding "collate" to the roclets argument of roxygenize. Alternatively if you're developing in RStudio there is a simple box that can be checked under Build->Configure Build Tools->Configure... (Button next to "Generate documentation with Roxygen").
R loads files in alphabetical order. To change the order, Collate field could be used from the DESCRIPTION file.
roxygen2 provides an explicit way of saying that one file must be loaded before another: #include. The #include tag gives a space separated list of file names that should be loaded before the current file:
#' #include class-a.r
setClass("B", contains = "A")
If any #include tags are present in the package, roxygen2 will set the Collate field in the DESCRIPTION.
You need to run generation of roxygen2 documentation in order to changes to take effect.

Dynamically Generate Reference Classes

I'm attempting to generate reference classes within an R package on the fly, and it's proving to be fairly difficult. Here are the approaches I've taken and problems I've run into:
I'm creating a package in which I hope to be able to dynamically read in a schema and automatically generate an associated reference class (think SOAP). Of course, this means I won't be able to define my reference classes before-hand in the package sources.
I initially attempted to create a new class using a simple:
myClass <- setRefClass("NewClassName", fields=list(fieldA="character"))
which, of course, works fine when executed interactively, but when included in the package sources, I get a locked binding error. From my reading, it looks like this occurs because when running interactively, the class information is being stored in the global environment, which is not locked, while my package's base environment is locked.
I then found a thread that suggested using something to the effect of:
myClass <- setRefClass("NewClassName", fields=list(fieldA="character"), where=globalenv())
This actually crashed R/Studio when I tried to build the package, so I don't have a log of the error it generated, unfortunately, but it certainly didn't work.
Next I tried creating a new environment within my package which I could use to store these reference classes. So I added a .classEnv <- new.env() line in my package sources (not inside of any function) and then attempted to use this class when creating a new reference class:
myClass <- setRefClass("NewClassName", fields=list(fieldA="character"), where=.classEnv)
This actually seemed to work OK, but generates the following warning:
> myClass <- setRefClass("NewClassName", where=.classEnv)
Warning message:
In getPackageName(where) :
Created a package name, ‘2013-04-23 10:19:14’, when none found
So, for some reason, methods::getPackageName() isn't able to pick up which package my new environment is in?
Is there a way to create my new environment differently so that getPackageName() can properly recognize the package? Can I add some feature which allows me to help getPackageName() detect the package? Will this even work if I can deal with the warning, or am I misusing reference classes by trying to create them dynamically?
To get the conversation going, I found that getpackageName stores the package name in a hidden .packageName variable in the specified environment.
So you can actually get around the warning with
assign(".packageName", "MyPkg", envir=.classEnv)
myClass <- setRefClass("NewClassName", fields=classFields, where=.classEnv)
which resolves the warning, but the documentation says not to trust the .packageName variable indefinitely, and I still feel like I'm hacking this in and may be misunderstanding something important about reference classes and their relationship to environments.
Full details from documentation:
Package names are normally installed during loading of the package, by the INSTALL script or by the library function. (Currently, the name is stored as the object .packageName but don't trust this for the future.)
Edit:
After reading a little further, the setPackageName method may be a more reliable way to set the package name for the environment. Per the docs:
setPackageName can be used to establish a package name in an environment that would otherwise not have one. This allows you to create classes and/or methods in an arbitrary environment, but it is usually preferable to create packages by the standard R programming tools (package.skeleton, etc.)
So it looks like one valid solution would be the following:
setPackageName("MyPkg", .classEnv)
myClass <- setRefClass("NewClassName", fields=classFields, where=.classEnv)
That eliminates the warning message and doesn't rely on anything that's documented as unstable. I'm still not clear why it's necessary, but...

More info on Rcpp exception

When writing R extensions using Rcpp is it possible to get more information when an exception is thrown?
For instance by default when an index is out of bound I get:
Error in myfunction(V) :
index out of bounds
Calls: source ... eval -> myfunction -> .Call -> cpp_exception
Execution halted
at this point I have no idea where in the code it might have happened. When compiling the code with debug information is it possible to print the stack? Can the Rcpp exception do that?
On a segfault I guess I can try to use deathhandler, but I am also looking for a solution for regular exceptions.
That one is most likely not from your code / Rcpp code.
If you use Rcpp for exception, you coontrol the and recover the message at the R level (provided you derive from std::exception etc). There a number of example out there as e.g. this SO post.
But to catch 'random' errors like this, you may need to resort to using the debugger.

Resources