如何在ggplot中使用R的本地管道和占位符。

huangapple go评论56阅读模式
英文:

How to use R's native pipe and placeholder in ggplot

问题

如何在ggplot的geom内使用本机管道和占位符?

当将data.frame传递给ggplot时,本机管道可以正常工作,但在geom内部,当我想要筛选原始data.frame时,我需要使用'magrittr'管道。

所以这样可以正常工作:

mtcars |> 
     ggplot() +
     geom_col(data = . %>% filter(cyl == 4),
              aes(x = gear, y = mpg),
              fill = "grey80") +
     geom_text(data = . %>% filter(cyl == 4 & gear == 3),
               aes(x = gear,
                   y = mpg,
                   label = "ooo"), color = "tomato3") +
     theme_minimal()

通过匿名函数,我可以完全切换到本机管道:

mtcars |> 
     ggplot() +
     geom_col(data = (\(x) filter(x, cyl == 4)),
              aes(x = gear, y = mpg),
              fill = "grey80") +
     geom_text(data = (\(x) filter(x, cyl == 4 & gear == 3)),
               aes(x = gear,
                   y = mpg,
                   label = "ooo"), color = "tomato3") +
     theme_minimal()

但是否有一种优雅的方法可以使用R的本机管道运算符和占位符来执行相同的操作?

这将引发错误'invalid use of pipe placeholder':

mtcars |> 
     ggplot() +
     geom_col(data = _ |>  filter(cyl == 4),
              aes(x = gear, y = mpg),
              fill = "grey80") +
     geom_text(data = _ |>  filter(cyl == 4 & gear == 3),
               aes(x = gear,
                   y = mpg,
                   label = "ooo"), color = "tomato3") +
     theme_minimal()
英文:

How can I use the native pipe and placeholder inside a ggplot geom?

When passing a data.frame to ggplot the native pipe works fine, but inside a geom I need to use the 'magrittr' pipe when I want to filter the original data.frame.

So this works fine:

mtcars |> 
     ggplot() +
     geom_col(data = . %>% filter(cyl == 4),
              aes(x = gear, y = mpg),
              fill = "grey80") +
     geom_text(data = . %>% filter(cyl == 4 & gear == 3),
               aes(x = gear,
                   y = mpg,
                   label = "ooo"), color = "tomato3") +
     theme_minimal()

With an anonymous function, I can switch completely to the native pipe:

mtcars |> 
     ggplot() +
     geom_col(data = (\(x) filter(x, cyl == 4)),
              aes(x = gear, y = mpg),
              fill = "grey80") +
     geom_text(data = (\(x) filter(x, cyl == 4 & gear == 3)),
               aes(x = gear,
                   y = mpg,
                   label = "ooo"), color = "tomato3") +
     theme_minimal()

But is there an elegant way to use R's native pipe operator AND the placeholder to do the same operation?

This throws the error 'invalid use of pipe placeholder':

mtcars |> 
     ggplot() +
     geom_col(data = _ |>  filter(cyl == 4),
              aes(x = gear, y = mpg),
              fill = "grey80") +
     geom_text(data = _ |>  filter(cyl == 4 & gear == 3),
               aes(x = gear,
                   y = mpg,
                   label = "ooo"), color = "tomato3") +
     theme_minimal()

答案1

得分: 3

以下是翻译好的部分:

"其实可以继续使用原生的管道,但可以利用 ggplot2,尽管可能会弃用公式语法,而更喜欢新的匿名函数语法,它仍然有效。

mtcars |> 
  ggplot() +
  geom_col(data = ~filter(., cyl == 4),
           aes(x = gear, y = mpg),
           fill = "grey80") +
  geom_text(data =  ~filter(., cyl == 4 & gear == 3),
            aes(x = gear,
                y = mpg,
                label = "ooo"), color = "tomato3") +
  theme_minimal()

尽管如此,我个人非常相信不要在绘图/图表代码中进行数据操作。
我更愿意提前进行所有数据更改,然后编写纯粹的绘图函数。

d1 <- filter(mtcars, cyl == 4)
d2 <- filter(mtcars, cyl == 4 & gear == 3)

  ggplot() +
  geom_col(data =  d1,
           aes(x = gear, y = mpg),
           fill = "grey80") +
  geom_text(data =  d2,
            aes(x = gear,
                y = mpg,
                label = "ooo"), color = "tomato3") +
  theme_minimal()
```"

<details>
<summary>英文:</summary>

Its possible to stay with the native pipe, but leverage that ggplot2 though perhaps deprecating formula syntax in favour of the new anonymous function syntax, still works.

mtcars |>
ggplot() +
geom_col(data = ~filter(., cyl == 4),
aes(x = gear, y = mpg),
fill = "grey80") +
geom_text(data = ~filter(., cyl == 4 & gear == 3),
aes(x = gear,
y = mpg,
label = "ooo"), color = "tomato3") +
theme_minimal()


That said, I personally am a great believer of not doing data manipulations in my plotting/charting code. 
I would much rather do all my data changes up front, and then write a purely plotting function.

d1 <- filter(mtcars, cyl == 4)
d2 <- filter(mtcars, cyl == 4 & gear == 3)

ggplot() +
geom_col(data = d1,
aes(x = gear, y = mpg),
fill = "grey80") +
geom_text(data = d2,
aes(x = gear,
y = mpg,
label = "ooo"), color = "tomato3") +
theme_minimal()

答案2

得分: 2

  1. 基础管道中的占位符 _ |&gt; 指的是随后的函数中的第一个参数。
  2. magrittr 管道 %&gt;% 中的占位符 . 指的是正在传递的数据。
  3. 在 ggplot2 函数中,数据参数预期是数据框或类似对象(例如 tibble),而不是函数调用。
  4. 因此,您不能直接在数据参数中使用基础管道和占位符。
  5. 但是,您可以在数据参数中使用匿名函数,该函数以数据框作为输入,并在此函数内部使用基础管道和占位符。
  6. 然后,您可以对此数据框应用函数并返回一个数据框,该数据框可以直接供 ggplot2 使用。

因此,您的第二种方法有效!

英文:

In addition to the comments some considerations:

  1. The placeholder _ in the base pipe |&gt; does refer to the first argument in the function that follows it.
  2. The placeholder . in the magrittr pipe %&gt;% refers to the data being piped.
  3. In ggplot2 functions, the data argument does expect a data frame or similar object (e.g., tibble) and not a function call.
  4. Therefore, you cannot use the base pipe and placeholder directly in the data argument.
  5. But, you can use an anonymous function in the data argument, taking a data frame as input and using the base pipe and placeholder within this function.
  6. Then you can apply a function to this data frame and return a data frame, which can be used directly by ggplot2.

Your second approach therefore works!

huangapple
  • 本文由 发表于 2023年7月4日 22:48:51
  • 转载请务必保留本文链接:https://go.coder-hub.com/76613795.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定