构建二进制包R

时间:2017-10-16 21:18:06

标签: r

我是R的新手,我正在尝试创建一个独立的可执行文件,以便我的脚本可以在没有开发工具的情况下运行。我创建了多个包含不同功能的R脚本,并使用Build > Build Binary Package 脚本连接其他脚本。我一直在使用RStudio并在每个文件上使用Source将它们添加到全局环境中,最后在我的主文件上使用Source来开始执行我的程序。尝试通过以下方式构建二进制包时:

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

我收到了错误:

** 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.

所以我创建了一个包,现在我得到的错误是

roxygen

有人可以向我解释如何解决这个问题吗?

编辑:我已经为我的每个功能添加了NAMESPACE条评论,它们都显示在fitness.r initDataset.r main.r operators.r selection.r 文件中,但仍然存在同样的问题。

这些是我的R目录包含的文件:

fitness.r

main.r中的reorderPopulation内的功能可以从selection.r找到,没有任何问题,因此我将之前位于fitness.r的{​​{1}}功能移至selection.r可以被找寻到。为什么var BigInteger = require('bigi'); var signature = ecdsa.sign(shaMsg, BigInteger.fromBuffer(privateKey)); 文件中的函数以及其他函数可能找不到?

2 个答案:

答案 0 :(得分:1)

没有什么可以重复的,所以我将通过一个有效的黑客示例,也许你可以用它作为模板来解释不同之处以及为什么你的工作仍然有效。

./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

(继续尝试在那里发送电子邮件......我认为这不会让我感到烦恼......)

./NAMESPACE

create之后:

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

document之后:

# Generated by roxygen2: do not edit by hand

export(reorderPopulation)

(无论如何,假设您使用roxygen2及其#' @export子句,或者您使用默认的“导出几乎所有内容”而不使用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

我添加此文件只是为了尝试“查找”此软件包中的一个导出函数。

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

根据?.onLoad

,我可以假设函数可用
  

请注意,'。onLoad'和'.onUnload'中的代码不应该假设   除基础包之外的任何包都在搜索路径上。   当前包中的对象将是可见的(除非是这样)   绕过),但应导入其他包中的对象   或者应该使用双冒号运算符。

构建并执行

我实际上是通过在目标目录中启动并运行:

创建的模板目录开始了这项工作
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

但是,您可以轻松地使用我上面提供的示例,并在不调用create的情况下继续前进。 (它还包括一些其他文件,例如./.gitignore./Porteous96.Rproj./.Rbuildignore,在此过程的其余部分中都不需要这些文件。如果您拥有它们并且它们没有-default值,可能很有用。)

从那里,我编辑/创建了上述文件,然后:

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

(你在上面和下面看到“什么都不做”的原因是我把它放在一个名为.onLoad的函数中,每次加载库时都会触发。这包括在devtools::document和{{1}期间}以及显而易见的devtools::install

其中一个副作用是使用适用的帮助文件创建library(Porteous96)目录。在这种情况下,单个文件./man/无需在此处显示。

reorderPopulation.Rd

为了更好的衡量,我关闭R并重新打开它。 (通常是不必要的。)

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

(同样,由于library(Porteous96) # do nothing ,这会被转储到控制台。)

.onLoad

层的总结

我猜这不能解决你的问题。它突出了我可以从你的问题中收集的内容。也许它提供了足够的框架,您可以在其中提及我的文件和您的文件之间的显着差异。虽然答案不适用于解决前的讨论,但我认为它有时是必要且有用的。

答案 1 :(得分:0)

在@ r2evans的帮助下,我找到了解决问题的方法。

我的main.r文件只是一堆函数调用,没有函数包装它们。所以我将函数调用包装在一个函数中,该函数现在看起来如下:

mainFunction <- function() {

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

    ... 
}

initSetup.r包含对我使用的其他文件的更多source()次调用。然后使用R控制台中的命令mainFunction()运行该程序