我正在使用Rstudio简化Sweave和R的数据分析,我将与其他分析师分享。为了使变量的编码变得清晰,有一个像帮助文件这样的东西会很好,所以他们可以调用?myData
并获得一个有用的文件,如果他们需要的话。我喜欢Rd降价并认为它实际上具有记录分析数据集的巨大潜力,包括总体摘要,通过变量分解的变量,以及如何运行一些探索性分析的示例。
如果你专门创建一个软件包,很容易做到这一点,但我认为它很混乱,因为软件包最终是一个函数集合,它们不集成Rnw文件。
我可以使用Roxygen2为不属于任何软件包的数据集创建帮助文件吗?
答案 0 :(得分:8)
在我解决这个问题之前,我想重申其他人所说的话。 R的包装系统正是您正在寻找的。许多人成功地使用它来分发数据而没有代码。结合R的数据延迟加载,您可以将大型数据集作为包分发,而不是负担不希望加载所有数据集的用户。
此外,除非您使用套餐,否则您将无法利用R&#39的帮助系统。原始问题明确询问使用?myData
,如果您不使用包,您的用户将无法执行此操作。这很简单地是R的基本帮助功能的限制。
现在,回答这个问题。您将需要使用一些非导出的roxygen函数来完成这项工作,但它并不太繁琐。此外,您需要将您的R文件记录到他们自己的某个文件夹中,在该文件夹中,您需要创建一个名为man
的空文件夹。
示例目录结构:
# ./
# ./man/
# ./myData.R
# ./otherData.R
myData.R
#' My dataset
#'
#' This is data I like.
#'
#' @name myData
NULL
otherData.R:
#' My other dataset
#'
#' This is another dataset I like
#'
#' @name otherData
NULL
现在,将所有内容组合在一起的代码(当然你可以将它包装在一个函数中):
library(roxygen2)
mydir <- "path/to/your/data/directory/"
myfiles <- c("myData.R","otherData.R")
# get parsed source into roxygen-friendly format
env <- new.env(parent = globalenv())
rfiles <- sapply(myfiles, function(f) file.path(mydir,f))
blocks <- unlist(lapply(rfiles, roxygen2:::parse_file, env=env), recursive=FALSE)
parsed <- list(env=env, blocks=blocks)
# parse roxygen comments into rd files and output then into the "./man" directory
roc <- roxygen2:::rd_roclet()
results <- roxygen2:::roc_process(roc, parsed, mydir)
roxygen2:::roc_output(roc, results, mydir, options=list(wrap=FALSE), check = FALSE)
您现在应该在一次空myData.Rd
文件夹中格式化otherData.Rd
和man
个文件。
答案 1 :(得分:2)
roxygen2现在本地支持此功能,但是,由于相关功能被标记为“内部”,因此它们不会显示在文档索引中。
仍然,这些函数已导出并成为正式API的一部分:
并且,要显示结果帮助,您将需要
工作流程如下:
source_env = roxygen2::env_file(sourcefile)
rd_blocks = roxygen2::parse_file(sourcefile, source_env)
help_topics = roxygen2::roclet_process(roxygen2::rd_roclet(), rd_blocks, source_env, dirname(sourcefile))
rd_code = lapply(help_topics, format)
这为您提供了文件中的帮助主题列表。要显示其中之一,您需要{tools}软件包,它是base R的一部分,但默认情况下未附加。
下面显示了如何显示文本帮助。显示HTML帮助更加复杂(我邀请您阅读和理解utils:::print.help_files_with_topic
的源代码,该源代码实际显示帮助主题,并且完全没有文档记录。。>
# Display first help topic. In reality you’d want to select a specific one.
topic = names(rd_code)[1L]
help_text = rd_code[[topic]]
rd = tools::parse_Rd(textConnection(help_text))
packagename = tools::file_path_sans_ext(basename(sourcefile))
helpfile = tools::Rd2txt(rd, out = tempfile('Rtxt'), package = packagename)
helptitle = gettextf('R Help on %s', sQuote(sub('\\.Rd$', '', topic)))
file.show(helpfile, title = helptitle, delete.file = TRUE)
答案 2 :(得分:0)
这是一种有效的hacky方法。在临时目录中创建一个虚拟包,使用它来生成Rd
个文件,然后提取Rd
个文件并清理。请参阅下面的代码。
希望这有帮助。
注意:请确保您要为其生成@export
个文件的函数中包含Rd
标记,以使其生效。
makeRd <- function(rscript, dir.out){
stopifnot(require(devtools))
# Prepare paths
pkg.path = tempdir()
r.path = file.path(pkg.path, 'R')
man.path = file.path(pkg.path, 'man')
desc.path = file.path(pkg.path, 'DESCRIPTION')
# Create directories
dir.create(r.path, F)
dir.create(man.path, F)
# Write dummy description
z = c('Package', 'Type', 'Title', 'Version', 'Date', 'Author', 'Maintainer', 'Description', 'Licence')
writeLines(paste0(z, ': X'), desc.path)
# Copy rscript file over to dummy package and generate rd files
file.copy(rscript, r.path)
suppressMessages( document(pkg.path) )
# Copy generated Rd files to output directory
f.in = list.files(man.path, full.names = T)
f.out = file.path(dir.out, basename(f.in))
for(i in 1:length(f.in)) file.copy(f.in[i], f.out[i], overwrite = T)
# Unlink
unlink(pkg.path, T, T)
return(f.out)
}
# Example
rd = makeRd(rscript='foo.R', dir.out='~/Desktop')
print(rd)
# [1] "~/Desktop/myFunction.Rd"
答案 3 :(得分:0)
parse_Rd
包中有一个名为tools
的函数。您可以生成.Rd文件,对它们运行parse_Rd
,并将输出保存为模块命名空间中的对象。您需要一个新的搜索功能(可能是modHelp
),在命名空间中找到相应的Rd对象,并使用Rd2text
或其他一个或自定义解决方案显示它。不确定你是否可以获得除Rd2text吐出的基本文本帮助以外的任何内容,但你可能会这样做。
答案 4 :(得分:0)
这里是@Konrad Rudolph的代码包装的通用函数,可用于为指定文件夹下的R脚本生成.Rd文件。对于使用具有“非标准”文件夹结构的模块软件包的项目,这可以是无需创建已安装软件包的文档解决方案。
moxygenise <- function(codepath, manpath) {
apply_at_level <- function(l, f, n, ...) {
## function to apply a function at specified level of a nested list
if (n < 0) {
stop("Invalid parameter - n should be integer >= 0 -- APPLY_AT_LEVEL")
} else if (n==0) {
return(l)
} else if (n == 1) {
return(lapply(l, f, ...))
} else {
return(lapply(l, function(x) {apply_at_level(x, f, n-1)}))
}
}
list.files.paths <- function(path, pattern) {
## function to list absolute path of all files under specified path matching certain pattern
path <- normalizePath(path)
return(file.path(path, list.files(path=path, pattern=pattern)))
}
sourcefiles <- list.files.paths(codepath, "\\.R$")
source_envs <- lapply(sourcefiles, roxygen2::env_file)
rd_blockss <- mapply(roxygen2::parse_file, sourcefiles, source_envs)
help_topicss <- mapply(function(rdblock, sourceenv, sourcefile) {
return(roxygen2::roclet_process(
roxygen2::rd_roclet(),
rdblock, sourceenv,
dirname(sourcefile)))},
rd_blockss, source_envs, sourcefiles)
rd_codes <- purrr::flatten(apply_at_level(help_topicss, format, 2))
mapply(function(text, topic, outpath=manpath) {
cat("Write", topic, "to", outpath, "\n")
write(text, file=file.path(outpath, topic))
}, rd_codes, names(rd_codes))
return(NULL)
}
指定保存模块源文件的路径以及要生成.Rd文件的路径(如果您希望帮助功能与源软件包一起使用,则应为projecthome / man /)
moxygenise('path/of/module/source/', 'path/of/output.Rds')
答案 5 :(得分:0)
另一种(更简单的)方法是使用 document
包:
> document::document("~/Downloads/tmp.R") #your temporal R file to convert to Rd
# it brings an error, but document are correctly built in a temporal directory
# (copy the path in below variable: tmppath)
> tmppath <- "/var/folders/dl/zj51mknn0x17lp376dpx_j3r0000gn/T//RtmpaikYJb/document_8e706d7cd54a/tmp/man"
> rstudioapi::previewRd(paste0(tmppath, "/tmp.Rd")) #to preview
答案 6 :(得分:-4)
我的回答是为什么你不把分析放在一个包中?通过这种方式,您可以获得软件包附带的所有支持,包括文档(数据和任何自编函数),以及具有自动知道数据所在位置(并且能够存在)的插图列出R-help中的晕影)。你想要一个包的功能,没有包,只是需要。相反,请选择包结构进行分析,并将其用于您的优势,例如记录数据集。
您评论包没有集成Rnw
文件,但我认为您错了。包vignettes
的默认格式是Rnw
或Sweave
文件。您可以轻松地选择小插图作为执行包的分析报告的方法。
我实际上在自己的分析中使用了这种方法,并在几篇博文中记录了它:why,how和comparison to project template。我也在两个学术分析项目中使用它(做得越来越多,不能指向一个例子)和个人项目(例如https://github.com/rmflight/timmysDensity,http://rmflight.github.io/posts/2013/06/timmysDensity.html,注意我还没有使用包机制来查找数据)。
顺便说一句,除了将数据放入一个包(其中只有数据包,Bioconductor有很多数据包)之外,我认为没有办法做你所要求的,除了只需在.R文件中提供原始roxygen2
标记,如上面针对数据集所述。