英文:
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
- 基础管道中的占位符
_
|>
指的是随后的函数中的第一个参数。 - magrittr 管道
%>%
中的占位符.
指的是正在传递的数据。 - 在 ggplot2 函数中,数据参数预期是数据框或类似对象(例如 tibble),而不是函数调用。
- 因此,您不能直接在数据参数中使用基础管道和占位符。
- 但是,您可以在数据参数中使用匿名函数,该函数以数据框作为输入,并在此函数内部使用基础管道和占位符。
- 然后,您可以对此数据框应用函数并返回一个数据框,该数据框可以直接供 ggplot2 使用。
因此,您的第二种方法有效!
英文:
In addition to the comments some considerations:
- The placeholder
_
in the base pipe|>
does refer to the first argument in the function that follows it. - The placeholder
.
in the magrittr pipe%>%
refers to the data being piped. - In ggplot2 functions, the data argument does expect a data frame or similar object (e.g., tibble) and not a function call.
- Therefore, you cannot use the base pipe and placeholder directly in the data argument.
- 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.
- 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!
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论