在R中高效地打包和解包函数参数

3

我有一些R代码,我的函数参数越来越多,像这样:

f<-function(a,b,c,d,e,f,g,...){
  #do stuff with a,b,c,d,e,f,g
  return(list(q=q,r=r,s=s,...))
}

我在考虑将参数折叠成相关参数的列表,然后从函数内部提取出这些参数。但是这很麻烦,因为我必须使用大量的样板代码。

list_of_params<-list(a=a,b=b,...)
f<-function(list_of_params){
  a<-list_of_params[["a"]]
  b<-list_of_params[["b"]]
  c<-list_of_params[["c"]]
  ...
  #do stuff with a,b,c,...
  return(list(q=q,r=r,s=s,...))
}

我在考虑使用类似list2env的东西将变量自动从列表中提取到函数的环境中。有没有人对这种方法是否合理有意见?我在某个地方读到使用assign是一个坏主意,这似乎类似。我提议的函数看起来像这样:

f<-function(list_of_params){
  list2env(list_of_params, envir=as.environment(-1)) #-1 means current environment
  #do stuff with a,b,c...
  return(list(q=q,r=r,s=s,...))
}

我以前从未使用过assign()list2env()。我担心它们可能像attach()一样具有危险的陷阱,需要注意。在这里使用list2env()是否合适?如果不是,那么什么是此函数的适当用法?


4
为什么你需要这么多参数?请简化一下。 - Rich Scriven
我同意Richard的观点。你真的需要在一个函数中对所有这些参数都做些什么吗?似乎你应该编写接受列表作为参数并且只对少数列表组件进行一两个快速处理的小函数。想象一下lm对象的工作方式-它只是一个列表,但当我在其上使用predictsummary时,我不想逐个传入组件...我只需传入模型对象(也就是列表)。 - Gregor Thomas
3
我同意Gregor的观点,如果没有上下文的情况下,回答这个问题会非常宽泛和困难。 - rawr
1
我认为assign更多的是“常见误用”,而不是“险恶陷阱”。当人们使用assign()来构造变量名时,意味着他们应该使用列表。当人们使用assign()从函数中删除全局环境中的内容时,意味着他们应该从函数中返回对象。 - Gregor Thomas
6
我同意rawr赞同Gregor赞同我。 - Rich Scriven
显示剩余6条评论
1个回答

0
一个很长的参数列表可能是代码异味。 最简单的方法是停下来,思考应该封装哪种类型的对象来包含您的参数。它可能不仅仅是一个简单的列表。
另一个选择是,如果许多函数参数在过程或词法范围方面被固定。那么你可以利用functions are R are closures这个事实。例如:
make_f <- function(object, params){
   e <- calculate_e(object, params)
   f <- calculate_f(object, params)
   g <- calculate_g(object, params)
   f<-function(a,b,c,d,...){
        #do stuff with a,b,c,d,e,f,g
        return(list(q=q,r=r,s=s,...))
   }
   return(f)
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接