【问题标题】:Getting the object name for S3 print method failing获取 S3 打印方法的对象名称失败
【发布时间】:2011-06-24 23:21:09
【问题描述】:

定义一个S3类“bar”的对象和一个打印方法:

foo=list(1)
class(foo) <- c("bar")
print.bar <- function(x,...){
  cat("print.bar says this was ",deparse(substitute(x)),"\n")
}

现在 print(foo) 会这样做:

> print(foo)
print.bar says this was  foo 

很好,但自动打印失败:

> foo
print.bar says this was  structure(list(1), class = "bar")

我猜这与该行被评估为顶级表达式的方式有关。快速搜索 R-devel 无济于事。有人知道怎么解决吗?

我想要这个名字的原因是因为我定义的东西是一个函数,我希望能够将'try foo(2)'放在打印方法中(从对象的名称中获取'foo' )。是的,您可以在 S3 中对函数进行子类化。我想可能还有其他陷阱..

【问题讨论】:

    标签: r r-s3


    【解决方案1】:

    这是一种相当特殊的情况,因为当您在命令行中键入名称时,R 在调用 print 之前将其值替换为 foo。这可以通过以下方式说明:

    foo=list(1)
    class(foo) <- c("bar")
    print.bar <- function(x,...){
      print(sys.calls())
    }
    
    > foo
    [[1]]
    print(list(1))
    
    [[2]]
    print.bar(list(1))
    
    > print(foo)
    [[1]]
    print(foo)
    
    [[2]]
    print.bar(foo)
    

    ergo,如果没有名称作为属性(如 Aaron 所示),您将无法从任何地方提取对象的名称。它根本不在调用堆栈中。

    【讨论】:

    • 是的,好像做不到。我可能会查看源代码以了解这是如何发生的。谢谢!
    【解决方案2】:

    如果您不打算重命名对象,则可以将名称作为属性包含并打印出来。

    foo <- structure(list(1), class="bar", name="foo")
    print.bar <- function(x,...){
      cat("print.bar says this was",attr(x, "name"),"\n")
    }
    

    然后它会做你期望的事情:

    > print(foo)
    print.bar says this was foo 
    > foo
    print.bar says this was foo 
    

    除非您对同一个对象使用不同的名称:

    > fooX <- foo
    > fooX
    print.bar says this was foo 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-27
      • 2023-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多