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

Dan*_*mes 2 r package-development r-package

我有以下 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}
}
Run Code Online (Sandbox Code Playgroud)

我想产生向量的总和,向量的平方和和相同向量的立方的总和。我希望它在我只运行一个函数时打印三个结果,并将包含在 R 包文档中。

我知道如何通过记录将R文件夹及其文件,并说明文件,而只用一个函数编写的R包只有一个任务,roxygen2devtools我做休息。

我想要

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

ss sss sss

3 5 9

只用包中的一个函数。

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

Gre*_*reg 6

There are several ways to consolidate your functionality and its documentation.

Warning

Because you asked how to consolidate and document your existing functions, I have not improved your functions. How you choose to implement your ss*() functions is up to you.

Strive to be consistent with the principles of modular programming. It is your responsibility to ensure that each of your functions does its own job, so that other functions can rely on them. So it is your responsibility to correct any errors at their source. If you do so, then the corrections will "bubble up" from your helper functions into the rest of your package—you will "kill two bugs with one stone".

As it stands, however, there are some noticeable issues with your code.

Correction


Update

As of now, the question has been edited to correct the error below, according to my first suggestion. Also, the ** operator has been wisely replaced with ^.


Your functions actually square and cube x redundantly:

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.
}
Run Code Online (Sandbox Code Playgroud)

The result is that sss() actually uses the 4th (not the 2nd) power, and ssq() uses the 9th (not the 3rd) power:

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

ssq(x = c(1,2))
# [1] 513
Run Code Online (Sandbox Code Playgroud)

You must either avoid multiplying x by itself

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
}
Run Code Online (Sandbox Code Playgroud)

or remove the **2 and **3 after %dopar% {i

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
}
Run Code Online (Sandbox Code Playgroud)

to get the output you intended:

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

ssq(x = c(1,2))
# [1] 9
Run Code Online (Sandbox Code Playgroud)

Note

The first correction is more extensible, since

  foreach::foreach(i = x, .combine = "+") %dopar% {i**10}
Run Code Online (Sandbox Code Playgroud)

is shorter to type than

  foreach::foreach(i = x*x*x*x*x*x*x*x*x*x, .combine = "+") %dopar% {i}
Run Code Online (Sandbox Code Playgroud)

for higher powers like 10.

Improvement

Frankly, your code is very convoluted for such simple operations. If you actually need custom functions at all — and a separate function for each sum — you could just do this with base R:

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

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

ssq <- function(x){
  sum(x^3)
}
Run Code Online (Sandbox Code Playgroud)

Consolidated Documentation

Per the R documentation for...well...documenting R, you can describe several related functions within the same .Rd document.

Example

Consider how base::nrow() is documented together with related functions like 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)
Run Code Online (Sandbox Code Playgroud)

Arguments

x

a vector, array, data frame, or NULL.

?

Application

You might want to document ss(), sss(), and ssq() all together, on the same page. This can be done via roxygen2, by using the @describeIn tag

#' 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}
}
Run Code Online (Sandbox Code Playgroud)

or alternatively by using the @rdname tag:

#' 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}
}
Run Code Online (Sandbox Code Playgroud)

Consolidated Function

You might want to "declutter" your set of @exported functions.

Using Existing Functionality

On the one hand, you could create a new function one_sum() to wrap your existing functions; where one_sum() will be the only @exported function:

#' 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\".")
  }
}
Run Code Online (Sandbox Code Playgroud)

Extensibly

On the other hand, you could replace everything with a single function any_sum(), which has another parameter power as the power used to compute the sum:

#' 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)
}
Run Code Online (Sandbox Code Playgroud)

Consolidated Output

To achieve the particular output you specified

I want

ss sss qss
30 300 90000
Run Code Online (Sandbox Code Playgroud)

with just a function from the package.

you can either exploit your existing functions or create an entirely new function.

Using Existing Functionality

On the one hand, you can leverage your existing functions in a new three_sums() function; where three_sums() will be the only @exported function:

#' 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"))
}
Run Code Online (Sandbox Code Playgroud)

Extensibly

On the other hand, you could replace everything with a single function all_sums(), which has another parameter powers as the different powers used for computing the sums.

#' 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)
}
Run Code Online (Sandbox Code Playgroud)

Here, you can specify each and every power, whose sum you want to see. For example, the following call

all_sums(x = c(1, 2), powers = c(3, 4, 6, 9))
Run Code Online (Sandbox Code Playgroud)

will give you the sum of cubes (3rd powers), of 4th powers, of 6th powers, and of 9th powers; all for the values in the vector c(1, 2):

  3   4   6   9 
  9  17  65 513 
Run Code Online (Sandbox Code Playgroud)

Note

When powers is unspecified, then by default

all_sums(x = c(1, 2))
Run Code Online (Sandbox Code Playgroud)

will use the 1st, 2nd (square), and 3rd (cubic) powers

  1  2  3 
  3  5  9 
Run Code Online (Sandbox Code Playgroud)

as you desired in your sample output.