【问题标题】:What are these square brackets for S3 classes?S3 类的这些方括号是什么?
【发布时间】:2018-04-10 02:31:19
【问题描述】:

我是从an open source repo on git 获得的。这显示了 S3 类的泛型和方法的编写。但我不理解分配函数的符号或约定。以下是我的问题:

  • 使用反引号`` 来定义函数名。通常我们不会使用反引号甚至双引号来分配变量/函数,但我看到这种情况发生了很多次。这是命名约定吗?
  • 为什么在 blob 名称之前包含 .?通常它不会被称为 blob 而一个方法就是 method.blob 吗?
  • 那里为什么有[ 括号?特别是[<-[[<-。我们是否在执行某种双重分配?

希望有人能够阐明什么是 ha

#' @export
 `[.blob`  <- function(x, i, ...) {
  new_blob(NextMethod())
}

#' @export
`[<-.blob` <- function(x, i, ..., value) {
  if (!is_raw_list(value)) {
    stop("RHS must be list of raw vectors", call. = FALSE)
  }

  NextMethod()
}

#' @export
 `[[<-.blob` <- function(x, i, ..., value) {
  if (!is.raw(value) && !is.null(value)) {
    stop("RHS must be raw vector or NULL", call. = FALSE)
  }

  if (is.null(value)) {
    x[i] <- list(NULL)
    x
  } else {
    NextMethod()
  }
}

【问题讨论】:

  • [ 是子集运算符。 [.blob 是新的blob 对象的子集化方法。因此,. 以标准 s3 方法调度方式使用(正如您在问题中指出的那样)
  • 特殊符号(例如,反引号、方括号、百分号、名称中带空格的变量)默认不能“分配给”。为此,如果您将其用反引号括起来,它就可以工作。例如,一个名为A B 的变量不能用A B &lt;- 1 赋值,而`A B` &lt;- 1 有效。
  • [[&lt;-.blob 函数用于为新的blob 对象覆盖[[&lt;- s3 方法。 “正常”的基本 R 示例是 myvec &lt;- c(1:5); myvec[[3]] &lt;- 2
  • 你也可以用反引号调用函数,例如`[`(letters, 4)会给你第4个字母,相当于letters[4]
  • 您可以使用反引号做一些事情,包括:使用标准语法调用中缀运算符(例如iris[['Species']]`[[`(iris, 'Species'))或引用具有非法(? ) 字符,例如如果dat 的列被命名为"0 bad column name",您可以说dat$`0 bad column name`,但不能说dat$0 bad column name。我还想其他几件事?

标签: r r-s3


【解决方案1】:

总结

如果您要在 R 中创建一个新的对象,您需要“不同”的子集和赋值行为,您应该为这些操作创建关联的方法。

  • . 正在以您期望的方式工作 - 方法调度

  • [.blob 正在覆盖 S3 [ 子集运算符

  • [&lt;-.blob 覆盖了 S3 [&lt;- 运算符(即向量子集赋值)

  • [[&lt;-.blob 正在覆盖 S3 [[&lt;- 运算符(即列表子集分配)

  • 默认情况下不能“分配给”特殊符号(例如,反引号、方括号、百分号、名称中带有空格的变量)。为此,如果您将其用反引号括起来,它就可以工作。例如,一个名为A B 的变量不能用A B &lt;- 1 赋值,而`A B` &lt;- 1 有效(信用@r2evans)

示例

子集

[.blob 为例,这允许您为blob 对象创建自己的子集操作。

## Create your own blob object (class)
blob <- 1:5
attr(blob, "class") <- "blob"

## create a subset operator, which in this example just calls the next method in the s3 dispatch chain 
`[.blob` <- function(x, i, j, ...) NextMethod()

由于我们在自己的子集方法中没有做任何特别的事情,所以它就像正常的 R 向量一样工作

blob[3]
# [1] 3

但是,我们可以让子集操作做任何我们想做的事情,例如总是返回向量的第一个元素

## define the function to always subset the first element
`[.blob` <- function(x, i, j, ...) { i = 1; NextMethod() }

现在您的 blob 对象将只返回第一个元素。

blob[1]
# [1] 1
blob[2]
# [1] 1
blob[3]
# [1] 1

作业

如果您将[&lt;- 重载为

,则对于其中一个赋值运算符也是如此
`[<-.blob` <- function(x, i, j, ...) { i = 5; NextMethod() }

这将始终为 blob 对象的第 5 个元素分配新值

blob[1] <- 100
blob
# [1]   1   2   3   4 100
# attr(,"class")
# [1] "blob"

反引号

使用了反引号,因此我们可以将函数/变量分配给特殊符号。

例如,尝试将向量分配给[ 符号

[ <- 1:5
# Error: unexpected '[' in "["

而用刻度包围它可以让它通过(虽然不推荐这个例子)

`[` <- 1:5
`[`
# [1] 1 2 3 4 5

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多