10

我正在尝试为"["我创建的自定义类重载下标运算符 ()。我试图弄清楚如何处理以下问题。

  • 您如何确定操作员是在 lhs 还是 rhs 上?即a[x] = foofoo = a[x]
  • 当下标整个维度foo = a[,x]时,我如何识别第一个参数?
  • 当使用 a[seq(x,y)] 时,它似乎在扩展整个序列。有没有一种简单的方法可以在不扩展的情况下获得第一步、一步和最后一个值?

编辑:我的第一点收到了多个答案。在这个过程中,我已经找到了第二个的答案。您可以使用“缺失”功能来确定存在哪些参数。

这是一个示例代码:

setMethod("[", signature(x="myClass"),
          function(x, i, j, k, l) {
              if (missing(i)) { i = 0 }
              if (missing(j)) { j = 0 }
              if (missing(k)) { k = 0 }
              if (missing(l)) { l = 0 }
          })

我已经接受了这个问题的答案,因为第 3 点对我来说是最不重要的。

4

4 回答 4

10

发现 Generic,这样您就知道您的目标是实现什么:

getGeneric('[')
# standardGeneric for "[" defined from package "base"
# function (x, i, j, ..., drop = TRUE) 

和 :

getGeneric('[<-')
# standardGeneric for "[<-" defined from package "base"
# function (x, i, j, ..., value) 

然后你像这样实现它,例如:

`[<-.foo` <-
function(x, i, j, value) 
{
       ....

}
于 2014-03-14T14:53:25.310 回答
7

对于第一个要点,有两个函数需要重载:

  1. [
  2. [<-

第一个函数返回值,第二个函数设置值。请参阅文档Extract.data.frame{base}

于 2014-03-14T14:45:08.753 回答
6

请参阅源代码[.data.frame作为示例。你有一个 x、一个 i 和 aj,按这个顺序。

> `[.data.frame`
function (x, i, j, ..... )
> `[<-.data.frame`
function (x, i, j, value) 

你可以做类似的事情:

obj <- structure(runif(10),class="myclass")
`[.myclass` <- function(x,i=NULL,j=NULL) {
  message("First parameter is ", i, "\n")
  message("Second parameter is ", j, "\n")
    sum(x)
}
obj[c(1,2,3)]

`[<-.myclass` <- function(x,i=NULL,j=NULL,value) {
    res <- unclass(x)
    res[i] <- value
    res
}
obj[1] <- 1

顺序无关紧要。i 和 j 是正确的:

2 -> obj[2]
> obj
 [1] 1.0000000 2.0000000 0.3466835 0.3337749 0.4763512 0.8921983 0.8643395 0.3899895 0.7773207 0.9606180
于 2014-03-14T14:49:28.790 回答
1

至于第三个要点,您可以使用如下内容:

seq_parse <- function(s) {
    the_s <- deparse(substitute(s))
    env <- new.env()
    assign("seq", function(...) return(list(...)), envir=env)
    seq_params <- try(eval(parse(text=the_s), envir=env), silent=TRUE)
    if(!inherits(seq_params, "try-error")) {
        cat("parsing successful \n")
        return(seq_params)
    } else {
        stop("Failed to parse.")
    }
}

此函数将参数返回给seq,

> seq_parse(seq(from=1,to=10,by=0.5))
working with params to seq_params 
$from
[1] 1

$to
[1] 10

$by
[1] 0.5 

或传统的评估论点,

> seq_parse(1:5)
parsing successful 
[1] 1 2 3 4 5

但是,我不确定这是否是好的做法。此外,您必须仔细解释 to 的参数seq,它们可能是未命名的,而不是to可能有length.out等。

于 2014-03-14T16:12:19.367 回答