如何使用 forcats 根据另一个变量的子集(方面)重新排序一个因子?
How to reorder a factor based on a subset (facets) of another variable, using forcats?
forcats
vignette 表示
The goal of the forcats package is to provide a suite of useful tools
that solve common problems with factors
事实上,其中一个工具是通过另一个变量对因子重新排序,这是绘制数据时非常常见的用例。我试图使用 forcats
来完成此操作,但在多面图的情况下。也就是说,我想通过其他变量重新排序一个因子,但只使用数据的一个子集。这是一个代表:
library(tidyverse)
ggplot2::diamonds %>%
group_by(cut, clarity) %>%
summarise(value = mean(table, na.rm = TRUE)) %>%
ggplot(aes(x = clarity, y = value, color = clarity)) +
geom_segment(aes(xend = clarity, y = min(value), yend = value),
size = 1.5, alpha = 0.5) +
geom_point(size = 3) +
facet_grid(rows = "cut", scales = "free") +
coord_flip() +
theme(legend.position = "none")
这段代码生成的情节接近我想要的:
但我希望净度轴按值排序,这样我可以快速找出具有最高值的净度。但是每个方面都意味着不同的顺序。所以我想选择按特定方面内的值对图进行排序。
当然,直接使用 forcats
在这种情况下不起作用,因为它会根据所有值而不只是特定方面的值对因子重新排序。让我们开始吧:
# Inserting this line right before the ggplot call
mutate(clarity = forcats::fct_reorder(clarity, value)) %>%
然后生成这个图。
当然,它根据整个数据对因子进行了重新排序,但是如果我希望绘图按 "Ideal" 切割的值排序怎么办?我该如何使用 forcats
?
我目前的解决方案如下:
ggdf <- ggplot2::diamonds %>%
group_by(cut, clarity) %>%
summarise(value = mean(table, na.rm = TRUE))
# The trick would be to create an auxiliary factor using only
# the subset of the data I want, and then use the levels
# to reorder the factor in the entire dataset.
#
# Note that I use good-old reorder, and not the forcats version
# which I could have, but better this way to emphasize that
# so far I haven't found the advantage of using forcats
reordered_factor <- reorder(ggdf$clarity[ggdf$cut == "Ideal"],
ggdf$value[ggdf$cut == "Ideal"])
ggdf$clarity <- factor(ggdf$clarity, levels = levels(reordered_factor))
ggdf %>%
ggplot(aes(x = clarity, y = value, color = clarity)) +
geom_segment(aes(xend = clarity, y = min(value), yend = value),
size = 1.5, alpha = 0.5) +
geom_point(size = 3) +
facet_grid(rows = "cut", scales = "free") +
coord_flip() +
theme(legend.position = "none")
产生我想要的东西。
但我想知道是否有更多 elegant/clever 的方法可以使用 forcats
。
如果你想根据特定方面的值重新排序 clarity
,你必须告诉 forcats::fct_reorder()
这样做,例如,
mutate(clarity = forcats::fct_reorder(
clarity, filter(., cut == "Ideal") %>% pull(value)))
它仅使用 "Ideal" 方面的值进行重新排序。
因此,
ggplot2::diamonds %>%
group_by(cut, clarity) %>%
summarise(value = mean(table, na.rm = TRUE)) %>%
mutate(clarity = forcats::fct_reorder(
clarity, filter(., cut == "Ideal") %>% pull(value))) %>%
ggplot(aes(x = clarity, y = value, color = clarity)) +
geom_segment(aes(xend = clarity, y = min(value), yend = value),
size = 1.5, alpha = 0.5) +
geom_point(size = 3) +
facet_grid(rows = "cut", scales = "free") +
coord_flip() +
theme(legend.position = "none")
创造
根据要求。
forcats
vignette 表示
The goal of the forcats package is to provide a suite of useful tools that solve common problems with factors
事实上,其中一个工具是通过另一个变量对因子重新排序,这是绘制数据时非常常见的用例。我试图使用 forcats
来完成此操作,但在多面图的情况下。也就是说,我想通过其他变量重新排序一个因子,但只使用数据的一个子集。这是一个代表:
library(tidyverse)
ggplot2::diamonds %>%
group_by(cut, clarity) %>%
summarise(value = mean(table, na.rm = TRUE)) %>%
ggplot(aes(x = clarity, y = value, color = clarity)) +
geom_segment(aes(xend = clarity, y = min(value), yend = value),
size = 1.5, alpha = 0.5) +
geom_point(size = 3) +
facet_grid(rows = "cut", scales = "free") +
coord_flip() +
theme(legend.position = "none")
这段代码生成的情节接近我想要的:
但我希望净度轴按值排序,这样我可以快速找出具有最高值的净度。但是每个方面都意味着不同的顺序。所以我想选择按特定方面内的值对图进行排序。
当然,直接使用 forcats
在这种情况下不起作用,因为它会根据所有值而不只是特定方面的值对因子重新排序。让我们开始吧:
# Inserting this line right before the ggplot call
mutate(clarity = forcats::fct_reorder(clarity, value)) %>%
然后生成这个图。
当然,它根据整个数据对因子进行了重新排序,但是如果我希望绘图按 "Ideal" 切割的值排序怎么办?我该如何使用 forcats
?
我目前的解决方案如下:
ggdf <- ggplot2::diamonds %>%
group_by(cut, clarity) %>%
summarise(value = mean(table, na.rm = TRUE))
# The trick would be to create an auxiliary factor using only
# the subset of the data I want, and then use the levels
# to reorder the factor in the entire dataset.
#
# Note that I use good-old reorder, and not the forcats version
# which I could have, but better this way to emphasize that
# so far I haven't found the advantage of using forcats
reordered_factor <- reorder(ggdf$clarity[ggdf$cut == "Ideal"],
ggdf$value[ggdf$cut == "Ideal"])
ggdf$clarity <- factor(ggdf$clarity, levels = levels(reordered_factor))
ggdf %>%
ggplot(aes(x = clarity, y = value, color = clarity)) +
geom_segment(aes(xend = clarity, y = min(value), yend = value),
size = 1.5, alpha = 0.5) +
geom_point(size = 3) +
facet_grid(rows = "cut", scales = "free") +
coord_flip() +
theme(legend.position = "none")
产生我想要的东西。
但我想知道是否有更多 elegant/clever 的方法可以使用 forcats
。
如果你想根据特定方面的值重新排序 clarity
,你必须告诉 forcats::fct_reorder()
这样做,例如,
mutate(clarity = forcats::fct_reorder(
clarity, filter(., cut == "Ideal") %>% pull(value)))
它仅使用 "Ideal" 方面的值进行重新排序。
因此,
ggplot2::diamonds %>%
group_by(cut, clarity) %>%
summarise(value = mean(table, na.rm = TRUE)) %>%
mutate(clarity = forcats::fct_reorder(
clarity, filter(., cut == "Ideal") %>% pull(value))) %>%
ggplot(aes(x = clarity, y = value, color = clarity)) +
geom_segment(aes(xend = clarity, y = min(value), yend = value),
size = 1.5, alpha = 0.5) +
geom_point(size = 3) +
facet_grid(rows = "cut", scales = "free") +
coord_flip() +
theme(legend.position = "none")
创造
根据要求。