19

我正在使用 Rstudio 简化 Sweave 和 R 进行数据分析,我将与其他分析师分享。为了使变量的编码非常清晰,最好有一个帮助文件,这样他们可以?myData在需要时调用并获得一个有用的文件。我喜欢 Rd 降价,并认为它实际上具有记录分析数据集的巨大潜力,包括总体摘要、按变量细分的变量以及如何运行一些探索性分析的示例。

如果您专门创建一个包,这样做很容易,但我认为这很令人困惑,因为包最终是函数的集合,并且它们不集成 Rnw 文件。

我可以使用 Roxygen2 为不属于任何包的数据集创建帮助文件吗?

4

7 回答 7

13

在我对此进行破解之前,我想重申其他人所说的话。R 的包系统实际上正是您正在寻找的。许多人成功地使用它来分发数据而不分发代码。结合 R 的数据延迟加载,您可以将大型数据集作为包分发,而不会给不想全部加载的用户带来负担。

此外,除非您使用包,否则您将无法利用 R 的帮助系统。原始问题明确询问有关使用的问题?myData,如果您不使用包,您的用户将无法这样做。这只是 R 的基本帮助功能的一个限制。


现在,来回答这个问题。您将需要使用一些非导出的 roxygen 函数来完成这项工作,但这并不太繁重。此外,您需要将记录数据的 R 文件放入他们自己的某个文件夹中,并在该文件夹中创建一个名为man.

示例目录结构:

# ./
# ./man/
# ./myData.R
# ./otherData.R

我的数据

#' My dataset
#' 
#' This is data I like.
#' 
#' @name myData
NULL

其他数据.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.Rdman

于 2014-08-13T16:19:44.817 回答
7

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} 包,它是基础 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)
于 2019-09-18T10:07:38.597 回答
1

这是从@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')
于 2019-11-27T15:13:58.323 回答
1

另一种(更简单)的方法是使用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 
于 2021-06-03T12:02:13.833 回答
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"
于 2014-08-13T15:40:12.050 回答
0

parse_Rd包中有一个函数调用tools。您可以生成 .Rd 文件,parse_Rd在它们上运行,并将输出保存为模块命名空间中的对象。您将需要一个新的搜索功能(也许modHelp),在命名空间中找到适当的 Rd 对象并使用Rd2text或不同的对象或自定义解决方案显示它。不确定除了 Rd2text 吐出的基本文本帮助之外,您是否可以获得任何其他内容,但您可能会。

于 2014-08-13T17:01:03.357 回答
-4

我的回答是你为什么不把分析放在一个包里?通过这种方式,您可以获得软件包附带的所有点点滴滴的支持,包括文档(数据和任何自编写的函数),以及自动知道数据所在位置的小插图(并能够从 R 中列出小插图-帮助)。你想要一个包的功能,没有一个包,那只是需要。相反,选择包结构进行分析,并利用它来发挥你的优势,比如记录你的数据集。

您评论说软件包不集成Rnw文件,但我认为您错了。包的默认格式vignettesRnworSweave文件。您可以轻松地选择小插图作为进行包装分析报告的一种方式。

我实际上在自己的分析中使用了这种方法,并在几篇博客文章中记录了它:为什么如何与项目模板的比较。我还在学术分析项目(越来越多,还不能指向示例)和个人项目(例如https://github.com/rmflight/timmysDensityhttp://rmflight .github.io/posts/2013/06/timmysDensity.html,注意我还没有使用包机制来查找数据)。

顺便说一句,除了将数据放入一个包(只有数据包,Bioconductor有很多)之外,我认为除了简单地roxygen2在.R 文件,如上所述用于数据集。

于 2014-08-13T15:21:53.383 回答