3

背景

我正在阅读有关如何将自我调整文本放入条形图中的出色答案:Resizeable text grobs inside bar

在阅读了一些 关于扩展 ggplotggproto的小插曲之后,我想知道为什么作者必须将例程定义如下:setup_data

GeomFit <- ggproto("GeomFit", GeomRect,
               setup_data = function(data, params) {
                 data$width <- data$width %||%
                   params$width %||% (resolution(data$x, FALSE) * 0.9)
                 transform(data,
                           ymin = pmin(y, 0), ymax = pmax(y, 0),
                           xmin = x - width / 2, xmax = x + width / 2, width = NULL
                 )
               })

因为这本质上是来自以下内容的复制粘贴ggplot2::GeomBar

GeomBar$setup_data
# <ggproto method>
#   <Wrapper function>
#     function (...) 
# f(...)

#   <Inner function (f)>
#     function (data, params) 
# {
#     data$width <- data$width %||% params$width %||% (resolution(data$x, 
#         FALSE) * 0.9)
#     transform(data, ymin = pmin(y, 0), ymax = pmax(y, 0), xmin = x - 
#         width/2, xmax = x + width/2, width = NULL)
# }

所以我想我可以简单地替换它:

GeomFit <- ggproto("GeomFit", GeomRect,
                   setup_data = function(self, data, params)
                      ggproto_parent(GeomBar, self)$setup_data(data, params))

这种方法有效,但我怀疑这是否会导致一些不需要的行为,仅仅是因为GeomFitisGeomRectnot GeomBar的父类。

问题

是否可以(从某种意义上说:没有可能导致问题的条件)用于ggproto_parent从不是我的ggproto对象的父类的类中调用函数?为什么ggproto_parent一开始就有parent争论?父母不应该由 的第二个参数决定ggproto吗?

4

1 回答 1

4

我没有参与ggplot2包的开发,但我会尝试一下,因为已经有一个星期了,到目前为止还没有其他人发布过......

以下是我从 ggplot2 的GitHub 页面上复制的相关函数定义:

ggproto_parent <- function(parent, self) {
  structure(list(parent = parent, self = self), class = "ggproto_parent")
}

`$.ggproto_parent` <- function(x, name) {
  res <- fetch_ggproto(.subset2(x, "parent"), name)
  if (!is.function(res)) {
    return(res)
  }

  make_proto_method(.subset2(x, "self"), res)
}

从第一个函数中,我们可以推断ggproto_parent(GeomBar, self)在这种情况下将返回一个包含两个项目的列表list(parent = GeomBar, self = self)(其中 self 解析为GeomFit)。此列表作为 传递给第二个函数x

然后,第二个函数在 中搜索x[["parent"]]与给定名称对应的方法,在本例中为setup_data( ),如果所讨论的函数包含参数 ( ),则将fetch_ggproto其与相关联。x[["self"]]selfmake_proto_method

这两个函数都不会检查GeomFit(可以在 处访问GeomFit$super())的父级,所以我认为拥有GeomBar代替GeomRectinggproto_parent()并不重要。


也就是说,我可能会使用这样的东西:

GeomFit <- ggproto("GeomFit", GeomRect,
                   setup_data = .subset2(GeomBar, "setup_data"))

或这个:

GeomFit <- ggproto("GeomFit", GeomRect,
                   setup_data = environment(GeomBar$setup_data)$f)

这使得代码更短。

于 2019-03-27T10:24:47.360 回答