Метод печати с пользовательскими классами

Я экспериментирую с S3-class методы и общие функции, но у меня есть проблема, которая, как мне кажется, подчеркивает недопонимание в моем мышлении. Возможно, я путаюсь с тем, как работает печать или как хранить values а также attributes работает внутри?

Я пытался гуглить вокруг безрезультатно, возможно, потому что я не слишком уверен, что я ищу.

Настроить

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 ответ

Решение

Вот две лучшие возможности, первая следует вашему подходу (который может быть быстрее из-за автоматической индексации, но я не тестировал):

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 метод никак не связан с умножением.

Другие вопросы по тегам