r语言 - 从父类调用setup_data



Backround

我正在阅读这个关于如何将自调整文本放入条形图的出色答案:条形内可调整大小的文本 grobs

在阅读了ggproto,尤其是扩展 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而不是GeomBar

问题

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

我没有参与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),如果相关函数包含self参数 (make_proto_method),则将其与x[["self"]]相关联。

这两个函数都不检查GeomFit的父级(可以在GeomFit$super()访问),所以我认为在ggproto_parent()中使用GeomBar而不是GeomRect并不重要。


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

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

或者这个:

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

这使得代码更短。

相关内容

  • 没有找到相关文章

最新更新