微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

R:如何在 S3 类中使用和扩展 data.table

如何解决R:如何在 S3 类中使用和扩展 data.table

我想创建一个 S3 类,该类通过添加将由该类的其他方法使用的属性来扩展 data.table。在下面的示例中,我添加一个属性 colMeas,其中包含带有度量的列的名称

library(data.table)

myclass <- function(dt,colMeas) {

  stopifnot(data.table::is.data.table(dt))

  data.table::setattr(dt,"colMeas",colMeas)
  data.table::setattr(dt,"class",union("myclass",class(dt)))

}

is.myclass <- function(obj) inherits(obj,"myclass")

我有一个修改现有测量列的方法

modCol <- function(obj,arg) {
  UseMethod("modCol")
}

# Modify the existing column
modCol.myclass <- function(obj,arg) {

  stopifnot(is.myclass(obj))
  stopifnot(is.numeric(arg))

  colMeas <- attr(obj,"colMeas")

  obj[,(colMeas) := get(colMeas) + arg]
}

以及添加新列的方法

addCol <- function(obj,arg) {
  UseMethod("addCol")
}

# Add a column
addCol.myclass <- function(obj,colNew := get(colMeas) + arg]

  data.table::setattr(obj,"colNew","colNew")
}

我使用的一切如下:

library(data.table)
dt = data.table(x = 1:10,y = rep(1,10))
myclass(dt,colMeas = "y")


modCol(dt,10)
addCol(dt,10)

给出:

> dt
     x  y colNew
 1:  1 11     21
 2:  2 11     21
 3:  3 11     21
 4:  4 11     21
 5:  5 11     21
 6:  6 11     21
 7:  7 11     21
 8:  8 11     21
 9:  9 11     21
10: 10 11     21

> attributes(dt)
$names
[1] "x"      "y"      "colNew"

$row.names
 [1]  1  2  3  4  5  6  7  8  9 10

$class
[1] "myclass"    "data.table" "data.frame"

$.internal.selfref
<pointer: 0x7f841e016ee0>

$colMeas
[1] "y"

$colNew
[1] "colNew"

问题更多是关于 R/S3“学说”。在上面的方法中,我正在“就地”修改 data.table 对象,我可以调用这些函数而无需将结果分配给新对象。这是处理 S3 类中 data.table 对象的正确方法吗?或者我应该向所有函数添加显式 return(obj),然后像这样分配结果:

dt = myclass(dt,colMeas = "y")
    
dt = modCol(dt,10)
dt = addCol(dt,10)

这不会导致对 dt 对象的过度复制吗?

解决方法

我会投票Yes就地修改它,即不需要捕获返回值。

(在考虑这个回复时,我改变了主意两次,但现在我确定了)。

data.table 中有几个函数可以就地修改对象,例如 setnames(...)。对此有明确的优先权。

data.table 代码库中还有一个通过引用工作的通用哲学,这是将其与 data.frames 区分开来的一个重要特性

采用这种设计理念听起来很正确。

注意:我觉得隐式返回data.table对象还是不错的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。