I am working on a R package that uses an external 3rd party dll to load data. I have written wrapper functions to that external dll that I can call with .C()
Assume that my package is called mypackage and the external is called xternal.dll. It seems that to load the mypackage.dll that is generated during compilation it is necessary that external.dll is loaded first. I am using roxygen2 to manage the NAMESPACE file, and I have used the #' #useDynLib tags. Unfortunately when roxygen2 writes the NAMESPACE file it adds the useDynLib calls in the lexical order of the shared object being called like A-Z, a-z.
Is there a way to control the order of the useDynLib in the namespace by roxygen2?
So far I have found the follwing solutions and neither of them seems to be particularly compelling:
Renaming my package to be lexically ordered after the external dll.
Managing the NAMESPACE file manually.
Example:
The function foo.R:
#' #export
#' #useDynLib xternal
#' #useDynLib mypackage
foo <- function(){
return(FALSE)
}
results in the NAMESPACE after calling devtools::document():
# Generated by roxygen2: do not edit by hand
export(foo)
useDynLib(mypackage)
useDynLib(xternal)
The package would fail to load, however if I manually swap the two useDynLib lines the package installs and works fine.
After a very helpful hint received on GitHub:
The solution is to use the #rawNamespace tag, that writes a verbatim line into the NAMESPACE file:
foo.R:
#' #export
#' #rawNamespace useDynLib(xternal); useDynLib(mypackage)
foo <- function(){
return(FALSE)
}
results in a NAMESPACE file:
# Generated by roxygen2: do not edit by hand
export(foo)
useDynLib(xternal); useDynLib(mypackage)
and the shared objects are loaded in the correct order.
Related
When developing an R package, it is common for me to just turn on Packrat and use a localized repository, and develop as I explore in a session. But when publishing the package, it is a big headache to recall and manually add every dependency I have used in the developed package. Is there a (semi-)automatic way to do this?
For example, in NodeJS development, we can just use npm install --save and the dependency will be added automatically to package.json.
Yes, use roxygen2 to generate your NAMESPACE file.
Example way to generate package level documentation:
#' #details
#' \tabular{ll}{
#' Package: \tab \cr
#' Type: \tab Package\cr
#' Version: \tab 1.0.0\cr
#' Date: \tab 2016-05-15\cr
#' License: \tab MIT \cr
#' }
#' #useDynLib pkg
#' #importFrom Rcpp evalCpp
#' #importFrom methods is
#' #importFrom stats ts as.ts is.ts
#' #import ggplot2
"_PACKAGE"
Note: I tend to keep my import statements together in the package-level documentation. You can use these same statements within function documentation.
Use #importFrom <pkg> <function1> <function2> for specific imports.
Otherwise, use #import <pkg> for all functions in a given package.
Edit
To lock it to a specific version, you will need to modify your DESCRIPTION file's Imports: section like so:
Imports:
Rcpp (>= 0.12.5),
scales (<= 0.4.0),
grid (== 0.7-4),
stats
A common way to do this (although not one that's used much by "old school" R programmers, who as far as I know maintain their NAMESPACE files by hand ...) is to manually insert roxygen2 #importFrom statements in the code ... e.g.
# returns a true family() object iff one was given
## to glmmTMB() in the first place ....
##' #importFrom stats family
##' #export
family.glmmTMB <- function(object, ...) {
object$modelInfo$family
}
although it would certainly be helpful to have an automated system, to provide hints if nothing else. Certainly maintaining dependencies in this way (making sure to add #importFrom statements as needed for every function that has a dependency) is better than trying to keep track of when dependencies are (still) needed after developing the code.
#import and #importFrom (which translate to import and importFrom statements) are both legal, the R extensions guide says
Using importFrom selectively rather than import is good practice and recommended notably when importing from packages with more than a dozen exports.
("good practice" translates to "CRAN maintainers will yell if you don't" ...)
I don't know if there's a way to do versioned importFrom statements: R puts package version dependencies in the Imports: field in the DESCRIPTION file and importFrom statements in the NAMESPACE file: roxygen2 generates this information automatically, but I don't think the mapping from roxygen2 directives to NAMESPACE/DESCRIPTION information is fine-grained enough to support this ...
Running R CMD check --as-cran gives hints about functions from recommended packages that need to be imported.
I have an Rcpp based R package which when checked by devtool::check() produces following warning:
Error in .doLoadActions(where, attach) : error in load action .A.1 for package tarantoolr: (function (ns) : could not find function "loadModule"
What might be the cause of such behavior and what is the best way to fix this issue?
Full build and check log from travis-ci can be viewed here, warnings are located around lines 1212 and 1223.
Package itself is located at Github.
Try running your package using devtools::check(document = FALSE) as I think your NAMESPACE file is being overwritten and made "empty" as you do not use roxygen2 to create the necessary entries
e.g. You need to create a file called tarantoolr-package.R that contains:
#' #importFrom(Rcpp, evalCpp)
#' #useDynLib(tarantoolr)
#' #exportPattern("^[[:alpha:]]+")
#' #details
#' We all live in a yellow submarine..
"_PACKAGE"
Without this file, again, the NAMESPACE file is empty and, thus, the global export of all function via exportPattern("^[[:alpha:]]+") does not occur. Hence, there are no known functions within the environment.
I am making an R package in Rstudio and I selected the option Configure Build Tools > Configure and select Use roxygen to generate NAMESPACE. I wrote my functions in Rcpp and this is what the NAMESPACE looks like when I generate it with roxygen2:
# Generated by roxygen2 (4.1.1): do not edit by hand
export(function1)
export(function2)
export(function3)
export(function4)
Since my functions are written with Rcpp, which I then export, then they will used in R via .Call. However, from writing R extensions we should use useDynLib() in such a case. This is why I think I am getting an error when I try to call function1 and the error is:
Error in .Call("Mypackage_function1", PACKAGE = "Mypackage", var1, :
"Mypackage_function1" not available for .Call() for package "Mypackage"
When I use the default NAMESPACE when I start a project in Rstudio, I have the following in NAMESPACE:
useDynLib(packagename)
exportPattern("^[[:alpha:]]+")
importFrom(Rcpp, evalCpp)
When I use the default NAMESPACE I can call the functions using .Call however I get a warning when I check the package that I am not generating the NAMESPACE using roxygen.
Is there a fix for this? Any advice is appreciated.
This is unrelated to the usage of RStudio: For Roxygen to generate the relevant useDynLib specification, you need to use the #useDynLib tag in a Roxygen doc comment:
#' #useDynLib packagename
You can do this anywhere (where you can use normal Roxygen comments) but it makes sense to put this into the package documentation, rather than the documentation of a specific function. Usually this resides in a file called R/packagename-package.r:
#' My package documentation
#' … bla bla …
#' #name packagename
#' #docType package
#' #useDynLib packagename
NULL
I am trying to make a package but when I run document() it prints NAMESPACE not generated by roxygen2. Skipped. I am trying to use ggplot2,XML, R6 packages in my functions. I am importing them in the following way:
#' #rdname visualization
#' #param hist_data A table of weather variables with PWS created by hist_data function
#' #param variable A character string of variable name
#' #examples
#' table <- getWeather(city = "San Francisco", state="CA")
#' please <- getConditionsTable(table, "2015-03-09")
#' tab <- hist_data(table, please)
#' head(tab)
#' plot_variable_across_all_pws(hist_data=tab, variable="tempi")
#' #import ggplot2
#' #import XML
#' #import R6
I am wondering what might be causing this error and there is nothing in my Namespace except for exportPattern("^[^\\.]")
Also, I was going over R packages book by Hadley http://r-pkgs.had.co.nz/namespace.html
And confused by the line :
"Note that you can choose to use roxygen2 to generate just NAMESPACE, just man/*.Rd, or both. If you don’t use any namespace related tags, roxygen2 won’t touch NAMESPACE. If you don’t use any documentation related tags, roxygen2 won’t touch man/."
Is this what I'm doing wrong? or missing?
Backup NAMESPACE file, if you need it for future use
Delete the NAMESPACE file
Run devtools::document(), so that roxygen2 will generate new NAMESPACE file in the package source directory
*** make sure you have #export tag in the roxygen2 doc section of the R source file.
I think that devtools tries to avoid overwriting DESCRIPTION and NAMESPACE files that it didn't generate itself (to avoid angst if you have meticulously typed them in yourself, instead of using embedded roxygen comments in your r code). It isn't always possible but it tries.
The main mechanism, as I understand it, is to post a comment at the top of the file when it generates the file, and then later on, look for that comment (there are tricky bits round the edge, for example if you use #includes to create the Collate order in the DESCRIPTION file, but I don't think that is your problem here.)
An example of such a comment is
# Generated by roxygen2 (4.1.0.9001): do not edit by hand
The not generated by ... message is alerting you to this, and letting you know devtools is not going to use roxygen2 to make a NAMESPACE file for you. You possibly have the one you mention without the comment because you used RStudio to start your package, rather than devtools::create() ?
If you just delete the NAMESPACE file, I think devtools::document() would then work for you.
BTW You have a typo in the example code above (you have#' #import ggplo2 instead of #' #import ggplot2)
Thanks to #jsta's solution and I copied the following line # Generated by roxygen2: do not edit by hand at the top of the NAMESPACE file, and then with an empty line.
Then I ran devtools::document() in the console and it automatically replaced the existing NAMESPACE file.
I think that top line is just what roxygen will look for to see if that file is generated by roxygen.
None of the preceding examples worked for me. If I deleted the NAMESPACE file then roxygen complained there was no NAMESPACE. If I deleted and re-created a NAMESPACE file (with `touch, e.g. RStudio: Building package with roxygen2. Not producing NAMESPACE file) then roxygen complained that the file was not created with roxygen.
The solution was to copy a NAMESPACE file from another project that was created with roxygen.
Also one may simply delete everything from NAMESPACE and add leave one line: exportPattern("^[[:alpha:]]+")
If the file NAMESPACE is changed manually, devtools::document() fails to overwrite this file, that is why it leaves as before. When you delete the text from the NAMESPACE file and insert this line, devtools::document() thinks that the file is new and overwrites it.
Actual question
How do I avoid Rd file name conflicts when
a S4 generic and its method(s) are not necessarily all defined in the same package (package containing (some of) the custom method(s) depends on the package containing the generic) and
using roxygenize() from package roxygen2 to generate the actual Rd files?
I'm not sure if this is a roxygen2 problem or a common problem when the generic and its method(s) are scattered across packages (which IMHO in general definitely is a realistic use-case scenario if you follow a modular programming style).
What's the recommended way to handle these situations?
Illustration
In package pkga
Suppose in package pkga you defined a generic method foo and that you've provided the respective roxygen code that roxygenize() picks up to generate the Rd file:
#' Test function
#'
#' Test function.
#'
#' #param ... Further arguments.
#' #author Janko Thyson \email{janko.thyson##rappster.de}
#' #example inst/examples/foo.R
#' #docType methods
#' #rdname foo-methods
#' #export
setGeneric(
name="foo",
signature=c("x"),
def=function(
x,
...
) {
standardGeneric("xFoo")
}
)
When roxygenizing() your package, a file called foo-methods.Rd is created in the man subdirectory that serves as the reference Rd file for all methods that might be created for this generic method. So far so good. If all of the methods for this generic are also part of your package, everything's good. For example, this roxygen code would make sure that documentation is added to foo-methods.Rd for the ANY-method of foo:
#' #param x \code{ANY}.
#' #return \code{TRUE}.
#' #rdname foo-methods
#' #aliases foo,ANY-method
#' #export
setMethod(
f="foo",
signature=signature(x="ANY"),
definition=cmpfun(function(
x,
...
) {
return(TRUE)
}, options=list(suppressAll=TRUE))
)
However, if package pkga provides the generic for foo and you decide in some other package (say pkgb) to add a foo-method for x being of class character, then R CMD check will tell you that there is a name clash with respect to Rd file names and/or aliases (as there already exists a Rd file foo-methods.Rd in pkga):
In package pkgb
#' #param x \code{character}.
#' #return \code{character}.
#' #rdname foo-methods
#' #aliases foo,character-method
#' #export
setMethod(
f="foo",
signature=signature(x="character"),
definition=cmpfun(function(
x,
...
) {
return(x)
}, options=list(suppressAll=TRUE))
)
To be more precise, this is the error that's thrown/written to file 00install.out
Error : Q:/pkgb/man/foo-methods.Rd: Sections \title, and \name must exist and be unique in Rd files
ERROR: installing Rd objects failed for package 'pkgb'
Due dilligence
I tried to change the values for #rdname and #aliases to foo_pkgb* (instead of foo*), but \title and \name still are set to foo when roxygenizing and thus the error remains. Any ideas besides manually editing the Rd files generated by roxygenize()?
EDIT 2012-12-01
In light of starting the bounty, the actual question might get a slightly broader flavor:
How can we implement some sort of an "inter-package" check with respect to Rd files and/or how can we consolidate S4 method help files scattered across packages into one single Rd file in order to present a single source of reference to the end-user?
The basic question is indeed "roxygenize"-only.
That's why I never had seen the problem.
While there are good reasons for the roxygenizing approach of package development,
I still see a very good reason not to go there:
Plea for much less extreme roxygenation
The resulting help pages tend to look extremely boring, not only the auto generated *.Rd files but also the rendered result.
E.g.
examples are often minimal, do not contain comments, are often not well formatted (using space, / new lines /..)
Mathematical issues are rarely explained via \eqn{} or \deqn{}
\describe{ .. } and similar higher level formatting is rarely used
Why is that? Because
1) reading and editing roxygen comments is so much more
"cumbersome" or at least visually unrewarding
than reading and editing *.Rd files in ESS or Rstudio or (other IDE that has *.Rd support built in)
2) If you are used that documentation
is the thing that's automatically generated at the end of your package building/checking
you typically tend to not considerung well written R documentation as something important
(but rather your R code, to which all the docs is just a comment :-)
The result of all that: People prefer writing documentation about their functions in vignettes or even blogs, github gists, youtube videos, or ... where it is very nice at the time of authoring, but is
pretty much detached from the code and bound to get outdated and withering (and hence, via Google search misleading your useRs)
--> The original motivation of roxygen of having code and documentation in the same place is entirely defeated.
I like roxygen and use it extensively at the time I create a new function...
and I keep and maintain it as long as my function is not in a package, or is not exported.
Once I decide to export it,
I run (the ESS equivalent of) roxygenize() once
and from then on take the small extra burden of maintaining a *.Rd file that is well formatted, contains its own comments (for me as author), has many nice examples, has its own revision control (git / svn / ...) history, etc.
I managed to generate NAMESPACE and *.Rd files for S4 methods for generics defined in another package than mine.
It took me the following steps:
Create NAMESPACE by hand as a workaround to a known roxygen2 bug.
Writing a NAMESPACE by hand is not so difficult at all!
Switch off NAMESPACE generation by roxygen2 in RStudio:
Build > more > Configure build tools > configure roxygen > do not use roxygen2 to generate NAMESPACE.
import the package containing the generic and export the S4 methods using exportMethods.
Write separate roxygen2 documentation for each of the S4 methods. Do not combine roxygen2 documentation (as I generally do for different methods of the same generic).
Add explicit roxygen tags #title and #description to the roxygen documentation of the S4 methods. Write #description explicitly, even if its value is identical as #title.
That makes it work for me.