问题描述
可以说,在R中,我有一个数据框架字母,数字和动物,我想用图形来检查所有三者之间的关系。 library(dplyr)
library(ggplot2)
library(gridExtra)
set.seed(33)
my_df< - data.frame(
letters = c(letters [1:10],letters [6:15],letters [ (''''''),
animals = c(rep('sheep',10),rep('cow',10),rep('horse',10)),
numbers = rnorm 1:30)
)
ggplot(my_df,aes(x = letters,y = numbers))+ geom_point()+
facet_wrap(〜animals,ncol = 1, scale ='free_x')
我会看起来像。然而,我想要x轴的顺序依赖于y轴的顺序。这很容易做到没有方面,按照这个
尽管我并不特别喜欢这个解决方案,因为它不容易推广到有很多方面的情况。
我宁愿做一些像
ggplot(my_df,aes(x = y_ordered_by_facet(letters,by = numbers),y = numbers))+ geom_point ()+
facet_wrap(〜animals,ncol = 1,scales ='free_x')
其中y_ordered是一些函数,巧妙地命令字母因子为按照与数字相同的顺序排列。
有些东西接近于此,但似乎不起作用。
ggplot(my_df,aes(x = reorder(字母,数字),y =数字))+
geom_point()+ facet_wrap(〜animals,ncol = 1 ,scale ='free_x')
这并不奏效,因为订单最终会生效,而不是在方面包装之后,并且因此将标签放在不是每个面板的正确顺序上。
任何聪明的想法?
我发现在处理每个组中的不同因子级别时,dplyr不能很好地处理 group_by()
。所以一个解决方法是考虑创建一个新的因子,这对每个动物字母组合都是独一无二的。首先,我们创建一个带有动物和字母的交互变量,并确定每个动物字母的正确顺序。 ; - my_df%>%
group_by(animals)%>%
do(data_frame(al = levels(reorder(interaction(。$ animals,。$ letters,drop = TRUE)数字))))%>%
pull(al)
现在我们创建在我们想要绘制的数据中使用交互变量,使用这个新的顺序,最后改变标签,使它们看起来再次像字母一样
my_df%>%
mutate(al =因子(交互(动物,字母),levels = new_order))%>%
ggplot(aes(x = al,y = numbers)) +
geom_point()+ facet_wrap(〜animals,ncol = 1,scales ='free_x')+
scale_x_discrete(breaks = new_order,labels = gsub(^。* \\\。, ,new_order))
Lets say, in R, I have a data frame letters, numbers and animals and I want to examine the relationship between all three graphically. I could do something like.
library(dplyr)
library(ggplot2)
library(gridExtra)
set.seed(33)
my_df <- data.frame(
letters = c(letters[1:10], letters[6:15], letters[11:20]),
animals = c(rep('sheep', 10), rep('cow', 10), rep('horse', 10)),
numbers = rnorm(1:30)
)
ggplot(my_df, aes(x = letters, y = numbers)) + geom_point() +
facet_wrap(~animals, ncol = 1, scales = 'free_x')
I'd get something that looks like.
However, I want the order of the x axis to be dependent on the order of the y-axis. This is easy enough to do without facets, as per this example.I can even make an ordered figure for each animal and then bind them together with grid.arrange as in this example
my_df_shp <- my_df %>% filter(animals == 'sheep')
my_df_cow <- my_df %>% filter(animals == 'cow')
my_df_horse <- my_df %>% filter(animals == 'horse')
my_df_shp1 <- my_df_shp %>% mutate(letters = reorder(letters, numbers))
my_df_cow1 <- my_df_cow %>% mutate(letters = reorder(letters, numbers))
my_df_horse1 <- my_df_horse %>% mutate(letters = reorder(letters, numbers))
p_shp <- ggplot(my_df_shp1, aes(x = letters, y = numbers)) + geom_point()
p_cow <- ggplot(my_df_cow1, aes(x = letters, y = numbers)) + geom_point()
p_horse <- ggplot(my_df_horse1, aes(x = letters, y = numbers)) + geom_point()
grid.arrange(p_shp, p_cow, p_horse, ncol = 1)
I don't particularly like this solution though, because it isn't easily generalizable to cases where there are a lot of facets.
I'd rather do something like ggplot(my_df, aes(x = y_ordered_by_facet(letters, by = numbers), y = numbers)) + geom_point() + facet_wrap(~animals, ncol = 1, scales = 'free_x')
Where y_ordered is some function that cleverly orders the letters factor to be in the same order as the numbers.
Something that gets close to this, but doesn't quite seem to work is
ggplot(my_df, aes(x = reorder(letters, numbers), y = numbers)) +
geom_point() + facet_wrap(~animals, ncol = 1, scales = 'free_x')
That doesn't quite work because the order ends up taking effect before, rather than after the facet wrapping and thus putting the labels in not quite the right order for each panel.
Any clever ideas?
I've found dplyr doesn't work super well with group_by()
when dealing with different factor levels in each of the groups. So one work around is thinking of creating a new factor that's unique for each animal-letter combination and ordering that. First, we create an interaction variable with animal+letter and determine the proper order for each of the letters for the animals
new_order <- my_df %>%
group_by(animals) %>%
do(data_frame(al=levels(reorder(interaction(.$animals, .$letters, drop=TRUE), .$numbers)))) %>%
pull(al)
Now we create the interaction variable in the data we want to plot, use this new ordering, and finally change the labels so they look like just the letters again
my_df %>%
mutate(al=factor(interaction(animals, letters), levels=new_order)) %>%
ggplot(aes(x = al, y = numbers)) +
geom_point() + facet_wrap(~animals, ncol = 1, scales = 'free_x') +
scale_x_discrete(breaks= new_order, labels=gsub("^.*\\.", "", new_order))
这篇关于通过y轴值在ggplot的每个方面排序因子的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!