我所在的组织拥有许多内部 R 包,这些包都是多年前编写的。这些文件存储为.zip在 R 3.x 下的 Windows 上构建的存档。它们无法在不重新构建的情况下加载到 Linux 或 macOS 或 R 4.y 下。不幸的是,我无权访问包源。他们输给了时间……
我想获取这些二进制文件,提取源代码,并根据当前的最佳实践(版本控制、roxygen2、testthat等)重新打包它。最好的方法是什么?
我已经通过以下方式解决了其中一个二进制文件:
.R文件。.R文件中,以便重现浏览器中显示的帮助页面。我部分陷入(1),因为某些功能是 S4 通用的。dput(<name>)给出new("standardGeneric", ...)而不是简单的function定义。否则,这个过程相当简单,但非常耗时。
有没有办法以编程方式从 R 包二进制文件“反向工程”源文件,同时正确处理 S4 通用函数、类和方法?
在这个问题得到解决之前,组织中的每个人都将停留在 R 3.6 上。
检查这是否适用于R 3.6.
下面的脚本可以通过将所有函数源写入单独且适当命名的文件中来自动解决问题的至少一部分.R。该代码还将处理隐藏函数。
# Use your package name
package_name <- "dplyr"
# Extract all method names, including hidden
nms <- paste(lsf.str(paste0("package:", package_name), all.names = TRUE))
# Loop through the method names,
# extract head and body, and write them to R files
for (i in 1:length(nms)) {
# Extract name
nm <- nms[i]
# Extract head
hd_raw <- capture.output(args(nms[i]))
# Collapse raw output, but drop trailing NULL
hd <- paste0(hd_raw[-length(hd_raw)], collapse = "\n")
# Extract body, collapse
bd <- paste0(capture.output(body(nms[i])), collapse = "\n")
# Write all to file
write(paste0(hd, bd), file = paste0(nm, ".R"))
}
Run Code Online (Sandbox Code Playgroud)
要以类似的方式提取函数的帮助文本,您可以使用以下答案中的代码:
起点可能是这样的:
library(tools)
package_name <- "dplyr"
db <- Rd_db(package_name)
# Extract all method names, including hidden
nms <- paste(lsf.str(paste0("package:", package_name), all.names = TRUE))
# Loop through the method names,
# extract Rd contents if they exist in this namespace,
# and write them to new Rd files
for (i in 1:length(nms)) {
# Extract name
nm <- nms[i]
rd_raw <- db[names(db) %in% paste0(nm, ".Rd")]
if (length(rd_raw) > 0) {
rd <- paste0(capture.output(rd_raw), collapse = "\n")
# Write all to file
write(rd, file = paste0(nm, ".Rd"))
}
}
Run Code Online (Sandbox Code Playgroud)