简体   繁体   中英

Building binary package R

I am new to R and I am trying to make a standalone executable so that my scripts can be run without development tools. I have created multiple R scripts containing different functions and have been using a main.r script to connect the other scripts. I have been using RStudio and using Source on each file to add them to the Global Environment and finally using Source on my main file to start executing my program. When attempting to build a binary package through:

Build > Build Binary Package

I was getting the error:

ERROR: The build directory does not contain a DESCRIPTION 
file so cannot be built as a package.

So I created a package and now the error I get is

** preparing package for lazy loading
Error in reorderPopulation(pop_fitness_list) : 
  could not find function "reorderPopulation"
Error : unable to load R code in package 'EAtsp'
ERROR: lazy loading failed for package 'EAtsp'
* removing 'C:/Users/Ryan/AppData/Local/Temp/RtmpsXbv0j/temp_libpath27ec59515c59/EAtsp'
Error: Command failed (1)
Execution halted

Exited with status 1.

Can someone explain to me how to fix this problem?

EDIT: I have since added roxygen comments to each of my functions and they are all displaying within the NAMESPACE file but still have the same issue.

These are the files my R directory contains:

fitness.r
initDataset.r
main.r
operators.r
selection.r

The functions within fitness.r can be found from main.r with no problem so I moved the reorderPopulation function which was previously in selection.r to fitness.r and it can be found. Why can the functions inside the selection.r file and possibly the others not be found?

There's nothing reproducible, so I'll go through a hacked example that works, perhaps you can use it as a template for explaining what is different and why yours should still work.

./DESCRIPTION

Package: Porteous96
Title: This package does nothing
Version: 0.0.0.9000
Authors@R: person('r2evans', email='r2evans@ignore.stackoverflow.com', role=c('aut','cre'))
Description: This package still does nothing
Depends: R (>= 3.3.3)
License: MIT
Encoding: UTF-8
LazyData: true
RoxygenNote: 6.0.1

(Go ahead and try to send an email there ... I don't think it'll bug me ...)

./NAMESPACE

After create :

# Generated by roxygen2: fake comment so roxygen2 overwrites silently.
exportPattern("^[^\\.]")

After document :

# Generated by roxygen2: do not edit by hand

export(reorderPopulation)

(Regardless, this file needs no manually editing, assuming you are either using roxygen2 with its #' @export clause, or you are using the default "export almost everything" without roxygen2 .)

./R/reorderPopulation.R

#' Do or do not
#'
#' (There is no try.)
#' @param ... any arguments ultimately ignored
#' @return nothing, invisibly
#' @export
reorderPopulation <- function(...) {
  cat("do nothing\n")
  invisible(NULL)
}

unorderPopulation <- function(...) {
  reorderPopulation()
  cat("should not be found\n")
  invisible(NULL)
}

./R/zzz.R

I added this file just to try to "find" one of the exported functions from within this package.

.onLoad <- function(libname, pkgname) {
  reorderPopulation("ignored", "stuff")
}

I can get away with assuming the function is available, per ?.onLoad :

Note that the code in '.onLoad' and '.onUnload' should not assume any package except the base package is on the search path. Objects in the current package will be visible (unless this is circumvented), but objects from other packages should be imported or the double colon operator should be used.

Build and Execute

I actually started this endeavor with a template directory created by starting in the intended directory and running:

devtools::create(".")
# Creating package 'Porteous96' in 'C:/Users/r2/Projects/StackOverflow'
# No DESCRIPTION found. Creating with values:
# Package: Porteous96
# Title: What the Package Does (one line, title case)
# Version: 0.0.0.9000
# Authors@R: "My Real Name <myreal@@email.address.com> [aut,cre]"
# Description: What the package does (one paragraph).
# Depends: R (>= 3.3.3)
# License: Call for information, please
# Encoding: UTF-8
# LazyData: true
# * Creating `Porteous96.Rproj` from template.
# * Adding `.Rproj.user`, `.Rhistory`, `.RData` to ./.gitignore

However, you can easily just use the samples I provided above and move forward without calling create . (It also includes some other files, eg, ./.gitignore , ./Porteous96.Rproj , and ./.Rbuildignore , none of which are required in the rest of my process here. If you have them and they have non-default values, that might be good to know.)

From there, I edited/created the above files, then:

devtools::document(".")
# Updating Porteous96 documentation
# Loading Porteous96
# do nothing
# First time using roxygen2. Upgrading automatically...
# Writing NAMESPACE
# Writing reorderPopulation.Rd

(The reason you see "do nothing" above and below is that I put it in a function named .onLoad , triggered each time the library is loaded. This includes during devtools::document and devtools::install as well as the obvious library(Porteous96) .

One side-effect of that is that a ./man/ directory is created with the applicable help files. In this case, a single file, reorderPopulation.Rd , no need to show it here.

devtools::install(".")
# Installing Porteous96
# "c:/R/R-3.3.3/bin/x64/R" --no-site-file --no-environ --no-save --no-restore  \
#   --quiet CMD INSTALL "C:/Users/r2/Projects/StackOverflow/Porteous96"  \
#   --library="C:/Users/r2/R/win-library/3.3" --install-tests 
# * installing *source* package 'Porteous96' ...
# ** R
# ** preparing package for lazy loading
# ** help
# *** installing help indices
# ** building package indices
# ** testing if installed package can be loaded
# *** arch - i386
# do nothing
# *** arch - x64
# do nothing
# * DONE (Porteous96)
# Reloading installed Porteous96
# do nothing

For good measure, I close R and re-open it. (Generally unnecessary.)

library(Porteous96)
# do nothing

(Again, this is dumped to the console because of .onLoad .)

reorderPopulation()
# do nothing
unorderPopulation()
# Error: could not find function "unorderPopulation"
Porteous96:::unorderPopulation()
# do nothing
# should not be found

Wrap-Up

I'm guessing this does not solve your problem. It highlights about as much as I could glean from your question(s). Perhaps it provides enough framework where you can mention salient differences between my files and yours. Though answers are not meant for pre-solution discussion, I think it is sometimes necessary and useful.

After help from @r2evans I have managed to find a solution to the problem.

My main.r file was just a bunch of function calls with no function wrapping them. So I wrapped the function calls in a function and the function now looks as follows:

mainFunction <- function() {

    source("R/initSetup.r")
    initSetup()

    ... 
}

initSetup.r contains more source() calls to the other files that I use. The program is then run using the command mainFunction() in the R console

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM