2

我有以下 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 程序包,而其余的roxygen2则为devtools我完成。

我想

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

ssssssssssssssssssssssssssssssssssss

3 5 9

仅包含软件包中的一个功能。

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

4

2 回答 2

6

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

警告

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

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

但是,就目前而言,您的代码存在一些明显的问题。

更正


更新

截至目前,根据我的第一个建议,该问题已被编辑以更正以下错误。此外,**运算符已明智地替换为^.


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
}

删除**2and **3after%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
}

得到你想要的输出

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

改进

坦率地说,对于这种简单的操作,您的代码非常复杂。如果你真的需要自定义函数——并且每个总和都有一个单独的函数——你可以用baseR 来做到这一点:

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

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

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

综合文件

根据...以及...记录 R 的R 文档,您可以在同一.Rd文档中描述多个相关功能。

例子

考虑如何base::nrow()与相关功能一起记录,例如ncol

描述

nrowncol返回 中存在的行数或列数xNCOL并将NROW向量视为 1 列矩阵,甚至是长度为 0 的向量,与as.matrix()or兼容cbind(),请参见示例。

用法

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

论据

x

向量、数组、数据框或NULL.

⋮</p>

应用

您可能希望在同一页面上同时记录 、 和所有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()来包装现有函数;whereone_sum()将是唯一 @export的ed 函数:

#' 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)
}

合并输出

实现您指定的特定输出

我想

ss sss qss
30 300 90000

仅包含软件包中的一个功能。

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

使用现有功能

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

#' 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))

会给你立方(3rd powers)、4th powers、6th powers 和9th powers 的总和;全部用于向量中的值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 

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

于 2021-07-23T14:15:17.763 回答
1

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

您可以将您的功能组合成一个功能。这是一个例子:

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)
}

默认情况下,所有三个函数都会被调用,结果会以列表的形式返回。

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

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

编辑

您的多维数据集函数有错误。立方体没有被i***2. 是i**3。正确的功能是:

ssq <- function(x){
`%dopar%` <- foreach::`%dopar%`
foreach::foreach(i = x*x*x, .combine = "+") %dopar% {i**3}
}
于 2021-07-23T14:30:12.543 回答