可以(应该)我继承R中函数的一部分吗?

Mat*_*ert 4 oop r

我有两个相似的功能.因此,我想知道这是否适合在R中继承遗产.

firstfunc <- function(table,pattern="^Variable") {

dframe <- get(table)
cn <- colnames(get(table))
qs <- subset(cn, cn  %in% grep(pattern, cn, value=TRUE))

    .....

}

secondfunc <- function(table,pattern="^stat"){

dframe <- get(table)
cn <- colnames(get(table))
qs <- subset(cn, cn  %in% grep(pattern, cn, value=TRUE))

    ....

}
Run Code Online (Sandbox Code Playgroud)

将有两个以上的功能和两个模式.我的表包含很多变量,可以按名称轻松分组,这就是我使用这些模式识别的原因.它到目前为止运作良好,而且这些几行的c&p并不是那么费力.但是,将这些行写入一个函数/方法并让其他函数/方法继承是否合理?

我在R中阅读OO的大部分帮助到目前为止都使用了为数据分配属性然后使用泛型函数的示例.不幸的是,我还不明白这是否也可以帮助我.

对于任何建议的Thx,指向一个好头的指针首先开始这个!

Vit*_*hKa 13

R中没有函数部分的继承.你不能从其他函数"继承部分"函数,只能从其他函数调用函数.R中的所有OO范例(S3,S4,refClasses)正是他们所说的,面向对象的.根据接收的对象类别调度方法.

你的问题是如何摆脱代码重复.

有两种方式,一种是标准,另一种不是标准.

  • 标准方式:为重复代码编写函数,并从其他函数调用它们.缺点是函数只返回一个对象,但你有三个.所以你可以这样做:

    repeated_code <- function(table, pattern){
        objects <- list()
        objects$dframe <- get(table)           
        objects$cn <- colnames(get(table))
        objects$qs <- subset(cn, cn  %in% grep(pattern, cn, value=TRUE))
        }
    
    
    firstfunc <- function(table,pattern="^Variable") {
          objects <- repeated_code(table, pattern)
          ...
          manipulate objects
          ...
          }
    
    
    secondfunc <- function(table,pattern="^Variable") {
          objects <- repeated_code(table, pattern)
          ...
          manipulate objects
          ...
          }     
    
    Run Code Online (Sandbox Code Playgroud)
  • 不那么标准的方式: 使用未评估的表达式:

     redundant_code <- expression({
          dframe <- get(table)  
          cn <- colnames(get(table))
          qs <- subset(cn, cn  %in% grep(pattern, cn, value=TRUE))
     })
    
    
     firstfunc <- function(table,pattern="^Variable") {
         eval(redundant_code, envir=parent.frame())
         ...
     }
    
    
     secondfunc <- function(table,pattern="^Variable") {
         eval(redundant_code, envir=parent.frame())
         ...
     }
    
    Run Code Online (Sandbox Code Playgroud)

[更新:由于R 2.12.0还有另一种多分配方式.编写一个返回对象列表的函数(如上面的"标准"情况).然后将返回列表中的对象分配给当前的evnvironmnet list2env:

    secondfunc <- function(table,pattern="^Variable") {
          objects <- repeated_code(table, pattern)
          list2env(objects, envir = parent.frame())
          ...
          }     
Run Code Online (Sandbox Code Playgroud)

]

  • 为“list2env”的提示干杯。很有意思。 (2认同)

Sha*_*ane 6

你能? 是. S4具有处理此方案的功能.有关一些资源,请参阅Wiki页面.Hadley最近也写了一篇很好的介绍(参见"通用函数和方法"一节).

您可以setMethod在任何现有S4代码中看到这一点(参见timeSeries示例).请注意同一功能的不同签名.

你应该? 是的,你应该,但是你会为代码增加一些复杂性. S4不是免费的; 它需要更多的基础设施.所以有一个权衡,你需要决定它是否值得.