从父类调用setup_data

时间:2019-03-21 14:01:54

标签: r ggplot2 ggproto

背景

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

在阅读了ggproto,特别是Extending ggplot的小插图之后,我想知道为什么作者必须如下定义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))

此方法有效,但是我怀疑这是否可能导致某些不良行为,只是因为GeomFit的父类是GeomRect不是 {{1} }。

问题

可以使用GeomBar从不是我的ggproto_parent的父类的类中调用函数(在某种意义上:没有条件可能会导致问题)宾语?为什么ggproto首先有一个ggproto_parent参数?父母不应该由parent的第二个参数确定吗?

1 个答案:

答案 0 :(得分:1)

我没有参与ggplot2程序包的开发,但是我要花一点时间,因为已经过去了一个星期,而且到目前为止还没有人发布。。。

以下是我从ggplot2的GitHub page复制而来的相关函数定义:

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_datafetch_ggproto),如果满足,则将其与x[["self"]]关联该函数包含一个self参数(make_proto_method)。

这两个函数都不检查GeomFit的父级(可以在GeomFit$super()上访问),因此我不认为在{{中使用GeomBar而不是GeomRect 1}}真的很重要。


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

ggproto_parent()

或者这个:

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

哪个代码更短。