省略号参数— 可变长参数

省略号参数— 可变长参数

​ 在R中我们查看别人的函数或者内部函数,经常用到这种参数,...也称把可变长参数,今天就来聊一聊中方法的使用。

1.捕获省略号中的内容

先看一个例子:构造一个函数然后对所有的参数进行相加求和。

addemup <- function(x, ...){
   args <- list(...)# 推荐把省略号的内容分配给list,然后在对该list进行操作
   for (a in args){
                x <- x + a 
   } 
   x
 }

addemup(1,1)
#> [1] 2
addemup(1,2,3,4,5)
#> [1] 15

我们还可以通过..1,..2..9等直接引用列表中的内容。..1表示第一项,..2表示第二项,以此类推

对list操作可以结合purrr包中的map, reduce, accumulate和基础函数do.call等 操作更方便。一个实际的例子,

DGM_U = function(...){
  #######  第一部分是对参数的检查 #####################
  # 输入的参数为U_{k},U_{k}代表一个完整的区间乘积互反判断矩阵。
  n = nrow(..1)
  m = ncol(..1)
  args <- list(...)
  stopifnot( length(args) >=2, all( map_lgl(args,is.matrix)),2*n ==m )
  # 检查所有的矩阵维度是否一样
  library(purrr)
  t = map(args,dim) %>% do.call(rbind, .) 
  stopifnot( nrow(unique(t)) == 1)
  
  ####### 第二部分 对参数的操作,达到想要的目的###########
  ## 1. 使用快捷的函数
  k = 1 / length(args)
  UB = reduce( map(args,function(x)fenjie(x)$B),`*`)^k
  UD = reduce( map(args, function(x)fenjie(x)$D), `*`)^k
  
  ## 2. 使用循环操作 -- 对比操作
  # UB = matrix(1,nrow = n, ncol = n)
  # UD = matrix(1,nrow = n, ncol = n)
  # for(xx in args){
  #   B = fenjie(xx)$B
  #   D = fenjie(xx)$D
  #   for(i in 1:n){
  #     for(j in 1:n){
  #       UB[i,j] = UB[i,j] * B[i,j]
  #       UD[i,j] = UD[i,j] * D[i,j]
  #     }
  #   }
  # }
  # k = 1 / length(args)
  # UB = UB^( k)
  # UD = UD^(k)
  return( hecheng(UB,UD))
}
# 由于该函数引用了部分其他函数,故这里不能运行
DGM_U(U_t1,U_t2,U_t3)

2. 用省略号传递给图形参数

我们知道R中的图形参数是有很多的,可以把它传递给图形参数。

nicePlot = function(X,Y,...){
  xlabel = deparse(substitute(X)) # 捕获X的输入
  ylabel = deparse(substitute(Y)) # 捕获Y的输入
  
  plot(X,Y,type ='o',
      xlab = xlabel,ylab = ylabel,main = paste(xlabel,ylabel,sep = '--'),
      ...)
}

Date = 1:7
Sales = c(100,120,150,130,160,210,120)
nicePlot(Date,Sales,col='red')

其中substitute()函数捕获输入的内容(无论输入什么样的内容,则原样输出),deparse() 函数将其转变为字符串

3. 将省略号与其他参数结合

v <- c(sqrt(1:100))
f <- function(x, ...) { 
   print(x); 
   summary(...)
  }
f("Here is the summary for v.", v, digits=2)
#> [1] "Here is the summary for v."
#>    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
#>     1.0     5.1     7.1     6.7     8.7    10.0

4. 也可对省略号取名称

实际上,参数本身的值不是通过省略号参数传递的唯一信息。也可以使用参数的名称(如果指定),例如:

f <- function(...) {
  names(list(...))
  
   # 进一步的分析
}

f(some_number = 123,some_string ='abc',some_missing_value = NA)
#> [1] "some_number"        "some_string"        "some_missing_value"

5. 将省略号参数解压缩为本地函数变量(甚至是全局变量)

rm(list = ls())
f <- function(...) {
  args <- list(...)
  for( i in 1:length(args) ){ 
    assign( x = names(args)[i],value = args[[i]] )
  }
  ls()#显示可用的变量 #使用省略号参数作为当前变量进行进一步操作
  
  # 进一步的分析
}

f( some_number = 123,some_string ="abc")
#> [1] "args"        "i"           "some_number" "some_string"
sessionInfo()
#> R version 4.0.2 (2020-06-22)
#> Platform: x86_64-apple-darwin17.0 (64-bit)
#> Running under: macOS Mojave 10.14.5
#> 
#> Matrix products: default
#> BLAS:   /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRblas.dylib
#> LAPACK: /Library/Frameworks/R.framework/Versions/4.0/Resources/lib/libRlapack.dylib
#> 
#> locale:
#> [1] zh_CN.UTF-8/zh_CN.UTF-8/zh_CN.UTF-8/C/zh_CN.UTF-8/zh_CN.UTF-8
#> 
#> attached base packages:
#> [1] stats     graphics  grDevices utils     datasets  methods   base     
#> 
#> loaded via a namespace (and not attached):
#>  [1] compiler_4.0.2  magrittr_1.5    bookdown_0.20   tools_4.0.2    
#>  [5] htmltools_0.5.0 yaml_2.2.1      stringi_1.4.6   rmarkdown_2.3  
#>  [9] blogdown_0.20   knitr_1.29      stringr_1.4.0   digest_0.6.25  
#> [13] xfun_0.17       rlang_0.4.7     evaluate_0.14

次;