当我有多个函数来执行复合任务时,如何编写 R 包文档?

How Do I Write R Package Documentation When I Have More than One Function to Perform a Composite Task?

我有以下 R 函数,我想用它们来获取任何数字向量的总和、平方和和立方和:

功能更正

ss <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x, .combine = "+") %dopar% {i}
}
sss <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x, .combine = "+") %dopar% {i^2}
}

ssq <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x, .combine = "+") %dopar% {i^3}
}

我想生成向量的总和、向量的平方和以及同一向量的立方的总和。一旦我 运行 只有一个函数将包含在 R 包文档中,我希望它打印三个结果。

我知道如何通过记录 R 文件夹及其文件以及 DESCRIPTION 文件来为一项任务编写一个只有一个功能的 R 包,而 roxygen2devtools 为我完成剩下的工作.

我要

如果 x <- c(1, 2) 我想要这样的格式。

ss sss qss

3 5 9

只有包中的一个功能。

请说明您在输出中使用的向量。

有多种方法可以整合您的功能及其文档。

警告

因为您询问如何整合和记录您的现有功能,所以我没有改进您的功能。您选择如何实现 ss*() 功能由您决定。

力求与模块化编程的原则保持一致。 有责任确保您的每个功能都完成自己的工作,以便其他功能可以依赖它们。因此,有责任从源头上纠正任何错误。如果您这样做,那么更正将从您的辅助函数“冒泡”到您的包的其余部分——您将“一举两得”。

但是,就目前而言,您的代码存在一些值得注意的问题。

更正


更新

now, the question has been edited to correct the error below, according to my first suggestion. Also, the ** 开始,运算符已被明智地替换为 ^


你的函数实际上是平方和立方x 冗余:

sss <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x*x, .combine = "+") %dopar% {i**2}
  #                     ^^                            ^^^
  #            First time squaring.          Second time squaring.
}


ssq <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x*x*x, .combine = "+") %dopar% {i**3}
  #                     ^^^^                            ^^^
  #             First time cubing.              Second time cubing.
}

结果是sss()实际用的是4次方(不是2次方),而ssq()用的是9次方(不是3次方):

sss(x = c(1,2))
# [1] 17

ssq(x = c(1,2))
# [1] 513

您必须或者避免将x乘以自身

sss <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x, .combine = "+") %dopar% {i**2}
  #                    ^
  #                Corrected
}


ssq <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x, .combine = "+") %dopar% {i**3}
  #                    ^
  #                Corrected
}

删除%dopar% {i

后的**2**3
sss <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x*x, .combine = "+") %dopar% {i}
  #                                                  ^
  #                                              Corrected
}


ssq <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x*x*x, .combine = "+") %dopar% {i}
  #                                                    ^
  #                                                Corrected
}

得到output you intended:

sss(x = c(1,2))
# [1] 5

ssq(x = c(1,2))
# [1] 9

备注

第一次更正更具扩展性,因为

  foreach::foreach(i = x, .combine = "+") %dopar% {i**10}

更短
  foreach::foreach(i = x*x*x*x*x*x*x*x*x*x, .combine = "+") %dopar% {i}

更高的权力,如 10

改进

坦率地说,您的代码对于如此简单的操作来说非常复杂。如果您实际上 需要 自定义函数 — 并且每个总和有一个单独的函数 — 您可以使用 base R:

ss <- function(x){
  sum(x)
}

sss <- function(x){
  sum(x^2)
}

ssq <- function(x){
  sum(x^3)
}

综合文档

根据 R documentation 对于...嗯...记录 R,您可以在同一 .Rd 文档中描述几个相关函数。

例子

考虑如何将 base::nrow()ncol 等相关函数一起记录:

Description

nrow and ncol return the number of rows or columns present in x. NCOL and NROW do the same treating a vector as 1-column matrix, even a 0-length vector, compatibly with as.matrix() or cbind(), see the example.

Usage

nrow(x)
ncol(x)
NCOL(x)
NROW(x)

Arguments

x

a vector, array, data frame, or NULL.

申请

您可能希望在同一页面上一起记录 ss()sss()ssq()。这可以通过 roxygen2、使用 @describeIn 标签

来完成
#' Obtain the sum.
#  ⋮
#' @param x A vector of \code{numeric} values.
#  ⋮
ss <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x, .combine = "+") %dopar% {i}
}

#' @describeIn ss Obtain the sum of squares.
sss <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x, .combine = "+") %dopar% {i**2}
}

#' @describeIn ss Obtain the sum of cubes.
ssq <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x, .combine = "+") %dopar% {i**3}
}

或者使用 @rdname 标签:

#' Obtain the sums of various powers: \code{ss} for original values, \code{sss} for their squares, and \code{ssq} for their cubes.
#  ⋮
#' @param x A vector of \code{numeric} values.
#  ⋮
ss <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x, .combine = "+") %dopar% {i}
}

#' @rdname ss
sss <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x, .combine = "+") %dopar% {i**2}
}

#' @rdname ss
ssq <- function(x){
  `%dopar%` <- foreach::`%dopar%`
  foreach::foreach(i = x, .combine = "+") %dopar% {i**3}
}

合并函数

您可能想要“整理”您的 @exported 函数集。

使用现有功能

一方面,您可以创建一个新函数 one_sum() 来包装您现有的函数;其中 one_sum() 将是 @exported 函数:

#' Obtain the sum of any available power.
#  ⋮
#' @param x A vector of \code{numeric} values.
#' @param mode \code{character}. The approach to use when summing: \code{"ss"} to sum the values themselves; \code{"sss"} to sum their squares; and \code{"ssq"} to sum their cubes.
#  ⋮
#' @export
#  ⋮
one_sum <- function(x, mode = c("ss", "sss", "ssq")) {
  if(mode == "ss") {
    ss(x)
  } else if(mode == "sss") {
    sss(x)
  } else if(mode == "ssq") {
    ssq(x)
  } else {
    stop("'mode' must be one of \"ss\", \"sss\", or \"ssq\".")
  }
}

可扩展

另一方面,您可以用单个函数any_sum()替换所有内容,它有另一个参数power作为用于计算总和:

#' Obtain the sum of any power.
#  ⋮
#' @param x A vector of \code{numeric} values.
#' @param power \code{numeric}. The power to which the addends in \code{x} should be raised.
#  ⋮
any_sum <- function(x, power) {
  sum(x^power)
}

合并输出

实现您指定的特定输出

I want

ss sss qss
30 300 90000

with just a function from the package.

您可以利用现有功能或创建全新功能。

使用现有功能

一方面,您可以在新的 three_sums() 功能中利用现有功能;其中 three_sums() 将是 @exported 函数:

#' Obtain at once the sums of the three available powers.
#  ⋮
#' @param x A vector of \code{numeric} values.
#  ⋮
#' @export
three_sums <- function(x) {
  setnames(c(ss(x), sss(x), ssq(x)), c("ss", "sss", "qss"))
}

可扩展

另一方面,您可以将所有内容替换为单个函数all_sums(),该函数具有另一个参数powers作为用于计算的不同幂总和。

#' Obtain at once the sums of all given powers.
#  ⋮
#' @param x A vector of \code{numeric} values, to raise to powers and add.
#' @param powers A vector of \code{numeric} values: the powers to which the addends will be raised.
#  ⋮
all_sums <- function(x, powers = 1:3) {
  setNames(object = sapply(X = powers,
                           FUN = function(n){sum(x^n)},
                           simplify = TRUE),
           nm = powers)
}

在这里,您可以指定要查看其总和的每一个幂。比如下面的调用

all_sums(x = c(1, 2), powers = c(3, 4, 6, 9))

将为您提供立方总和(3次方)、4次方、6次方和9次方;全部用于向量 c(1, 2):

中的值
  3   4   6   9 
  9  17  65 513 

备注

未指定powers时,则默认

all_sums(x = c(1, 2))

将使用 1st、2nd(平方)和 3rd(立方)次方

  1  2  3 
  3  5  9 

如您在示例输出中所希望的那样。

编辑:我更改了代码,以便输出是向量而不是列表。

您可以将多个函数合并为一个函数。这是一个例子:

sums <- function(x, methods = c("sum", "squaredsum", "cubedsum")){
  
  output <- c()
  
  if("sum" %in% methods){
    output <- c(output, ss = ss(x))
  }
  
  if("squaredsum" %in% methods){
    output <- c(output, sss = sss(x))
  }
  
  if("cubedsum" %in% methods){
    output <- c(output, ssq = ssq(x))
  }
  
  return(output)
}

默认情况下,您的所有三个函数都会被调用,结果会return在一个列表中。

您可以只指定一个或多个函数,在这种情况下,它只会 return 被调用函数的输出。

在您的文档中,您现在可以将每个可能的方法视为可以设置的变量。'

编辑

你的 cube 函数有错误。 i***2 未使用立方体。是 i**3。正确的函数是:

ssq <- function(x){
`%dopar%` <- foreach::`%dopar%`
foreach::foreach(i = x*x*x, .combine = "+") %dopar% {i**3}
}