How to define which variables or functions from a package are exported - r

My R package uses an internal variable x. If I load the package (I've only tried using devtools::load_all), then x doesn't appear in the ls() list, but it does have a value. How can I avoid this?
I'm fine with the user being able to access the variable with myPackage::x, but not simply x.

The load_all function has an export_all argument.
From ?load_all
If TRUE (the default), export all objects. If FALSE, export only the objects that are listed as exports in the NAMESPACE file.
So, try using export_all=FALSE in your load_all call.

Try building the package first, and check whether the problem still exists. The exports from a package are defined in the NAMESPACE file. When you use devtools::load_all, the namespace isn't loaded ( see here). Read more about this and building a package in the manual Writing R extensions.
You might be using a default export pattern in your NAMESPACE file. Check it in your package, and if it looks like this:
exportPattern("^[^\\.]")
then the package exports everything from the namespace that doesn't start with a dot. So you either call it .x, or you change the exportPattern() to eg...
export(myfun1, myfun2)
to export the functions myfun1 and myfun2 from the package. By explicitly defining what you want to export, you avoid that something's available when there's no need for that.

Related

How to declare a dependency on an R package from which you only use S3/S4 methods, but no exports?

Currently I have in my package DESCRIPTION, a dependency on dbplyr:
Imports:
dbplyr,
dplyr
dbplyr is useful almost solely because of the S3 methods it defines: https://github.com/tidyverse/dbplyr/blob/main/NAMESPACE. The actual functions you call to use dbplyr are almost entirely from dplyr.
By putting dbplyr in my Imports, it should automatically get loaded, but not attached, which should be enough to register its S3 methods: https://r-pkgs.org/dependencies-mindset-background.html#sec-dependencies-attach-vs-load.
This seems to work fine, but whenever I R CMD check, it tells me:
N checking dependencies in R code (10.8s)
Namespace in Imports field not imported from: ‘dbplyr’
All declared Imports should be used.
Firstly, why does R CMD check even check this, considering that it often makes sense to load packages without importing them. Secondly, how am I supposed to satisfy R CMD check without loading things into my namespace that I don't want or need?
I am pretty sure two of your assumptions are false.
First, putting Imports: dbplyr into your DESCRIPTION file won't load it, so its methods won't be loaded from that alone. Basically the Imports field in the DESCRIPTION file just guarantees that dbplyr is available to be loaded when requested. If you import something via the NAMESPACE file, that will cause it to be loaded. If you evaluate dbplyr::something that will cause it to be loaded. Executing loadNamespace("dbplyr") is another way, and there are a few others. You may also load some other package that loads it.
Second, I think you have misinterpreted the error message. It isn't saying that you loaded it without importing it (though it would complain about that too), it is saying that it can't detect any use of it in your package, so maybe it shouldn't be a requirement for installing your package.
Unfortunately, the code to detect uses is fallible, so it sometimes misses uses. Examples I've heard about are:
if the package is only used in the default value for a function argument. This has been fixed in R-devel.
if the package is only used during the build to construct some object, e.g. code like someclass <- R6::R6Class( ... ) needs R6, but the check code won't see it because it looks at someclass, not at the source code that created it.
if the use of the package is hidden by specifying the name of the package in a character variable.
if the need for the package is indirect, e.g. you need to use ggplot2::geom_hex. That needs the hexbin package, but ggplot2 only declares it as "Suggested".
These examples come from this discussion: https://github.com/hadley/r-pkgs/issues/828#issuecomment-1421353457 .
The recommended workaround there is to create an object that refers to the imported package explicitly, e.g. putting the line
dummy_r6 <- function() R6::R6Class
into your package is enough to suppress the note without actually loading R6. (It will be loaded if you ever call this function.)
However, your requirement is stronger: you do need to make sure dbplyr is loaded if you want its methods to be used. I'd put something in your .onLoad() function that triggers the load. For example,
.onLoad <- function(lib, pkg) {
# Make sure the dbplyr methods are loaded
loadNamespace("dbplyr")
}
EDITED TO ADD: As pointed out in the comments, there's a bug in the check code that means it won't detect this as being a use of dbplyr. You really need to do both things, e.g.
.onLoad <- function(lib, pkg) {
# Make sure the dbplyr methods are loaded
loadNamespace("dbplyr")
# Work around bug in code checking in R 4.2.2 for use of packages
dummy <- function() dbplyr::across_apply_fns
}
The function used in the dummy construction is arbitrary; it probably doesn't even need to exist, but I chose one that does.

Role of export() without an argument in a namespace file

I found this in the NAMESPACE file for a package:
export()
When I look at reference docs for export(), all the examples I find use an argument, e.g., export(myFunc), and I cannot locate an exact man page for export(). What will the above line do?
When documenting functions in a package, one will usually use the function export implying that the function that has been specified should be exported as part of the package.
The NAMESPACE holds information about functions imported from other packages as well as those exported from the package one is writing. Hence, under the NAMESPACE file, the export(myFunc) simply refers to a function that will be part of the package. It is nowadays normally not generated by hand and is done with roxygen2. An empty export() might be a design error because as the manual states:
Exports are specified using the export directive in the NAMESPACE file. A directive of the form
export(f, g)
specifies that the variables f and g are to be exported. (Note that variable names may be
quoted, and reserved words and non-standard names such as [<-.fractions must be.)
For more intuition, look at the error that occurs when you try to use a function not exported as part of a package.
stats::group_by
Error: 'group_by' is not an exported object from 'namespace:stats'

Self-written R package does not find its own function

I created a package with some functions which are helpful at my company. Recently, I restructered the package such that there are helper functions which need not to be accessible for everyone, but are called internally from other (exported) functions of the package. These helper functions are not exported to the namespace (no #' #export in the respective .R files).
Now, when I call one of the "major" (exported) functions, I get the error message (no real function names):
Error in major_function() : could not find function "helper_function"
Im fairly new in building packages, but from what I understood so far (from https://cran.r-project.org/web/packages/roxygen2/vignettes/namespace.html), it should neither be necessary to export the helper functions, nor to add #' importFrom my_package helper_function to the .R file of the major function.
When I tried this, it actually produced errors when checking the package. I also tried to call the helper functions with my_package:::helper_function, but this lead to the note that it should almost never be necessary to call functions from the same package like this.
Maybe useful information:
The error occurs only when I call a major_function_1 which internally calls major_function_2 which calls a helper_function.
I think there is more to your problem than what you state. As long as all your functions are defined in the same namespace (this also means that all your functions need to live in .R files in the same folder), the calling function should find the helper-functions accordingly.
I suspect you have your helper functions nested in some way, and that is causing the problem.
I recommend to recheck your namespace structure, or post a simplistic outline of your package here.
Another reason that could come to mind, is that you do not export your 'mayor_function2' in your NAMESPACE-file in your package root (maybe you have not recompiled the Roxygen documentation generating this file), and additionally have a local shadow of the the calling function 'mayor_function1'. Try to check this and rerun from a clean compile.

Difference between environment and namespace

I know what a namespace is from other languages but in R I just cannot find a difference between the environment and namespace. Could anyone explain this since in the tutorials I have read (as The Art of R Programming and others) I just cannot find a distinction?
A namespace is something specific to a package. It is defined as a list of directive that allow you to import functions from other packages to be used locally or to export your functions and classes to be used in R.
So if you have created in your package a function called foo you will add to your namespace something like export(foo) to make your function usable.
If you want to import function from a specific package to use them in yours, you will add import(thePackage)
The environment is simply the space where you associate names to values. You can see it as a context in which you can evaluate functions and expressions.

R function without exporting in Namespace

I am writing an R package. Generally, I have some functions that they are not useful for external uses. So when I put them in Namespace file, it causes an error about documentation of functions. On the other hand, if I remove them from Namespace file, it causes another problem, Function not found. So, is there any way of calling a function without a need of writing documentations?
As Andrie commented if you want to include the function in the R package you need to put it inside a folder (e.g. packageparent/R/) and declare in NAMESPACE. You do not put a function in NAMESPACE.
IF you do not want to include it in your package, none of your functions in your package shall call this function, otherwise the package does not compile. You still can include this function in your package and not write any documentation for it.
To use this function outside your package just source it

Resources