英文:
Reorder factor levels after pivot_longer
问题
我正在尝试在使用pivot_longer
后重新排列tibble中的因子水平。最终目标是在ggplot
中绘制数据,并使图表中的图例与线条的顺序相对应。我不想每次手动分配水平。我希望根据枢轴tibble中的一个变量对因子进行排序。但该列对于每个因子都有多个值...
这应该比我现在做的更容易!
这是我的代码:
df <- tibble(Year=c(1900, 1901, 1903), Foo=c(9,30, 60), Bar=c(3,20, 50)) %>%
pivot_longer(!Year, names_to = "Name", values_to = "Count")
df$Name <- factor(df$Name)
然后levels(df$Name)
返回默认的字母顺序[1] "Bar" "Foo"
。但我想根据tibble的Count
列中每个因子的最大值重新排序它,即在这种情况下是[1] "Foo" "Bar"
。
所有这些都是为了绘制数据并将图例与图表中线条的顺序对齐(而不手动设置水平的顺序)。这是我的ggplot
代码:
p <- ggplot(df, aes(x = Year, y = Count)) +
geom_line(aes(colour = Name))
p
这是绘图:
帮助?谢谢!
英文:
I am trying to reorder factor levels in a tibble after using pivot_longer
. Ultimately, the goal is to plot the data in ggplot
and have the legend align with the order of the lines in the chart. I don't want to manually assign the levels each time. I'd like the factor ordered by one of the variables in the pivoted tibble. But that column has multiple values for each factor...
This has to be easier than I am making it!
Here is my code:
df <- tibble(Year=c(1900, 1901, 1903), Foo=c(9,30, 60), Bar=c(3,20, 50)) %>%
pivot_longer(!Year, names_to = "Name", values_to = "Count")
df$Name <- factor(df$Name)
Then levels(df$Name)
returns the default alphabetical order of [1] "Bar" "Foo"
. But I'd like to reorder that based on the maximum value each factor has in the Count
column of the tibble, i.e. [1] "Foo" "Bar"
in this case.
All of this is so I can plot the data and align the legend to the order of the lines in the chart (without setting the order of the levels manually). Here is my ggplot
code:
p <- ggplot(df, aes(x = Year, y = Count)) +
geom_line(aes(colour = Name))
p
And here is the plot:
Help? Thanks!
答案1
得分: 1
更新
有点繁琐,但我们可以首先创建一个向量,以根据每个因素的最大值(这里是 foo = 60
,bar = 50
)来获取级别顺序,然后将其用作级别:
fac_order <- df1 %>%
pivot_longer(!Year, names_to = "Name", values_to = "Count") %>%
distinct(Count, .keep_all = TRUE) %>%
slice_max(Count, by = Name) %>%
arrange(desc(Count)) %>%
pull(Name)
df1 %>%
pivot_longer(!Year, names_to = "Name", values_to = "Count") %>%
mutate(Name = factor(Name, levels = fac_order)) %>%
ggplot(aes(x = Year, y = Count)) +
geom_line(aes(colour = Name))
结果保持不变。
第一个版本
你可以使用以下代码:
library(tidyverse)
df1 <- tibble(Year=c(1900, 1901, 1903), Foo=c(9,30, 60), Bar=c(3,20, 50))
df1 %>%
pivot_longer(!Year, names_to = "Name", values_to = "Count") %>%
mutate(Name = fct_reorder(Name, Count, .desc = TRUE)) %>%
ggplot(aes(x = Year, y = Count)) +
geom_line(aes(colour = Name))
这将返回:
英文:
Update
A little bit cumbersome, but we can first create a vector to get the levels order based on the maximum values per factor (here: foo = 60
, bar = 50
) and then use it as levels:
fac_order <- df1 %>%
pivot_longer(!Year, names_to = "Name", values_to = "Count") %>%
distinct(Count, .keep_all = TRUE) %>%
slice_max(Count, by = Name) %>%
arrange(desc(Count)) %>%
pull(Name)
df1 %>%
pivot_longer(!Year, names_to = "Name", values_to = "Count") %>%
mutate(Name = factor(Name, levels = fac_order)) %>%
ggplot(aes(x = Year, y = Count)) +
geom_line(aes(colour = Name))
The result remains the same.
First Version
You could use
library(tidyverse)
df1 <- tibble(Year=c(1900, 1901, 1903), Foo=c(9,30, 60), Bar=c(3,20, 50))
df1 %>%
pivot_longer(!Year, names_to = "Name", values_to = "Count") %>%
mutate(Name = fct_reorder(Name, Count, .desc = TRUE)) %>%
ggplot(aes(x = Year, y = Count)) +
geom_line(aes(colour = Name))
This returns
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论