R function call without loading package - r

I want to use functions from the Bioconductor packages hypergraph and hyperdraw without loading the packages. When running an example from the hyperdraw vignette
dh1 <- hypergraph::DirectedHyperedge("A", "B", "R1")
dh2 <- hypergraph::DirectedHyperedge(c("A", "B"), c("C", "D"), "R2")
hg <- hypergraph::Hypergraph(LETTERS[1:5], list(dh1, dh2))
hgbph <- hyperdraw::graphBPH(hg)
I get the error:
Error in hyperdraw::graphBPH(hg) : could not find function "hyperedges"
If I try to load hyperedges:
hyperedges <- hyperdraw:::hyperedges
I get the error
Error in get(name, envir = asNamespace(pkg), inherits = FALSE) :
object 'hyperedges' not found
When I load both packages using library or require, I get no error (in running the above code without hypergraph:: and hyperdraw::).
The reason why I do not want to load the packages is because I am building a package which uses hyperdraw and hypergraph in only one function and I'd rather put these packages into Suggests than into Depends in my DESCRPTION file.
Does anyone have an idea how to solve this?

hyperdraw has this in it's DESCRIPTION file
Depends: R (>= 2.9.0), methods, grid, graph, hypergraph, Rgraphviz
and it's relying on finding hypergraph::hyperedges on the search() path. Personally, I think hyperdraw should include a line
importFrom(hypergraph, hyperedges)
in it's NAMESPACE file. Currently, the best thing to do is to add Depends: hyperdraw to your DESCRIPTION file, and to importFrom(hyperdraw, <whatever functions you need>). I have contacted the maintainer of hyperdraw to ask them to update the NAMESPACE as above; you could then merely Imports: hyperdraw. I think you're just making work for yourself and frustrating your users by trying to use Suggests or other approaches to subvert the need for formal dependencies.

Related

Config/reticulate not setting up environment - ModuleNotFoundError: No module named 'pandas'

I am trying to build an R package that wraps an internal python module; however, it seems to not be properly installing the dependencies like I would expect. According to the documentation, I should be able to define the Config/reticulate field in the DESCRIPTION file and it will handle setting up the python environment; however, it doesn't seem that's happening.
Reticulate dependency vignette
This is somewhat of a migration project, so currently we're writing R objects to file, then using system(command) to run the python code before reading the results back into R. There are reasons it's done this way, although the plan is to leverage more of the reticulate tools to reduce read/write, I just don't have the time to make those changes right now.
I've replaced system with py_run_file() without success and py_module_available('pandas') returns false after loading the package. If I initialize reticulate in the directory, this resolves the problem, but that doesn't solve my package distribution problem (internal package).
I guess the question is:
How do I ensure reticulate::configure_environment() actually runs when distributing a package?
Below is a rough reproduceable example, making the changes to a RStudio new package template should successfully not work.
/R/hello.R:
RunDemoPy <- function(){
pyScript = system.file("python/pyDemo.py", package = "pyTestpkg")
reticulate::py_run_file(pyScript)
}
DESCRIPTION FIELD:
Config/reticulate:
list(
packages = list(
list(package = "pandas")
)
)
Imports:
reticulate
R/zzz.R
.onLoad <- function(libname, pkgname){
packageStartupMessage("On Load - config environment")
reticulate::configure_environment(pkgname)
}
.onUnload <- function(libname){
}
.onAttach <- function(libname, pkgname){
}
inst/python/pyDemo.py:
import os
import pandas as pd
pdf = pd.DataFrame()
pdf.to_csv("demo.csv")
print("Dataframe done")

BiodiversityR::accumcomp.long function not found

I am trying to use the function accumcomp.long in the Biodiversity.R package in order to adjust my species accumulation curves in ggplot.
However, calling the function accumcomp.long gives me an error, suggesting that this function perhaps does no longer exists.
accum.long1 <- accumcomp.long(Accum.1, ci=NA, label.freq=5)
Error in accumcomp.long(Accum.1, ci = NA, label.freq = 5) :
could not find function "accumcomp.long"
The function BiodiversityR::accumcomp.long
returns
Error: 'accumcomp.long' is not an exported object from 'namespace:BiodiversityR'
I am not certain whether this is an issue with the package, the way the package is loaded into my R space, or perhaps unrelated to the package simply the format of my data.
My community and environment files are of dataframe class. I have tried loading them as .csv files as well as .rda files, but the error remains.
??accumcomp.long
renders "No results found".
I am using R version 3.5.3 (2019-03-11)
Any suggestions as to what else I could try?
Thanks in advance!
I re-installed the package BiodiversityR and included force = T (as per this thread https://community.rstudio.com/t/could-not-find-function-error-even-though-fun-is-in-namespace-and-has-an-rd-file/91243). I then reloaded the package. I am not sure what force = T does, but the accumcomp.long function now works.

How do I deal with an error message while installing a package?

I am brand new to this so please forgive my inexperience...I'm trying to learn.
I'm attempting to install an R package called "Doublet Finder" using the specified code given on the Github site.
When I do this, I get this error immediately:
Error in rbind(info, getNamespaceInfo(env, "S3methods")) :
number of columns of matrices must match (see arg 2)
Being new to R, I'm not sure what this error means and when I google this something similar comes up and the individual removed and re-installed ALL of their libraries...that seems crazy. Does anyone have advice on what this could be, how to fix it, or why the package won't install?
Your problem seems to be fairly similar to this one. It might be the case that the dependencies (packages that Doublet Finder relies on) are outdated. What you can try is to follow these steps to uninstall and reinstall all packages with the hope that by updating packages there isn't a version mismatch.
This code is copied from the website above:
ip <- as.data.frame(installed.packages(lib.loc = .libPaths()[1]),
stringsAsFactors = FALSE)
head(ip)
str(ip)
path.lib <- unique(ip$LibPath)
# create a vector with all the names of the packages you want to remove
pkgs.to.remove <- ip[,1]
head(pkgs.to.remove)
str(pkgs.to.remove)
sapply(pkgs.to.remove, remove.packages, lib = path.lib)
sapply(pkgs.to.remove, install.packages, lib = path.lib)

R: Patching a package function and reloading base libraries

Occasionally one wants to patch a function in a package, without recompiling the whole package.
For example, in Emacs ESS, the function install.packages() might get stuck if tcltk is not loaded. One might want to patch install.packages() in order to require tcltk before installation and unload it after the package setup.
A temp() patched version of install.packages() might be:
## Get original args without ending NULL
temp=rev(rev(deparse(args(install.packages)))[-1])
temp=paste(paste(temp, collapse="\n"),
## Add code to load tcltk
"{",
" wasloaded= 'package:tcltk' %in% search()",
" require(tcltk)",
## Add orginal body without braces
paste(rev(rev(deparse(body(install.packages))[-1])[-1]), collapse="\n"),
## Unload tcltk if it was not loaded before by user
" if(!wasloaded) detach('package:tcltk', unload=TRUE)",
"}\n",
sep="\n")
## Eval patched function
temp=eval(parse(text=temp))
# temp
Now we want to replace the original install.packages() and perhaps insert the code in Rprofile.
To this end it is worth nothing that:
getAnywhere("install.packages")
# A single object matching 'install.packages' was found
# It was found in the following places
# package:utils
# namespace:utils
# with value
#
# ... install.packages() source follows (quite lengthy)
That is, the function is stored inside the package/namespace of utils. This environment is sealed and therefore install.packages() should be unlocked before being replaced:
## Override original function
unlockBinding("install.packages", as.environment("package:utils"))
assign("install.packages", temp, envir=as.environment("package:utils"))
unlockBinding("install.packages", asNamespace("utils"))
assign("install.packages", temp, envir=asNamespace("utils"))
rm(temp)
Using getAnywhere() again, we get:
getAnywhere("install.packages")
# A single object matching 'install.packages' was found
# It was found in the following places
# package:utils
# namespace:utils
# with value
#
# ... the *new* install.packages() source follows
It seems that the patched function is placed in the right place.
Unfortunately, running it gives:
Error in install.packages(xxxxx) :
could not find function "getDependencies"
getDependencies() is a function inside the same utils package, but not exported; therefore it is not accessible outside its namespace.
Despite the output of getAnywhere("install.packages"), the patched install.packages() is still misplaced.
The problem is that we need to reload the utils library to obtain the desired effect, which also requires unloading other libraries importing it.
detach("package:stats", unload=TRUE)
detach("package:graphics", unload=TRUE)
detach("package:grDevices", unload=TRUE)
detach("package:utils", unload=TRUE)
library(utils)
install.packages() works now.
Of course, we need to reload the other libraries too. Given the dependencies, using
library(stats)
should reload everything. But there is a problem when reloading the graphics library, at least on Windows:
library(graphics)
# Error in FUN(X[[i]], ...) :
# no such symbol C_contour in package path/to/library/graphics/libs/x64/graphics.dll
Which is the correct way of (re)loading the graphics library?
Patching functions in packages is a low-level operation that should be avoided, because it may break internal assumptions of the execution environment and lead to unpredictable behavior/crashes. If there is a problem with tck/ESS (I didn't try to repeat that) perhaps it should be fixed or there may be a workaround. Particularly changing locked bindings is something to avoid.
If you really wanted to run some code at the start/end of say install.packages, you can use trace. It will do some of the low-level operations mentioned in the question, but the good part is you don't have to worry about fixing this whenever some new internals of R change.
trace(install.packages,
tracer=quote(cat("Starting install.packages\n")),
exit=quote(cat("Ending install packages.\n"))
)
Replace tracer and exit accordingly - maybe exit is not needed anyway, maybe you don't need to unload the package. Still, trace is a very useful tool for debugging.
I am not sure if that will solve your problem - if it would work with ESS - but in general you can also wrap install.packages in a function you define say in your workspace:
install.packages <- function(...) {
cat("Entry.\n")
on.exit(cat("Exit.\n"))
utils::install.packages(...)
}
This is the cleanest option indeed.

extracting source code from r package

I am trying to install the r package sowas and unfortunately it is too old to implement in the new versions of r.
According to the author you can use the package using the source() function to gain access to the code but I have not been able to figure out how to do that.
Any help is appreciated.
Here is a link to the package I described as it is not a CRAN package: http://tocsy.pik-potsdam.de/wavelets/
The .zip file is a windows binary and as such it won't be too interesting. What you'll want to look at is the contents of the .tar.gz archive. You can extract those contents and then look at the code in the R subdirectory.
You could also update the package to work with new versions of R so that you can actually build and install the package. To do so you could unpack the .tar.gz as before but now you'll need to add a NAMESPACE file. This is just a plaintext file at the top of the package directory that has a form like:
export(createar)
export(createwgn)
export(criticalvaluesWCO)
export(criticalvaluesWSP)
export(cwt.ts)
export(plot.wt)
export(plotwt)
export(readmatrix)
export(readts)
export(rk)
export(wco)
export(wcs)
export(writematrix)
export(wsp)
Where you have an export statement for any function in the package that you actually want to be able to use. If a function isn't exported then the functions in the package still have access to that function but the user can't use it (as easily). Once you do that you should be able to build and install the package.
I took the liberty of doing some of this already. I haven't actually taken the time to figure out which functions are useful and should be exported and just assumed that if a help page was written for the function that it should be exported and if there wasn't a help page then I didn't export it. I used Rd2roxygen to convert the help pages to roxygen code (because that's how I roll) and had to do a little bit of cleanup after that but it seems to install just fine.
So if you have the devtools package installed you should actually be able to install the version I modified directly by using the following commands
library(devtools)
install_github("SOWAS", "Dasonk")
Personally I would recommend that you go the route of adding the NAMESPACE file and what not directly as then you'll have more control over the code and be more able to fix any problems that might occur when using the package. Or if you use git you could fork my repo and continue fixing things from there. Good luck.
If you want to see the source code of a particular function, then just type the name of the function without the braces and press enter. You will see the code.
For example type var in command prompt to see it's code.
> var
function (x, y = NULL, na.rm = FALSE, use)
{
if (missing(use))
use <- if (na.rm)
"na.or.complete"
else "everything"
na.method <- pmatch(use, c("all.obs", "complete.obs", "pairwise.complete.obs",
"everything", "na.or.complete"))
if (is.na(na.method))
stop("invalid 'use' argument")
if (is.data.frame(x))
x <- as.matrix(x)
else stopifnot(is.atomic(x))
if (is.data.frame(y))
y <- as.matrix(y)
else stopifnot(is.atomic(y))
.Call(C_cov, x, y, na.method, FALSE)
}
<bytecode: 0x0000000008c97980>
<environment: namespace:stats>

Resources