【问题标题】:r how to keep print method for custom classr 如何保留自定义类的打印方法
【发布时间】:2019-02-01 19:10:12
【问题描述】:

我已经定义了一个使用类 test 打印矢量的方法:

print.test <- function(x,  ...) {
    x <- formatC(
        as.numeric(x),
        format = "f",
        big.mark = ".",
        decimal.mark = ",",
        digits = 1
        )
    x[x == "NA"] <- "-"
    x[x == "NaN"] <- "-"
    print.default(x)
}

适用于以下情况

a <- c(1000.11, 2000.22, 3000.33)
class(a) <- c("test", class(a))
print(a)
[1] "1.000,11" "2.000,22" "3.000,33"

这也有效:

round(a)
[1] "1.000,0" "2.000,0" "3.000,0"

这不是:

median(a)
[1] 2000.22
class(median(a))
[1] "numeric"

现在我的问题是:我需要为这个类编写一个自定义方法来使用中位数吗?如果是这样,它会是什么样子或者有其他方法(因为我只是希望这个类以某种格式打印数据)?

【问题讨论】:

  • 您需要为sortmean 定义方法,因为它们剥离了类属性,因此median 也是如此。

标签: r class printing


【解决方案1】:

问题在于 median.default 返回一个 numeric 类的对象,因此返回对象的自动打印不会调用您的自定义 print 方法。
以下将这样做。

median.test <- function(x, na.rm = FALSE, ...){
    y <- NextMethod(x, na.rm = na.rm, ...)
    class(y) <- c("test", class(y))
    y
}

median(a)
#[1] "2.000,2"

至于NA值的处理,我先定义一个R基函数的另一种方法。如果经常使用test 类的对象,则不是严格需要,但可以节省一些代码行。

c.test <- function(x, ...){
    y <- NextMethod(x, ...)
    class(y) <- c("test", class(y))
    y
}


b <- c(a, NA)
class(b)
#[1] "test"    "numeric"

median(b)
#[1] "-"

median(b, na.rm = TRUE)
#[1] "2.000,2"

编辑。

下面定义了一个通用函数wMedian,一个默认方法和一个类"currency"对象的方法,根据OP在评论中的要求。

注意一定有一个方法print.currency,因为和上面的print.test完全一样,我就不重新定义了。至于其他方法,我借助一个新函数 as.currency 使它们变得更简单。

median.currency <- function(x, na.rm = FALSE, ...){
  y <- NextMethod(x, na.rm = na.rm, ...)
  as.currency(y)
}

c.currency <- function(x, ...){
  y <- NextMethod(x, ...)
  as.currency(y)
}

as.currency <- function(x){
  class(x) <- c("currency", class(x))
  x
}

wMedian <- function(x, ...) UseMethod("wMedian")
wMedian.default <- function(x, ...){
    matrixStats::weightedMedian(x, ...)
}

wMedian.currency <- function(x, w = NULL, idxs = NULL, na.rm = FALSE, interpolate = is.null(ties), ties = NULL, ...) {
  y <- NextMethod(x, w = w, idxs = idxs, na.rm = na.rm, interpolate = interpolate, ties = ties, ... ) 
  as.currency(y)
}


set.seed(1)
x <- rnorm(10)
wMedian(x, w = (1:10)/10)
#[1] 0.4084684
wMedian(as.currency(x), w = (1:10)/10)
#[1] "0,4"

【讨论】:

  • &lt;- 的方法似乎不必要且错误。 &lt;- 的第一个参数是分配第二个参数的符号。此外,&lt;- 不是 S3 泛型。
  • @Roland 你是对的。我的错误来自于同时定义了&lt;-.testc.test,这是通用的,并经过测试c(a, NA)。不管有没有&lt;-.test,它显然都有效。感谢您注意到这一点。
  • 我现在尝试从 matrixStats 包中为 weightedMedian 实现相同的过程。不知何故,相同的方法在这里不太适用。有任何想法吗? weightedMedian.currency
  • @jaydee 就像您编写的代码一样,它不起作用,因为weightedMedian 不是通用的。 isGeneric("weightedMedian") 返回FALSE
  • @RuiBarradas thx,我猜这个问题涉及到这样的事情。关于我如何仍然让它工作的任何想法,以保持我添加到我的向量中的附加类“货币”?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-02
  • 2022-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-07-12
相关资源
最近更新 更多