我正在尝试使用 ggplot2 构建一个自定义统计函数,其中我想访问一个离散变量来计算每个组的统计数据。但是,ggplot 层的默认行为是自动将隐式组分配给任何离散变量(大多数情况下)。这意味着我的数据会被自动分组,这是我不希望的。
我可以显示如下;我有一个非常标准的构造函数:
library(ggplot2)
stat_example <- function(
mapping = NULL,
data = NULL,
geom = "point",
position = "identity",
...,
na.rm = FALSE,
show.legend = NA,
inherit.aes = TRUE
) {
layer(data = data,
mapping = mapping,
stat = StatExample,
geom = geom,
position = position,
show.legend = show.legend,
inherit.aes = inherit.aes,
params = list(na.rm = na.rm))
}
我有一个 Stat ggproto 对象,它只是传递数据,但出于说明目的打印数据的头部。我在这里调用了我感兴趣的用于计算实际统计数据的位value
。
StatExample <- ggproto(
"StatExample",
Stat,
required_aes = c("x", "y", "value"),
default_aes = aes(x = after_stat(x), y = after_stat(y)),
compute_group = function(data, scales) {
print(head(data, 2))
data
}
)
现在,如果我用这个统计数据构建一个图,我们可以看到compute_group()
函数中的内容为data
.
g <- ggplot(iris) +
stat_example(aes(Sepal.Width, Sepal.Length, value = Species))
# To get only the print side-effect, not the plot (which looks normal)
g <- ggplotGrob(g)
#> x y value PANEL group
#> 1 3.5 5.1 setosa 1 1
#> 2 3.0 4.9 setosa 1 1
#> x y value PANEL group
#> 51 3.2 7.0 versicolor 1 2
#> 52 3.2 6.4 versicolor 1 2
#> x y value PANEL group
#> 101 3.3 6.3 virginica 1 3
#> 102 2.7 5.8 virginica 1 3
由reprex 包(v0.3.0)于 2020 年 5 月 28 日创建
我想要 1 个 data.frame 包含此案例的所有数据。我们在上面看到我们打印了 3 个带有不同group
变量的 data.frames,这意味着数据被分成了 3 组。我认为到达那里需要的是让value
变量逃脱自动组检测。
我考虑了以下几点:
- 我可以让组默认为
-1
,这是标准的“无组”组。但是,当我这样做时,数据不会自动分组,例如aes(colour = some_variable)
. 这是我绝对想要发生的。 - 查看
ggplot2:::add_group()
函数,似乎我可以通过命名我的value
变量来逃避自动分组label
,但是这会使 stat 不兼容geom_text()
并且它不能value
自然地描述的含义。 - 我可以用
layer()
这个函数的一个变体替换调用,这将创建一个不同的 Layer ggproto 对象,其中compute_aesthetics()
不同的组工作。然而,这是我宁愿避免负担的大量工作。 - 我可能会按照 . 的方式来做一个技巧,但是在那个类中包装我的变量
vctrs::new_vctr(..., class = "not_discrete")
的合适位置在哪里?value
欢迎提供有用的建议,或者对“仅使用label
”参数进行新的处理。