I'm experimenting with S3-class
methods and generic functions, but I'm having an issue which I think highlights a misunderstanding in my thinking. Perhaps I'm getting confused with how printing works, or how storing values
and attributes
works internally?
I've tried to google around to no avail, possibly because I'm not too sure what I'm looking for.
Setup
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)
}
Class methods
# 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"
Printing coverageB
without loading print.coverage
gives
> coverageB
[1] 0.3333333
attr(,"class")
[1] "coverage" "numeric"
attr(,"desc")
[1] "of data.table is in B"
where I'd like some way to print just the 0.3333333
.
Help would be much appreciated. Thanks.
(As a side note, I'm sure that eval(parse(...))
statement is not the right way to do things. Any pointers there would be appreciated too.)
I also wasn't sure what to title this - if anyone has any more appropriate suggestion I'm happy to change it.