【发布时间】:2017-10-15 22:06:38
【问题描述】:
我想按照this 的线条(没有双关语)制作一个斜率图。理想情况下,我想在 dplyr 样式的链中完成所有操作,但是当我尝试对数据进行子集化以添加特定的 geom_text 标签时遇到了障碍。这是一个玩具示例:
# make tbl:
df <- tibble(
area = rep(c("Health", "Education"), 6),
sub_area = rep(c("Staff", "Projects", "Activities"), 4),
year = c(rep(2016, 6), rep(2017, 6)),
value = rep(c(15000, 12000, 18000), 4)
) %>% arrange(area)
# plot:
df %>% filter(area == "Health") %>%
ggplot() +
geom_line(aes(x = as.factor(year), y = value,
group = sub_area, color = sub_area), size = 2) +
geom_point(aes(x = as.factor(year), y = value,
group = sub_area, color = sub_area), size = 2) +
theme_minimal(base_size = 18) +
geom_text(data = dplyr::filter(., year == 2016 & sub_area == "Activities"),
aes(x = as.factor(year), y = value,
color = sub_area, label = area), size = 6, hjust = 1)
但这给了我Error in filter_(.data, .dots = lazyeval::lazy_dots(...)) :
object '.' not found。使用子集而不是 dplyr::filter 会给我一个类似的错误。我在 SO/Google 上找到的是this question,它解决了一个稍微不同的问题。
像这样对链中的数据进行子集化的正确方法是什么?
编辑:我的reprex 是一个简化的例子,在实际工作中我有一个长链。 Mike 在下面的评论适用于第一种情况,但不适用于第二种情况。
【问题讨论】:
-
用
df替换.怎么样? -
您可以通过使用大括号明确指定您希望传入 data.frame 的管道位置来破解它:
df %>% filter(area == "Health") %>% { ggplot(.) + geom_line(aes(x = as.factor(year), y = value, group = sub_area, color = sub_area), size = 2) + geom_point(aes(x = as.factor(year), y = value, group = sub_area, color = sub_area), size = 2) + geom_text(data = dplyr::filter(., year == 2016 & sub_area == "Activities"), aes(x = as.factor(year), y = value, color = sub_area, label = area), size = 6, hjust = 1) }我不确定它是否能满足您的需求,但这是一个情节,至少。 -
@MikeH。谢谢,这行得通!但是,它需要
aes()中的变量前面的数据框名称(我的真实示例是一个长管道,数据框不是首先创建的)。但是,谢谢,当数据在全球环境中时,这是有效的。 -
@alistaire 哇,这是一种非常有趣的方式。您介意解释一下在这种情况下括号是如何工作的吗?
-
见
?magrittr::`%>%`。通常管道将左侧的结果传递给右侧的第一个参数,但如果您将 RHS 包裹在大括号中,它只会将结果发送到您放置.的任何位置,这样您就可以使用它重复或跨子管道中的多个调用。