Imported packages do not work with my package in R for some functions? - r

I built my own package. I imported the most important package that I need them in my package. In these packages there are some functions are not exported by the package (I did not find them in the namespace of the package). I need these functions. When I call them, I get an error that those funciton are not found. So, How I can solve this problem. Also, how does these packages uses this functions inside their packages without using #export!! any help please?
based on the answer:
I understand I do it like this inside my R code: I need the following function:
args <- preproc(c(as.list(environment()), call = match.call()),
check_matrix,
check_fammat,
check_parmat,
check_par2mat)
list2env(args, environment())
Then I must do like this:
VineCopula:::preproc()
Then how to call args?

You can call non exported functions with
packagename:::functionname()
It is however not recommended to do that since those functions might not be supported in future versions of packages.
If you want to use a non exported function from your own library inside your own library, you can just use functionname() altough some package developers still prefer packagename:::functionname().

Related

Name space of base package needed?

Writing an R-package I use name spaces to use functions from existing packages, e.g. raster::writeRaster(...).
However, I am wondering if functions from the base package have also be used like this, e.g. base::sum(...). This might end up in very confusing code parts:
foo[base::which(base::sapply(bar, function())]
No you don't need to reference base packages like this. You only need to reference non-base packages to ensure they are loaded into the function environment when functions from your package are run, either by using :: or #import in the Roxegen notes at the top of your script. See why you don't need to reference base packages below:
http://adv-r.had.co.nz/Environments.html
"Package namespaces keep packages independent. For example, if package A uses the base mean() function, what happens if package B creates its own mean() function? Namespaces ensure that package A continues to use the base mean() function, and that package A is not affected by package B (unless explicitly asked for)."(Hadley Wickham)
The only time you need to reference base:: is if the namespace for your package contains a package that has an alternative function of the same name.

Importing snowfall into custom R package

I'm developing an R package which needs to use parallelisation as made available by the snowfall package. snowfall doesn't seem to import the same was as other packages like ggplot2, data.table, etc. I've included snowfall, rlecuyer, and snow in the description file, name space file, and as an import argument in the function itself. When I try to access this function, I get the following error:
Error in sfInit() : could not find function "setDefaultClusterOptions"
The sfInit function seems to have a nostart / nostop argument which it says is related to nested usage of sfInit but that doesn't seem to do the trick for me either.
The actual code itself uses an sfInit (which is where I get the error), some sfExports and sfLibrarys, and an sfLapply.
Possible solution:
It seems to work if I move snow from the import section to the depends section in the Desciption file. I don't know why though.
When you include a package in 'Depends' when one attaches your package they also attach the package on which your package Depends to their namespace.
This and other differences between Depends and Imports is explained well in other questions on this site.
If you look at {snowfall}'s DESCRIPTION you'll see that it Depends on {snow}. It is plausible that the authors of snowfall know something we don't and that {snow} has to be attached to the global search path in order to work. In fact that is the top caveat in the top answer to the question I linked above...
... if your package relies on a package A which itself "Depends" on
another package B, your package will likely need to attach A with a
"Depends directive.
This is because the functions in package A were written with the
expectation that package B and its functions would be attached to the
search() path.
So, in your case, it just so happens that all {snowfall} wants is {snow} and you happened to provide it. However, it appears the more correct behavior may be for you to Depend on {snowfall} directly.
setDefaultClusterOptions is a function from the snow package. You need to import that too.

How to use S3 methods from another package which uses export rather than S3method in its namespace without using Depends or library()

I'm working on an R package at present and trying to follow the best practice guidelines provided by Hadley Wickham at http://r-pkgs.had.co.nz. As part of this, I'm aiming to have all of the package dependencies within the Imports section of the DESCRIPTION file rather than the Depends since I agree with the philosophy of not unnecessarily altering the global environment (something that many CRAN and Bioconductor packages don't seem to follow).
I want to use functions within the Bioconductor package rhdf5 within one of my package functions, in particular h5write(). The issue I've now run into is that it doesn't have its S3 methods declared as such in its NAMESPACE. They are declared using (e.g.)
export(h5write.default)
export(h5writeDataset.matrix)
rather than
S3method(h5write, default)
S3method(h5writeDataset, matrix)
The generic h5write is defined as:
h5write <- function(obj, file, name, ...) {
res <- UseMethod("h5write")
invisible(res)
}
In practice, this means that calls to rhdf5::h5write fail because there is no appropriate h5write method registered.
As far as I can see, there are three solutions to this:
Use Depends rather than Imports in the DESCRIPTION file.
Use library("rhdf5") or require("rhdf5") in the code for the relevant function.
Amend the NAMESPACE file for rhdf5 to use S3methods() rather than export().
All of these have disadvantages. Option 1 means that the package is loaded and attached to the global environment even if the relevant function in my package is never called. Option 2 means use of library in a package, which while again attaches the package to the global environment, and is also deprecated per Hadley Wickham's guidelines. Option 3 would mean relying on the other package author to update their package on Bioconductor and also means that the S3 methods are no longer exported which could in turn break other packages which rely on calling them explicitly.
Have I missed another alternative? I've looked elsewhere on StackOverflow and found the following somewhat relevant questions Importing S3 method from another package and
How to export S3 method so it is available in namespace? but nothing that directly addresses my issue. Of note, the key difference from the first of these two is that the generic and the method are both in the same package, but the issue is the use of export rather than S3method.
Sample code to reproduce the error (without needing to create a package):
loadNamespace("rhdf5")
rdhf5::h5write(1:4, "test.h5", "test")
Error in UseMethod("h5write") :
no applicable method for 'h5write' applied to an object of class
"c('integer', 'numeric')
Alternatively, there is a skeleton package at https://github.com/NikNakk/s3issuedemo which provides a single function demonstrateIssue() which reproduces the error message. It can be installed using devtools::install_github("NikNakk/s3issuedemo").
The key here is to import the specific methods in addition to the generic you want to use. Here is how you can get it to work for the default method.
Note: this assumes that the test.h5 file already exists.
#' #importFrom rhdf5 h5write.default
#' #importFrom rhdf5 h5write
#' #export
myFun <- function(){
h5write(1:4, "test.h5", "test")
}
I also have put up my own small package demonstrating this here.

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

Embed fix() function within .R script?

I am looking for a way to embed the fix() function within a script. Basically, here's what I'm currently doing:
I load a certain package. For example, library(PerformanceAnalytics)
I call the fix() function to edit a couple functions within the loaded package. Example, fix(VaR).
Then, using R's built-in editor, I copy-paste my function over the one originally loaded from the package.
Finally, I source in my .R script which calls the above functions I fixed and performs the computations I need.
Essentially, I'd like to streamline Step 3 above. Rather than having to manually type fix(function) and copy-paste over the original functions within the loaded package, I'd rather just have it done within a script I source.
Is there anyway to accomplish this?
FYI, I have reached out to the package's creator and loading a re-compiled version of the package with my modified code is out of the question.
Maybe source your functions and then use assignInNamespace?
EDIT #1:
The above won't work because assignInNamespace doesn't alter objects that have been exported. Instead,
put your functions in a file (foo.R)
load the package
then source(foo.R) or
sys.source(foo.R, envir=attach(NULL, name="myenv"))
Your functions will be higher up on the search list if you load them after the package, so R will find them before getting to the package's functions with the same name.
EDIT #2:
I didn't realize VaR called unexported functions in the namespace. That's why EDIT #1 doesn't work. To get it to work, you would need to explicitly reference all unexported PerformanceAnalytics functions used in VaR (e.g. change VaR.Gaussian to PerformanceAnalytics:::VaR.Gaussian).
See this post on R-devel for a couple other approaches. I couldn't quickly get Prof. Ripley's solution to work (I get the same error as in EDIT #1) and I didn't try Gabor's solution.
You can edit the body directly, discussed here:
What ways are there to edit a function in R?
You can download the packages source from CRAN. Edit the function (it will be found in PackageName/R), then install this package into R and just use it that way.
You can even change the package name in the DESCRIPTION file ... call it "PerformanceAnalytics2", then in R you just library(PerformanceAnalytics2) and use it as you would the original package.

Resources