如何在 ggplot 管道中使用子集?

问题描述

我正在尝试使用带有子集的 ggplot 来为 MyName 的不同值制作单独样式的线条。

如果我将数据框设置为在子集函数中引用的临时变量 temp,则此方法有效

temp <- data.frame(x = ...,y = ...,MyName = ...)
temp %>% ggplot(aes(x = x,y= y) + geom_line(data = subset(temp,MyName == "Var Name"),...)

除了我更喜欢避免创建临时数据框。

有没有一种语法可以让我避免这种情况? 类似的东西。在此,除了正确:

data.frame(x = ...,MyName = ...) %>%
%>% ggplot(aes(x = x,y= y) + geom_line(data = subset(.,...)

这表示对象'.'未找到。

解决方法

您可以使用 lambda 语法作为图层的 data 参数。然后它知道使用提供给主 ggplot 调用的数据。

library(ggplot2)
library(magrittr)

iris %>% ggplot(aes(Sepal.Width,Sepal.Length)) +
  geom_point(data = ~subset(.,Species == "setosa"))

reprex package (v1.0.0) 于 2021 年 2 月 4 日创建

关于幕后发生的事情的一些额外细节; ggplot2 在 fortify() 函数中的所有 data 参数上使用 layer() S3 泛型。存在调用 ggplot2:::fortify.formula()rlang::as_function() 方法,该方法用“真实”函数替换 lambda 语法公式。 ggplot2:::Layer$layer_data() ggproto 方法然后使用绘图数据作为唯一参数调用该函数。请注意,这与管道运算符的工作方式不同,但仍然非常方便。