【问题标题】:Error: object '->' not found in R错误:在 R 中找不到对象“->”
【发布时间】:2018-08-15 05:43:33
【问题描述】:

我有一个模型对象,描述为向量和矩阵参数的命名列表。此类对象的两个基本操作是基于每个参数向量或矩阵的元素与向量中的索引之间的映射,从/向数字向量加载和存储。这是一个简化的例子:

LoadModelFromVector <- function(vecParams) {
    model <- list(
        A = diag(5),            # a diagonal square matrix
        B = matrix(0, 5, 5)     # un upper triangular square matrix
    ) 
    attr(model, "p") <- 15

    diag(model$A) <- vecParams[1:5]
    model$B[upper.tri[model$B]] <- vecParams[5 + (1:(5*(5-1)/2)))]

    model
}

StoreModelToVector <- function(model) {
    vecParams <- double(length = attr(model, "p"))
    vecParams[1:5] <- diag(model$A)
    vecParams[5 + (1:(5*(5-1)/2)))] <- model$B[upper.tri[model$B]]

    vecParams
}

我不喜欢上面的示例,因为它在代码中的两个位置复制了映射。相反,我想把这个映射放在一个地方。我认为这可以使用赋值运算符&lt;-的抽象来优雅地完成:

LoadStoreModel <- function(vecParams, model = NULL) {
    if(is.null(model)) {
        model <- list(
            A = diag(5),            # a diagonal square matrix
            B = matrix(0, 5, 5)     # un upper triangular square matrix
        )
        `%op%` <- `<-`              # WORKS FINE :-)
        mode <- "load"
    } else {
        vecParams <- double(length = attr(model, "p"))
        `%op%` <- `->` # GENERATES "Error: object '->' not found" :-(
        mode <- "store"
    } 

    diag(model$A) %op% vecParams[1:5]
    model$B[upper.tri[model$B]] %op% vecParams[5 + (1:(5*(5-1)/2)))]

    if(mode == "load") {
        model
    } else {
        vecParams
    }
}

LoadModelFromVector(vecParams) {LoadStoreModel(vecParams)}
StoreModelToVector(model) {LoadStoreModel(NULL, model)}

上面的代码生成错误“错误:找不到对象'->'”。 '->' 和 '?assignOps 中。

【问题讨论】:

标签: r


【解决方案1】:

` 在控制台返回

.Primitive("&lt;-") 即。 &lt;- 是 R 中的一个原始函数

> `<-`
.Primitive("<-")
> `->`
Error: object '->' not found

另外,如果我们查看base 包的所有功能并尝试搜索&lt;--&gt;

#find all functions in package    
r <- unclass(lsf.str(envir = asNamespace("base"), all = T))

> r[grep("^<-$", r)]
[1] "<-"

> r[grep("^->$", r)]
character(0)

这返回base包中没有`->`函数

希望这会有所帮助。

【讨论】:

  • 谢谢!为您的回答 +1!
【解决方案2】:

我的示例的以下修改似乎可以正常工作(还修复了一些语法错字):

LoadStoreModel <- function(vecParams, model = NULL) {
  if(is.null(model)) {
    model <- list(
      A = diag(5),            # a diagonal square matrix
      B = matrix(0, 5, 5)     # un upper triangular square matrix
    )
    attr(model, "p")<-15
    "%op%" <- `<-`             
    mode <- "load"
  } else {
    vecParams <- double(length = attr(model, "p"))

    "%op%"<- function(a,b) eval(substitute(b<-a), parent.frame()) # key-chage

    mode <- "store"
  } 

  diag(model$A) %op% vecParams[1:5]
  model$B[upper.tri(model$B)] %op% vecParams[5 + (1:(5*(5-1)/2))]

  if(mode == "load") {
    model
  } else {
    vecParams
  }
}

LoadModelFromVector <- function(vecParams) LoadStoreModel(vecParams)
StoreModelToVector <- function(model) LoadStoreModel(NULL, model)

> StoreModelToVector(m)
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15
> m <- LoadModelFromVector(1:15)
> m
$A
     [,1] [,2] [,3] [,4] [,5]
[1,]    1    0    0    0    0
[2,]    0    2    0    0    0
[3,]    0    0    3    0    0
[4,]    0    0    0    4    0
[5,]    0    0    0    0    5

$B
     [,1] [,2] [,3] [,4] [,5]
[1,]    0    6    7    9   12
[2,]    0    0    8   10   13
[3,]    0    0    0   11   14
[4,]    0    0    0    0   15
[5,]    0    0    0    0    0

attr(,"p")
[1] 15
> StoreModelToVector(m)
 [1]  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15

我还尝试了注释为“key-change”的其他一些变体。这些都不起作用:

# evaluation happens locally in the environment of the operator function,
# so the actual objects a and b in the parent environment are not affected:
"%op%"<- function(a,b) eval(substitute(b<-a)) 

# not sure why this did not work, but it seems that changes are made on local 
# copies of the objects as well.
"%op%"<- function(a,b) eval(quote(b<-a), parent.frame())

> StoreModelToVector(m)
 [1] 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-06-12
    • 2017-12-19
    • 2019-01-18
    • 1970-01-01
    • 1970-01-01
    • 2022-07-09
    • 2015-04-13
    相关资源
    最近更新 更多