undefined function / function not found - r

I created a package for R to learn how to develop these things and I got a error that I can't resolve. I saw this error was nor uncommon but I could not find a solution.
This is the code of my package (pretty simple):
absconc<-function(x,a,b,...)
{
a<-as.numeric(a)
b<-as.numeric(b)
absconcCalc<- function(x,a,b,...)
{
conc<- (x*a)+b
}
conc<-absconcCalc(x,a,b,...)
print.absconc<- function(x,a,b,...)
{
cat("Slope:")
cat(a,"\n")
cat("Intercept:")
cat(b,"\n")
cat("Concentration:")
cat(conc)
}
print.absconc(x,a,b)
}
I created the package using package.skeleton and it worked like a charm, even the building of the package using R CMD build absconc worked.
The problem was when I trying to use the package it gave me Error: could not find function "absconc".
I though it was a problem coming from NAMESPACE and the export so I tried exporting the functions using export(absconc). When I tried building that I got an error saying:
Error in namespaceExport(ns, exports) :
undefined exports: absconc, absconcCalc, print.absconc
I am now scratching my head to understand why my function are not recognized.
I would appreciate some help on that as this is only my first package.
EDIT: here are my files (A bit messy, sorry)
https://github.com/Frisacher/absconc

You should not edit NAMESPACE by hand. Insert the line #' #export at the top of your R file and run devtools::document() in the console. This will do what is necessary for you.
Now you can execute devtools::load_all() and run your function.
More explicitly:
1) Create a folder named "R" below the root directory and create an R script that contains your function as Martin Morgan suggested in the comments.
2) Add a roxygen comment to your R script to export it:
#' #export
absconc<-function(x,a,b,...)
{
a<-as.numeric(a)
b<-as.numeric(b)
...
}
3) Execute devtools::document() in the console.
> devtools::document()
Updating absconc documentation
Loading absconc
Writing NAMESPACE
4) Load your package with devtools::load_all().
> devtools::load_all()
Loading absconc
5) Run your function.
> absconc(1,2,3)
Slope:2
Intercept:3
Concentration:5

Related

Why does wrapper function result in error

I'm trying to include a function from the Bioconductor package "simpIntLists" in my own package. "import(simpIntLists)" is added to the Namespace file.
However, the function results in an error
do_xy <- function(organism, IDType){
network <- simpIntLists::findInteractionList(organism, IDType)
}
do_xy("human", "EntrezId")
#Error message
data set ‘HumanBioGRIDInteractionEntrezId’ not foundError in get("HumanBioGRIDInteractionEntrezId") :
object 'HumanBioGRIDInteractionEntrezId' not found
# results in the same error (outside of the function)
simpIntLists::findInteractionList(organism, IDType)
It works fine when simpIntLists is attached
# works
library(simpIntLists)
network <- simpIntLists::findInteractionList(organism, IDType)
I saw the code here (https://bioconductor.org/packages/release/data/experiment/html/simpIntLists.html).
This code does not seem to take into account the situation where the package is used without installation.
For your information, the relevant part to this error is around the line 52.
else if (organism == 'human'){
if (idType == 'EntrezId'){
data(HumanBioGRIDInteractionEntrezId);
interactionList <- get("HumanBioGRIDInteractionEntrezId");
}
It tries to fetch the data to the namespace but it fails to do so if the package is not imported via library yet. This only generates a warning. The error then occurs when it tries to use the data because it does not exist in the namespace.
A workaround is that you import the data in your code explicitly. Then you can use the function as below. Note that the warning remains because of the embedded package code. If the warning is annoying, use suppressWarnings.
data(HumanBioGRIDInteractionEntrezId, package="simpIntLists")
simpIntLists::findInteractionList("human", "EntrezId")

PreprocessCore package

I'm quite new to R and I got an assignment that includes a sourcecode.
Part of the source code includes the following line:
library(preprocessCore)
Then I have in my source code a definition of the following function:
quantile.normalize.raw.gtex <- function(edata.mat)
{
norm_edata = normalize.quantiles(as.matrix(edata.mat))
rownames(norm_edata) = rownames(edata.mat)
colnames(norm_edata) = colnames(edata.mat)
return(norm_edata)
}
Finally, I have an object being initialized to the output of this function, after sending a predefined parameter:
tissue.edata.qn = quantile.normalize.raw.gtex(tissue.edata)
From what I understand, the library function is supposed to include the function normalize.quantiles, which is called in the function that is defined in my source code.
However, when I run the line library(preprocessCore) I get the following error:
Error in library(preprocessCore) :
there is no package called ‘preprocessCore’
I also tried to run the rest of the code and got the error:
Error in normalize.quantiles(as.matrix(edata.mat)) :
could not find function "normalize.quantiles"
I looked for the preprocessCore online and eventually I tried to write install.packages("preprocessCore"), but I got a warning message that this package is only available in version 3.6.0 of R, even though I checked and this is the version that I have.
If somebody has any idea what the problem is, I will appreciate your help.
Thanks in advance
The preprocessCore package is available in Bioconductor. So, to install it, you need the following lines:
source("http://bioconductor.org/biocLite.R")
biocLite("preprocessCore")
After that, you can load the package using library(preprocessCore)
Hope it helps.

Function imported from dependency not found, requires library(dependency)

I am trying to create an R package that uses functions from another package (gamlss.tr).
The function I need from the dependency is gamlss.dist::TF (gamlss.dist is loaded alongside gamlss.tr), but it is referenced in my code as simply TF within a call to gamlss.tr::gen.trun.
When I load gamlss.tr manually with library(), this works. However, when I rely on the functions of the dependency automatically being imported by my package through #import, I get an "object not found" error as soon as TF is accessed.
My attempt to be more explicit and reference the function I need as gamlss.dist::TF resulted in a different error ("unexpected '::'").
Any tips on how to use this function in my package would be much appreciated!
The code below reproduces the problem if incorporated into a clean R package (as done in this .zip), built and loaded with document("/path/to/package"):
#' #import gamlss gamlss.tr gamlss.dist
NULL
#' Use GAMLSS
#'
#' Generate a truncated distribution and use it.
#' #export
use_gamlss <- function() {
print("gen.trun():")
gamlss.tr::gen.trun(par=0,family=TF)
#Error in inherits(object, "gamlss.family") : object 'TF' not found
#gamlss.tr::gen.trun(par=0,family=gamlss.dist::TF)
#Error in parse(text = fname) : <text>:1:1: unexpected '::'
y = rTFtr(1000,mu=10,sigma=5, nu=5)
print("trun():")
truncated_dist = gamlss.tr::trun(par=0,family=TF, local=TRUE)
model = gamlss(y~1, family=truncated_dist)
print(model)
}
use_gamlss() will only start working once a user calls library(gamlss.tr).
This is due to bad design of gamlss.tr in particular the trun.x functions (they take character vectors instead of family objects / they evaluate everything in the function environment instead of the calling environment).
To work around this, you have to make sure that gamlss.distr is in the search path of the execution environment of gamlss.tr functions (This is why ## import-ing it in your package does not help: it would need to be #' #import-ed in gamlss.tr).
This can be achieved by adding it to Depends: of your package.
If you want to avoid that attaching your package also attaches gamlss.distr, you could also add the following at the top of use_gamlss:
nsname <-"gamlss.dist"
attname <- paste0("package:", nsname)
if (!(attname %in% search())) {
attachNamespace(nsname)
on.exit(detach(attname, character.only = TRUE))
}
This would temporarily attach gamlss.dist if it is not attached already.
You can read more on namespaces in R in Hadley Wickham's "Advanced R"

Extended R package can't correctly communicate with its 'parent' R package

I am trying to build a package that extends another package. However at its most basic level I am doing something wrong. I build a simple example that presents the same issue:
I have two packages, packageA and packageB. packageA has a single R file in the R folder that reads:
local.env.A <- new.env()
setVal <- function()
{
local.env.A$test <- 1
}
getVal <- function()
{
if(!exists("test", envir = local.env.A)) stop("test does not exist")
return(local.env.A$test)
}
For packageB I have the following single R file in the R folder:
# refers to package A
setVal()
getValinA <- function()
{
return(getVal())
}
I want both packageA and packageB to be available for end users, therefore I set packageB to depend on packageA (in the description file). When packageB is loaded, e.g. by means of library(packageB) I expect it to run setVal() and thus set the test value. However, if I next try to get the value that was set by means of getValinA(), it throws me the stop:
> library(packageB)
Loading required package: PackageA
> getValinA()
Error in getVal() : test does not exist
I am pretty sure it is related to environments, but I am not sure how. Please help!
With thanks to #Roland. The answer was very simple. I was under the impression (assumptions assumptions assumptions!) that when you perform library(packageB) it would load all the actions within it, in my case perform the setVal() function. This is however not the case. If you wish this function to be performed you need to place this within the function .onLoad:
.onLoad <- function(libname, pkgname)
{
setVal()
}
By convention you place this .onload function in an R file called zzz.R. Reason being that if you do not specifically collate your R scripts it will load alphabetically, and it makes sense to perform your actions when at least all the functions in your package are loaded.

Why does using "<<-" in a function in the global workspace work, but not in a 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.

Resources