Starting Situation:
I'm writing a small package of functions for myself only (not CRAN; on GitHub, but not public), and developing locally on the computer. Mostly this is me being a newbie at R and learning to write first package.
I'm using devtools and after load_all() and check(), I have been getting this "NOTE":
-- R CMD check results -------------------------------------------------------------------------------------------- MondelezR 0.1.0 ----
Duration: 21.1s
> checking dependencies in R code ... NOTE
Namespace in Imports field not imported from: 'tibble'
All declared Imports should be used.
0 errors v | 0 warnings v | 1 note x
Question:
Am I doing something wrong or is this a known/ expected problem that I can ignore?
Little more background:
I am using tibble()
In my package, "Find in Files" shows that I have used tibble in four files in different ways:
DESCRIPTION file:
[First Section of File Omitted]
Encoding: UTF-8
RoxygenNote: 7.2.0
Imports:
stringr,
dplyr,
purrr,
tibble,
magrittr
Suggests:
testthat (>= 3.0.0)
Config/testthat/edition: 3
(I have not seen the message for the other imported packages.)
FUNCTION: mdlz_otm_filter.R
[omitted]
#' #examples
#' df_otm_final <- tibble::tibble(
[omitted]
I am only using tibble in the example, not in the function itself, and the relevant portion is shown above.
DOCUMENTATION: mdlz_otm_filter.Rd
The roxygen2 documentation created from the above function shows the exact same example, but as documentation.
TEST THAT: test-mdlz_make_KEY1.R
test_that("POSTAL LANE2 works as expected", {
df_test <- tibble::tibble(ORIG_ZIP = c("18615", "12345", "a5J 1u8"),
DEST_ZIP = c("1234", "23456", "i9y2b4"),
FINAL_KEY = c("18615-01234","12345-23456","A5J1U8-I9Y2B4"))
expect_identical(mdlz_make_POSTAL_LANE(df_test$ORIG_ZIP,
df_test$DEST_ZIP),
df_test$FINAL_KEY)
})
Attempt to remove tibble from DESCRIPTION
I tried removing tibble from Imports: on the DESCRIPTION file, but as I expected would happen, I got this instead:
-- R CMD check results -------------------------------------------------------------------------------------------- MondelezR 0.1.0 ----
Duration: 26.6s
> checking for unstated dependencies in examples ... WARNING
'::' or ':::' import not declared from: 'tibble'
> checking for unstated dependencies in 'tests' ... WARNING
'::' or ':::' import not declared from: 'tibble'
0 errors v | 2 warnings x | 0 notes v
So... warnings are worse than notes I figure.
Research:
Google search to start with brought me to these posts:
RStudio Community Meta-Package This guy's problem is that he needs to use functions in every package he's trying to put in his meta-package. My issue is I'm already using tibble and getting the note regardless.
SO devtools R CMD check NOTE But this one doesn't seem to apply because I AM using tibble in my package, and this guy is trying to remove it.
Help?
I don't know how to clear the note, if I should worry about it at all, or why I'm getting it since I am using tibble as shown above. Trying to learn, so an expository answer is appreciated. Thank you in advance.
It seems devtools check function is looking for an importFrom tag with the package tibble in some of your function documentation roxygen Docs.
Adding #importFrom tibble tibble to the functions documentation which use the library tibble might remove the note.
Related
I am trying to push the following package to CRAN, but I keep getting an error on the check.
Error:
✓ checking R/sysdata.rda ...
WARNING
‘qpdf’ is needed for checks on size reduction of PDFs
✓ checking installed files from ‘inst/doc’ ...
✓ checking files in ‘vignettes’ ...
E checking examples (3s)
Running examples in ‘oRus-Ex.R’ failed
The error most likely occurred in:
> base::assign(".ptime", proc.time(), pos = "CheckExEnv")
> ### Name: analyseStories
> ### Title: Analysing Stories
> ### Aliases: analyseStories
>
> ### ** Examples
>
> # Transform the stories
> fileUrl <- example_stories()
> stories <- analyseStories(fileUrl, 7)
Joining, by = "word"
Joining, by = "word"
Error in loadNamespace(name) : there is no package called ‘reshape2’
Calls: analyseStories ... loadNamespace -> withRestarts -> withOneRestart -> doWithOneRestart
Execution halted
Current problems:
The example is in orus::analyseStores(...) function.
The example actually runs and works on the pkgdown website.
The error appears only when doing devtools::check
I have tried multiple things:
This answer base::assign(".ptime", proc.time(), pos = "CheckExEnv") ERROR when using devtools::check suggested using dontrun{...}. It passes CRAN's check, but it was bounced by a person after a couple of days.
This answer R package fails devtools::check, because "could not find function" even though the function is imported in NAMESPACE suggested doing require on the missing library. I did require(reshape2) but the check still does not pass.
This answer "Could not find function" in Roxygen examples during CMD check suggests that I need to make all my functions public (exported). I don't want to do that. I tried doing orus:::some_function(...) to call to the non-exported functions inside analyseStores but it doesn't work either.
According to this one: R package build failed when checking examples the data is working and the function has the #export tag. Also, namespace is properly updated.
I have run out of options. Any idea of what is happening?
As #stefan suggested in the comments, I had to add reshape2 into the Suggested packages in the description file. I added using:
usethis::usepackage("reshape2", "Suggests")
Followed by regenerating the docs:
devtools:document()
Package is on its way to CRAN!
Assume an R package (myPackage) that imports the R package RCircos via the DESCRIPTION file and the NAMESPACE file.
$ cat DESCRIPTION
Package: myPackage
Imports: RCircos (>= 1.2.0)
...
$ cat NAMESPACE
import(RCircos)
...
One of the perks of RCircos is that it defines a custom environment (called RCircos.Env) and reads/writes variables to this environment from various of its functions. For example, function RCircos.Initialize.Plot.Parameters reads and writes to this environment.
...
RCircosEnvironment <- NULL;
RCircosEnvironment <- get("RCircos.Env", envir = globalenv());
RCircosEnvironment[["RCircos.PlotPar"]] <- plot.param;
(This peculiar behavior has also been recognized by other R packages; see, for example, lines 247-249 of this package).
Unfortunately, it seems that the environment RCircos.Env is not recognized out of the box in myPackage when I simply import RCircos via the DESCRIPTION file and the NAMESPACE file.
So what can be done?
There seem to be two options of making the environment RCircos.Env accessible to functions like RCircos.Initialize.Plot.Parameters. However, both of these options cause the CRAN check (R CMD check myPackage --as-cran) to issue WARNINGs or NOTEs during the mandatory evaluation of myPackage prior to the submission to CRAN, thus preventing its acceptance on CRAN.
Option 1: I include the following line directly prior to the function demanding the object:
# my code here #
assign("RCircos.Env", RCircos::RCircos.Env, .GlobalEnv)
RCircos.Set.Core.Components(...)
# my code here #
However, the CRAN check highlights this line with a NOTE, thus preventing the acceptance of myPackage on CRAN.
* checking R code for possible problems ... NOTE
Found the following assignments to the global environment:
File ‘PACViR/R/visualizeWithRCircos.R’:
assign("RCircos.Env", RCircos::RCircos.Env, .GlobalEnv)
Option 2: I load the entire RCircos library prior to the function demanding the object:
# my code here #
library(RCircos)
RCircos.Set.Core.Components(...)
# my code here #
However, the CRAN check highlights this option with a WARNING, again preventing the acceptance of myPackage on CRAN.
* checking dependencies in R code ... WARNING
'library' or 'require' call not declared from: ‘RCircos’
'library' or 'require' call to ‘RCircos’ in package code.
Please use :: or requireNamespace() instead.
See section 'Suggested packages' in the 'Writing R Extensions' manual.
Surely, there must be an easy and CRAN-compatible way of making the environment RCircos.Env accessible to functions such as RCircos.Set.Core.Components within myPackage! Can someone name and explain such a way?
Apparently the normal re-export does not work with environments as it does with functions. But this does work:
RCircos.Env <- RCircos::RCircos.Env
#' test
#'
#' #param ... data
#'
#' #export
test_fun <- function(...) {
RCircos::RCircos.Set.Core.Components(...)
}
With DESCRIPTION:
Package: test
Type: Package
Title: test
Description: This is a description.
Version: 0.1.0
Authors#R: person("Wouter", "van der Bijl",
email = "redacted#redacted.com",
role = c("aut", "cre"))
Maintainer: Wouter van der Bijl <redacted#redacted.com>
License: GPL-3
Encoding: UTF-8
LazyData: true
Imports: RCircos
RoxygenNote: 6.1.1
And this NAMESPACE:
# Generated by roxygen2: do not edit by hand
export(test_fun)
Test with:
library(test)
data(UCSC.HG19.Human.CytoBandIdeogram, package = 'RCircos')
test_fun(UCSC.HG19.Human.CytoBandIdeogram)
Basically, when RCircos runs get("RCircos.Env", envir = globalenv()), it will traverse up the search path until it finds the RCircos.Env from your package instead.
When running R CMD Check I get 0 errors, 0 warnings, 0 notes.
Note that this strategy that RCircos uses, with an environment that gets looked up by using get(.., envir = globalenv()) is really unorthodox and generally not a good idea. R functions should generally not have side-effects, such as editing unseen environments. Setting default values etc. is typically done using options(). The whole package is probably not something you'd want to emulate, but at least now you can use it as a dependency.
UPDATE
I have completed the package and it is hosted online at https://github.com/iembry-USGS/ie2misc.
Since the error message in the original post was not helpful, I attempted to roxygenize the package to see if that would work or not. Below are the commands and the error message.
library(roxygen2)
roxygenize(".", roclets = "rd")
# First time using roxygen2. Upgrading automatically...
# Error in parse(n = -1, file = file, srcfile = NULL,
# keep.source = FALSE) :
# 1:1: unexpected input
# 1: �
^
I am assuming that the unexpected input is referring to a character, but I don't know which file has the character in question.
Any assistance would be helpful.
Thank you.
UPDATE End
I am working on creating a package that contains 3 functions. I've been successful at creating 3 other packages using 1 function, but not with this package.
I have included the contents of the DESCRIPTION file below. Below that content is the code and the error that I am receiving when attempting to document this package.
Thank you.
Package: ie2misc
Title: Irucka Embry's Miscellaneous functions created while he was a
CNTS USGS Contractor.
Version: 1.0.0
Authors#R: person("Irucka", "Embry", , "", c("aut", "cre"))
Depends: R (>= 3.0.0), tcltk, data.table (>= 1.9.4)
Imports: openxlsx, gWidgets2, gWidgets2tcltk, stringi, qdap
Suggests: Rcpp (>= 0.11.5)
Maintainer: Irucka Embry <iembry#usgs.gov>
Description: Irucka Embry's Miscellaneous functions (processing exp files,
psf files, etc.) created while he was a Cherokee Nation Technology Solutions
(CNTS) USGS Contractor.
URL: https://gitlab.com/iembry/ie2misc
BugReports: https://gitlab.com/iembry/ie2misc/issues
License: CC0
Collate:
'ie2misc.R'
'psfFileChangeBATCH.R'
'psfFileChange.R'
'expFileOutput.R'
LazyData: true
Encoding: UTF-8
Then I run:
setwd("ie2misc"); library(devtools); document();
Updating documentation
Loading
Error in if (pkg$package == "devtools") { : argument is of length zero
I still don't know what the problem is, but I created an empty package with library(devtools). Then, I copied most of the ie2misc files into the newly created package. I also rewrote the DESCRIPTION file in RStudio. (Usually I use the Kate text editor for working on all files for R packages.) Once those steps were completed, I was able to document, check, and build the package.
I'm creating a package using devtools and roxygen2 (in RStudio), however after I've built the package my function no longer works as intended. Yet, if I load the function's .R file and run the function from there in RStudio, it works perfectly. I've created another package using this method before and it worked fine (13 functions all working as intended from my other package), yet I cant seem to get this new one to work.
To start creating the package I start with:
library("devtools")
devtools::install_github("klutometis/roxygen")
library(roxygen2)
setwd("my parent directory")
create("triale")
All is working fine so far. So I put my .R file containing my function in the R folder under the triale folder. The .R file looks like this:
#' Trial Z Function
#'
#' This function counts the values in the columns
#' #param x is the number
#' #keywords x
#' #export
#' #examples
#' trialz()
trialz = function(x) {w_id= c(25,x,25,25,25,1,1,1,1,1);
wcenter= c(rep("BYSTAR-1",10));
df1 <<- data.frame(w_id, wcenter);
countit <<- data.table(df1);
view <<- countit[, .N, by = list(w_id, wcenter)];
View(view)}
Again if I were to just run the code from the .R file, and test the function it works fine. But to continue, next I enter:
setwd("./triale")
document()
The triale documentation is updated, triale is loaded, and the NAMESPACE and trialz.Rd are both written so that trialz.Rd is under the man folder, and NAMESPACE is under the triale folder as intended. Next I install triale:
setwd("..")
install("triale")
Which I know works because I get the following:
Installing triale
"C:/PROGRA~1/R/R-31~1.3/bin/x64/R" --vanilla CMD INSTALL \
"C:/Users/grice/Documents/R/triale" \
--library="C:/Users/grice/Documents/R/win-library/3.1" --install-tests
* installing *source* package 'triale' ...
** R
** preparing package for lazy loading
** help
*** installing help indices
** building package indices
** testing if installed package can be loaded
*** arch - i386
*** arch - x64
* DONE (triale)
Reloading installed triale
Package is now built, so I do the following:
library("triale")
library("data.table")
Note whenever I load the package data.table I get the following error message:
data.table 1.9.4 For help type: ?data.table
*** NB: by=.EACHI is now explicit. See README to restore previous behaviour.
However it doesnt seem to affect my function. So now its time to test my function from my package:
trialz(25)
This goes through, and I of course get a populated df1, and countit, but for whatever reason view is always empty (as in 0 obs. of 0 variables).
So I test my work using the dummy code below:
>trialy = function(x) {wid= c(25,x,25,25,25,1,1,1,1,1);
wc= c(rep("BYSTAR-1",10));
df2 <<- data.frame(wid, wc);
countitt <<- data.table(df2);
viewer <<- countitt[, .N, by = list(wid, wc)];
View(viewer)}
>trialy(25)
Even though this is the same exact code with just the names changed around it works. Dumbfounded I open trialz.R and copy the function from there and run it as below, and that works:
> trialz = function(x) {w_id= c(25,x,25,25,25,1,1,1,1,1);
wcenter= c(rep("BYSTAR-1",10));
df1 <<- data.frame(w_id, wcenter);
countit <<- data.table(df1);
view <<- countit[, .N, by = list(w_id, wcenter)];
View(view)}
> trialz(25)
Since I've created a package before I know my method is solid (that package had 13 dif. functions, all of which worked). I just don't understand how a function can work fine as written, yet when I package it, the function no longer works.
Again here is where it stops working as intended when using my package:
view <<- countit[, .N, by = list(w_id, wcenter)];
View(view)}
And my end result should look something like this, if my package worked:
wid wc N
1 25 BYSTAR-1 5
2 1 BYSTAR-1 5
Can anyone explain why view is never populated after I package my function? I've tested it as much as I know how, and my results should be reproducible for anyone thats willing to try it for themselves.
Thanks, I appreciate any feedback.
Your problem here is that "<<-" does not create variables in the global environment but rather in the parent environment. (See help("<<-").)
The parent environment of a function is the environment in which it has been defined. In the case where you defined your function directly in your workspace, this parent environment actually is the same as your workspace environment (namely: .GlobalEnv), which is why your variables are assigned values as you expect them to. In the case where your function is packaged, however, the parent environment is the package environment and not the .GlobalEnv! This is why you do not see your variables being assigned values in your workspace.
Refer to the chapter on environments in Hadley's book and How R Searches and Finds Stuff for more details on environments in R.
Note that doing this would not be considered a proper debugging technique, to say the least. In general, you never want to use the "<<-" operator.
For options on debugging R code, see, e.g., this question. I, in particular, like the debugonce function very well. See ?debugonce.
I forgot one important part when editing my description file in that I for got to add
Imports: data.table
Also the NAMESPACE file needed to include the data.table package as an import as well, like so:
import(data.table)
export(Z)
export(AS) .... etc.
Doing this ensures that whenever a function within your package uses a function from another package, that (second) package is called up before your code is executed.
I was trying now for several hours to build a package in R and getting a bit desperate about how slowly I progress. I managed quite fast to build a package with no dependencies, everything works fine. Due to recommendations in several posts, I'm using R Studio, devtools and Roxygen2 (being on Windows). With dependencies, I get problems when I CHECK (e.g. with devtools::check() ):
checking dependencies in R code ... NOTE Namespace in Imports field
not imported from: 'ggplot2' All declared Imports should be used.
See the information on DESCRIPTION files in the chapter 'Creating R
packages' of the 'Writing R Extensions' manual.
Furthermore, check() deletes the import(ggplot2) line in the NAMESPACE. If I do check(document=F), it gives an cryptic error about a digest package which is not loaded. I read 'Writing R Extensions' - 1.1.3 Package Dependencies and Hadley's Wiki concerning how to write packages, but couldn't solve my problem. DESCRIPTION and NAMESPACE files of other R packages from CRAN don't look different to mine (for my eyes)?
Question: What am I doing wrong? Sorry for such a basic question, but I am at a loss and most step-by-step tutorials I've seen so far stop before explaining dependencies.
So far, I have 3 files:
A DESCRIPTION:
Package: test
Type: Package
Title: Foo
Version: 1.0
Date: 2014-03-21
Author: Bar
Maintainer: Foo <bar#mail.com>
Description: Blubb
Imports:
ggplot2
License: GPL-3
A NAMESPACE:
export(is.equal.null)
import(ggplot2)
A R-File:
#' Extension of compare to include NULLs
#'
#' Works as an extension to usual compare
#' Compares two basic objects which in addition to usual compare can be NULL
#' Intuitive output: TRUE if both are equal or NULL resp., FALSE if both are unequal or only one is NULL
#'
#' #param obj1 Basic object like \code{numeric, char, boolean, NULL}
#' #param obj2 Basic object like \code{numeric, char, boolean, NULL}
#' #keywords compare
#' #export
#' #examples
#' is.equal.null(5,5) # TRUE
#' is.equal.null(5,NULL) # FALSE
#' is.equal.null(NULL,NULL) # TRUE
is.equal.null <- function(obj1, obj2) {
# Small helper function to generalize comparison to comparison of NULL
# returns TRUE if both are NULL, and FALSE if only one of the objects is NULL
bool <- obj1==obj2
#qplot(obj1)
if (length(bool)) return(bool)
if (is.null(obj1) & is.null(obj2)) return(TRUE)
return(FALSE)
}
You need to declare imports in two places:
The DESCRIPTION file. You should have a line similar to:
Imports: ggplot2, pkg1, pkg2
The NAMESPACE file. Here you declare the packages you need
import(ggplot2)
or to avoid namespace clashes
importFrom(ggplot2, geom_point)
You can get roxygen2 to maintain the NAMESPACE file using the #import and #importFrom tags.
In your example your DESCRIPTION file looks OK, but you haven't added the necessary functions to the NAMESPACE.
A standard workflow, as described by Hadley, is:
library(devtools)
# Add a dependency
use_package('tibble')
# (Re-)build NAMESPACE
document()
# Reload the package: CTRL-L or
load_all()