Exporting a Data Set (package development) - r

I have a package (qdap) and an accompanying data only package (qdapDictionaries) that will be used by some of the functions in qdap as seen here in line 41 I use the syn.env from line 454 here.
I have already asked a related question on the R-help list but was told off list it was not appropriate for the list as it uses private notation from roxygen2, however, I could actually export the data sets from qdapDictionaries. I tried simply adding #export to the .R file that describes the data sets but this results in an error when compiling.
> set(qdapDictionaries)
Installing qdapDictionaries
"C:/R/R-3.0.1/bin/i386/R" --vanilla CMD INSTALL \
"C:\Users\trinker\GitHub\qdapDictionaries" --library="C:/R/R-3.0.1/library" \
--with-keep.source --install-tests
* installing *source* package 'qdapDictionaries' ...
** R
** data
*** moving datasets to lazyload DB
** inst
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
*** arch - i386
Error in namespaceExport(ns, exports) :
undefined exports: abbreviations, action.verbs, adverb, amplification.words, BuckleySaltonSWL, contractions, deamplification.words, DICTIONARY, emoticon, env.pol, env.syl, env.syn, interjections, labMT, NAMES, NAMES_LIST, NAMES_SEX, negation.words, negative.words, OnixTxtRetToolkitSWL1, positive.words, preposition, SYNONYM, Top100Words, Top200Words, Top25Words
Error: loading failed
Execution halted
*** arch - x64
Error in namespaceExport(ns, exports) :
undefined exports: abbreviations, action.verbs, adverb, amplification.words, BuckleySaltonSWL, contractions, deamplification.words, DICTIONARY, emoticon, env.pol, env.syl, env.syn, interjections, labMT, NAMES, NAMES_LIST, NAMES_SEX, negation.words, negative.words, OnixTxtRetToolkitSWL1, positive.words, preposition, SYNONYM, Top100Words, Top200Words, Top25Words
Error: loading failed
Execution halted
ERROR: loading failed for 'i386', 'x64'
* removing 'C:/R/R-3.0.1/library/qdapDictionaries'
* restoring previous 'C:/R/R-3.0.1/library/qdapDictionaries'
Error: Command failed (1)
Clearly I am not exporting these data sets correctly. How can I export the data sets from qdapDictionaries so that I can then use #importFrom in the parent qdap package?
Here is what one of the documentations for the data sets looks like:
#' Fry's 100 Most Commonly Used English Words
#'
#' A stopword list containing a character vector of stopwords.
#'
#' #details Fry's Word List: The first 25 make up about one-third of all printed
#' material in English. The first 100 make up about one-half of all printed
#' material in English. The first 300 make up about 65\% of all printed
#' material in English."
#'
#'
#' #docType data
#' #keywords datasets
#' #name Top100Words
#' #usage data(Top100Words)
#' #format A character vector with 100 elements
#' #export
#' #references Fry, E. B. (1997). Fry 1000 instant words. Lincolnwood, IL:
#' Contemporary Books.
NULL
Note that I have the qdapDictionaries listed in the Depends section of the DESCRIPTION file but with R dev version a CRAN check reveals I need to still import the datasets from qdapDictionaries that are used within the parent qdap package.

Related

What's the preferred means for defining an S3 method in an R package without introducing a dependency?

I have an R package (not currently on CRAN) which defines a couple of S3 methods of generic functions from other packages (specifically knitr::knit_print and huxtable::as_huxtable). However, they're not a key part of my package, so I'd prefer not to create a dependency on those packages when a user installs my package. Up until R 4.0.0, I exported the S3 methods without importing the generics. Using roxygen2, my #export directive was translated into an export() directive in NAMESPACE rather than S3method(). This worked fine in R versions < 4.0.0 because R looks in the global environment for a matching generic_function.class method first rather than relying on proper registration of the S3 method. However, as per this blog on developer.r-project.org, R no longer looks for non-registered S3 methods.
What is the best way round this? For now, I've added #importFrom directives to my roxygen2 blocks and have added both packages to the imports section of DESCRIPTION. However, as I understand things this will mean any user installing my package will then also have to install knitr and huxtable whether they want to or not.
Fortunately, for R >= 3.6.0, you don't even need the answer by caldwellst. From the blog entry you linked above:
Since R 3.6.0, S3method() directives in NAMESPACE can also be used to perform delayed S3 method registration. With S3method(PKG::GEN, CLS, FUN) function FUN will get registered as an S3 method for class CLS and generic GEN from package PKG only when the namespace of PKG is loaded. This can be employed to deal with situations where the method is not “immediately” needed, and having to pre-load the namespace of pkg (and all its strong dependencies) in order to perform immediate registration is considered too “costly”.
Additionally, this is also discussed in the docs for the other suggestion of vctrs::s3_register():
#' For R 3.5.0 and later, `s3_register()` is also useful when demonstrating
#' class creation in a vignette, since method lookup no longer always involves
#' the lexical scope. For R 3.6.0 and later, you can achieve a similar effect
#' by using "delayed method registration", i.e. placing the following in your
#' `NAMESPACE` file:
#'
#' ```
#' if (getRversion() >= "3.6.0") {
#' S3method(package::generic, class)
#' }
So, you would simply need to not use #importFrom and instead of #export, use #exportS3Method package::generic (See https://github.com/r-lib/roxygen2/issues/796 and https://github.com/r-lib/roxygen2/commit/843432ddc05bc2dabc9b5b22c1ae7de507a00508)
Illustration
So, to illustrate, we can make two very simple packages, foo and bar. The package foo just has a generic foo() function and default method:
library(devtools)
create_package("foo")
#' foo generic
#'
#' #param x An object
#' #param ... Arguments passed to or from other methods
#' #export
foo <- function(x, ...) {
UseMethod("foo", x)
}
#' foo default method
#'
#' #param x An object
#' #param ... Arguments passed to or from other methods
#' #export
foo.default <- function(x, ...) {
print("Called default method for foo.")
}
After document() and install()ing, we create bar:
create_package("bar")
which creates a bar method for foo():
#' bar method for foo
#'
#' #param x A bar object
#' #param ... Arguments passed to or from other methods
#'
#' #exportS3Method foo::foo
foo.bar <- function(x, ...) {
print("Called bar method for foo.")
}
Importantly, we must load the foo package before running document(), or #exportS3Method won't work. That is,
library(foo)
document()
But, if we do that, we get the following in the NAMESPACE for bar:
# Generated by roxygen2: do not edit by hand
S3method(foo::foo,bar)
We have to manually add foo to "Suggests" in DESCRIPTION.
Then if we uninstall foo, we can still install bar:
> remove.packages("foo")
Removing package from ‘/home/duckmayr/R/x86_64-pc-linux-gnu-library/4.0’
(as ‘lib’ is unspecified)
> install("bar")
✓ checking for file ‘/home/jb/bar/DESCRIPTION’ ...
─ preparing ‘bar’:
✓ checking DESCRIPTION meta-information ...
─ checking for LF line-endings in source and make files and shell scripts
─ checking for empty or unneeded directories
─ building ‘bar_0.0.0.9000.tar.gz’
Running /opt/R/4.0.0/lib/R/bin/R CMD INSTALL \
/tmp/Rtmp5Xgwqf/bar_0.0.0.9000.tar.gz --install-tests
* installing to library ‘/home/jb/R/x86_64-pc-linux-gnu-library/4.0’
* installing *source* package ‘bar’ ...
** using staged installation
** R
** byte-compile and prepare package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded from temporary location
** testing if installed package can be loaded from final location
** testing if installed package keeps a record of temporary installation path
* DONE (bar)
The vctrs package provides a function called s3_register that dynamically registers methods for use in the .onLoad function. You can read more about its use here, for yourself you would want:
.onLoad <- function(...) {
if (requireNamespace("knitr", quietly = TRUE)) {
vctrs::s3_register("knitr::knit_print", "class_name")
}
if (requireNamespace("huxtable", quietly = TRUE)) {
vctrs::s3_register("huxtable::as_huxtable", "class_name")
}
}
The documentation is kind as well so you don't have to import vctrs:
To avoid taking a dependency on vctrs for this one function, please feel free to copy and paste the function source into your own package.

Using data.table in package - fail on check

I want to use data.tables as a backbone in a package that I wrote.
As I don't want to used :: all the time (and avoid the complications with [ and := operators), I include data.table as a Depends and not as an Import in DESCRIPTION to be able to use all dt functions directly.
If I build the package everything works fine but running a "check" results in the error (from DTTest.Rcheck/00install.out):
* installing *source* package ‘DTTest’ ...
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
Error : package ‘data.table’ required by ‘DTTest’ could not be found
Error: loading failed
Execution halted
ERROR: loading failed
The only function in this package is this
#' Creates a data.table
#'
#' #return a data.table
#' #export
#'
#' #examples
#' create_dt()
create_dt <- function() {
dt <- data.table(x = 1:10)
dt[, x_2 := x^2]
return(dt[])
}
And DESCRIPTION contains Depends: data.table, otherwise the files are the standard RStudio new package-files.
You can find the whole package here: https://github.com/DavZim/DTTest
Any ideas how to fix this?
After some helpful comments from Roland, I found the solution to my problem. It was indeed related to my .libPaths() and not with the code.
When checking the package R tried to search for the packages inside the first library in .libPaths(). As it happens, I have four paths (/usr/local/..., /usr/lib/R/site-library, /usr/lib/R/library, and /home/user/R/x86_64-pc-linux-gnu-library/3.4) and data.table is installed inside the last one.
The solution (more like a workaround at this stage) was to install data.table in the first one.
To do this, I executed R with admin privileges (sudo R in my case) and installed data.table with install.packages("data.table", lib = .libPaths()[1]).
Now the check pass as expected!

Does R's package support unicode rd file?

My platform is:
Win7 64
Rtudio
R3.1.3
devtools 1.8.0
Rxygen2 4.1.1
I am trying to make a package of my own. I need to describe the function by unicode. I used Roxygen2 to generate the Rd file. The code is very simple(I removed the real function just know how to make a package):
xxxx means comment made by unicode.
#' eastChoice
#' #param fn.kind wind xxxxxx
#' #param estChoice.Path wind
#' #return data.frame
#' #export
#' #examples
#' getIndByEastChoice("20150108.csv")
getIndByEastChoice <- function(fn.kind){
d <- data.frame(a=c(1,2,3), b=c(4,5,6))
dt <- data.table::data.table(d)
}
When I check(devtools) the R code, it always failed. The following error information is given:
* checking PDF version of manual ... WARNING
LaTeX errors when creating PDF version.
This typically indicates Rd problems.
LaTeX errors found:
! Package inputenc Error: Unicode char \u8:��<87> not set up for use with LaTeX.
See the inputenc package documentation for explanation.
Type H <return> for immediate help.
At first I thought that the Roxygen2 does not support unicode other than ASCII, but I read the Rd file generated by Roxygen2, it is OK.
And then I just use build&Reload function(using devtools), to my suprise, it passed.
And then I add more unicode comment in the R file and checked(devtools) it again. It is like the following:
#' eastChoice xxxxxx
#' #param fn.kind wind xxxxx
#' #param estChoice.Path wind xxxxxxxx
#' #return data.frame xxxxxxx
#' #export
#' #examples
#' getIndByEastChoice("20150108.csv")
getIndByEastChoice <- function(fn.kind){
d <- data.frame(a=c(1,2,3), b=c(4,5,6))
dt <- data.table::data.table(d)
}
It failed as I expected, but other information was given and seems more serious:
* checking whether package 'ftools.temp' can be installed ... ERROR
Installation failed.
See 'D:/onedrive/program/R.package/ftools.temp.Rcheck/00install.out' for details.
So I checked the log:
* installing *source* package 'ftools.temp' ...
** R
** preparing package for lazy loading
** help
*** installing help indices
wrong in gsub("&", "&", x, fixed = TRUE) : '<86>'multi byte string is wrong
* removing 'D:/onedrive/program/R.package/ftools.temp.Rcheck/ftools.temp'
And this time build&load also failed.
So I think that maybe the R does not support unicode other ASCII in its RD file? Can any one confirm it? If it is true, I will not waste my time trying to solve this problem.
#hrbrmstr
Thank you. I have tried your advice. First, I added the line "Encoding:UTF-8" in the decription file, and then saved .R and DESCRIPTION with coding UTF-8 to ensure that the encode is correct. And I run the "check " function, but I got the same error:
strsplit(txt, "\n", fixed = TRUE)���о���: �������ַ���1����UTF-8
* checking examples ... OK
* checking PDF version of manual ... WARNING
LaTeX errors when creating PDF version.
This typically indicates Rd problems.
����: ��������'"D:/R/R-31~1.3/bin/x64/Rcmd.exe" Rd2pdf --batch --no-preview --build-dir="C:/Users/kanpu/AppData/Local/Temp/RtmpgFjyKw/Rd2pdf15f2c22b7768d" --no-clean -o ftools.temp-manual.pdf "D:/onedrive/program/R.package/ftools.temp.Rcheck/ftools.temp"'��״̬��1
LaTeX errors found:
! Package inputenc Error: Unicode char \u8:��<97> not set up for use with LaTeX.
The DESCRIPTION is like this:
Package: ftools.temp
Type: Package
Title: Just try to make a package
Version: 0.1
Date: 2015-08-25
Author: None
Maintainer: no one <none#somewhere.net>
Description: Just try to make a package
License: CPL
LazyData: TRUE
Encoding:UTF-8
Depends:
data.table

Error use other library when I use Rstudio and Roxygen2 to build a package

To simplify the problem. I tried the following thing. My goal is to build a simple package which need another library.
I used RStudio and tried to create a new package, and checked the project option to "Generate document with Roxygen". And I get the following code:
#' Title just a test
#'
#' #return nothing
#' #export
#'
#' #examples
#' hello()
hello <- function() {
print("Hello, world!")
}
and I "check"ed it and "build and reload"ed it by the RStudio, all is OK.
Then I tried to add one line in the head of the code:
library("data.table")
#' Title just a test
#'
#' #return nothing
#' #export
#'
#' #examples
#' hello()
hello <- function() {
print("Hello, world!")
}
Then I failed amd get the following:
* checking whether package 'kanpu.temp' can be installed ... ERROR
Installation failed."
When I check the log, it says that:
* installing *source* package 'kanpu.temp' ...
** R
** preparing package for lazy loading
Error in library("data.table") : there is no package called 'data.table'
Error : unable to load R code in package 'kanpu.temp'
ERROR: lazy loading failed for package 'kanpu.temp'
* removing 'D:/onedrive/program/R/kanpu.temp.Rcheck/kanpu.temp'
I am sure that data.table is a existed package in my RStudio System. and also tried other package like "ggplot2", "plyr", and get the same result.
So how can I resolve this problem?
The envirement is:
Win7 64
RStudio 0.99.473
R 3.1.3 64
After checking the "Writing R Extensions", I know what's wrong with the code.
I should use "Import" or "Depends" in the "DESCRIPTION" file.
Looking at the error message, it seems that you do not have the ggplot2 package installed. This will cause an error when R reaches the line library(ggplot2).
The solution is to install that package:
install.packages("ggplot2")
However, you probably shouldn't be calling library in your packaged code. A package should make as few changes to the external environment as possible.
Instead, mark the package as required in your DESCRIPTION and make fully qualified function calls: SomePackage::someFunction().
See Hadley's pages for further information.

Roxygen2 - "argument is of length zero" error when documenting reference class

To demonstrate a minimal case, say I have the following package:
#' #docType package
#' #import methods
#' #title MyTitle
#' #description MyDescription
#' #details MyDetails
#' #export
A <- setRefClass("A")
When I roxygenize (in RStudio, before a 'Build & Reload'). I get:
==> roxygenize('.', roclets=c('rd', 'collate', 'namespace'))
* checking for changes ... ERROR
Error in process.docType(partitum) :
Roclet processing error in block Test1.R:7
argument is of length zero
What's going wrong? How do I resolve this error?
My setup:
Roxygen2 3.1.0
Using roxygen to generate (in RStudio):
Rd files
Collate field
NAMESPACE file
Automatically roxygenising when running (in RStudio):
R CMD check
Source and binary package builds
Build & Reload
R: 3.0.2 (Frisbee Sailing)
IDE: RStudio 0.98.490
OS: Windows 8.1
I had a similar situation where
#' #export
A <- setRefClass("A")
cause the same error, which I resolved using:
A <- setRefClass("A")
#' #export
A
Curiously, this was in a file that I had not modified in a while, so it's still a bit of a mystery...

Resources