使用S3方法将参数捆绑到R中的数据帧中

使用S3方法将参数捆绑到R中的数据帧中,r,generics,r-s3,R,Generics,R S3,我创建了一个函数,它有相当多的参数(所有向量的长度都相同),我认为将参数捆绑在一个数据帧中会更容易。我已经设法用S3方法实现了这一点,但是读了更多关于S3方法的内容,我开始怀疑我编写函数的方式是否有点滥用S3约定 我想知道我所做的是不是一个坏主意。如果是的话,我们欢迎其他的方法 以下是我所做工作的简化示例: myfunc <- function(x, ...) UseMethod("myfunc") myfunc.default(time, money, age, weight) {

我创建了一个函数,它有相当多的参数(所有向量的长度都相同),我认为将参数捆绑在一个数据帧中会更容易。我已经设法用S3方法实现了这一点,但是读了更多关于S3方法的内容,我开始怀疑我编写函数的方式是否有点滥用S3约定

我想知道我所做的是不是一个坏主意。如果是的话,我们欢迎其他的方法

以下是我所做工作的简化示例:

myfunc <- function(x, ...) UseMethod("myfunc")

myfunc.default(time, money, age, weight) {
   # a silly calculation
   return(money/(age + weight) - time)
}

myfunc.data.frame <- function(params, ...) {
  names(params) <- tolower(names(params))
  pass.args <- intersect(names(params), names(formals(myfunc.default)))
  res <- do.call(myfunc.default, c(params[pass.args], ...))
  return(res)
}

myfunc谢谢您的评论。我认为我在这里使用S3方法的策略是个坏主意。我已经切换到两个功能,例如
myfunc
myfunc\u df
。我还创建了一个helper函数,用于将具有单个参数的函数转换为接受数据帧的函数:

df_call <- function(.function, .parameters, .case=tolower, ...) {
  try(names(.parameters) <- match.fun(.case)(names(.parameters)))
  pass.args <- intersect(names(.parameters), names(formals(.function)))
  do.call(.function, c(.parameters[pass.args], list(...)))
}

df_调用您是否有另一类对象要传递给
myfunc
?换句话说,您是否看到要使用
myfunc.newobject()
的场景?如果不需要,则不需要S3方法和类。另外,您的
myfunc.data.frame
将无法通过
R CMD检查
,因此至少您没有正确使用S3方法。我猜想你完全可以做你上面做的事情,而不需要使用任何方法。我只设想了两种情况:传递一个数据帧
myfunc(mydata)
或传递这个单独的变量:
myfunc(年龄=c(20,40,25),体重=c(65,88,58),…)
等等。我可以有两个函数,
myfunc
myfunc_df
但认为如果他们两个名字相同,生活会更轻松。请注意,在实际版本中,默认函数的所有参数都有默认值,所以在实践中很容易使用,除非您想设置很多参数。这对我来说是个坏主意。正如我所说,您的函数不会通过
R CMD check
,因为您在泛型和方法中没有相同的参数。我倾向于使用相同的想法,但是要有一个
switch()
if()
作为检查输入类型的第一个语句。或者至少清理泛型-可能通过将
列表
传递给默认方法,而不是向量。(顺便说一句,你在代码中有一些聪明的想法!)谢谢安德里。我确实有一种潜在的感觉,那就是这是个坏主意。仔细想想,当我传递向量时,我想我总是很乐意命名参数,所以最好的办法是使用一个如下所示的函数:
myfunc