使用用户类的打印方法

时间:2015-11-15 13:47:02

标签: r data.table r-s3

我尝试使用S3-class方法和通用函数,但我遇到了一个问题,我认为这突出了我的思维中的误解。也许我对打印的工作方式,或者如何在内部存储valuesattributes感到困惑?

我试图谷歌无用,可能是因为我不太确定我在寻找什么。

设置

library(data.table)

# trivial data
dt <- CJ(letter = c("A", "B", "C"), number = 1:4)

# -- generic functions
coverage <- function (x, ...) {
  UseMethod("coverage", x)
}

prettyprint <- function (x, ...) {
  UseMethod("prettyprint", x)
}

类方法

# coverage method to find % of data.table satisfying an expr
coverage.data.table <- function(dt, subset, desc) {
  e <- parse(text = subset)  # parse condition to expression
  coverage <- dt[eval(e), .N]/dt[, .N]  # express coverage as a percent 
  class(coverage) <- c("coverage", class(coverage))  # set as 'coverage' class
  attributes(coverage)[["desc"]] <- desc  # carry description for printing
  coverage
}

# human readable data.table coverage
prettyprint.coverage <- function(coverage) {
  desc <- attributes(coverage)[["desc"]]
  paste0(round(coverage*100, 2), "% ", desc)
}

# normal printing
print.coverage <- function(coverage) {

  # unsure what to put in here such that I can use
  # this value with standard other operations such 
  # as multiplication

}

coverageB <- coverage(dt, "letter == \"B\"", "of data.table is in B")

> coverageB  # prints nothing as expected from empty function
> prettyprint(coverageB)
  [1] "33.33% of data.table is in B"

在不加载coverageB的情况下打印print.coverage

> coverageB
[1] 0.3333333
attr(,"class")
[1] "coverage" "numeric" 
attr(,"desc")
[1] "of data.table is in B"

我想在某种方式打印0.3333333

非常感谢帮助。感谢。

(作为旁注,我确定eval(parse(...))语句不是正确的做法。任何指针都会受到赞赏。)

我也不确定该怎么称呼 - 如果有人有更合适的建议,我很乐意改变它。

1 个答案:

答案 0 :(得分:1)

以下是两个更好的可能性,第一个跟随您的方法(由于自动索引可能会更快,但我还没有进行基准测试):

coverage.data.table <- function(dt, subset, desc) {
  coverage <- dt[eval(substitute(subset)), .N]/dt[, .N]  # express coverage as a percent 
  #coverage <- dt[, mean(eval(substitute(subset)))]  # express coverage as a percent 
  class(coverage) <- c("coverage", class(coverage))  # set as 'coverage' class
  attributes(coverage)[["desc"]] <- desc  # carry description for printing
  coverage
}

然后你这样称呼它:

coverageB <- coverage(dt, letter == "B", "of data.table is in B")

以下是使用print删除所有属性的c方法(请参阅其文档):

# normal printing
print.coverage <- function(coverage) {
  print.default(c(coverage))
} 

coverageB
#[1] 0.3333333
prettyprint(coverageB)
#[1] "33.33% of data.table is in B"

但是,我不理解您对print方法的评论。 print方法与乘法无关。