Group lowest values and sort this stacked area graph

纵然是瞬间 提交于 2019-12-24 12:51:49

问题


I have a time series of production in countries over time. I made this stacked area graph with the full data:

The problem is that it isn't very readable (since using all countries means I can't have a legend) so I thought that I wanted to somehow group the lowest producing countries and sort the graph on the production from highest to lowest. I think that grouping and sorting based on the last years (2017) values would make the most sense, since the production is usually much higher.

Here is a subset of the data

structure(list(country = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 
3L, 3L, 3L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 
4L, 4L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 
6L, 6L, 6L, 6L, 6L, 6L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 7L, 
8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 8L, 9L, 9L, 9L, 9L, 9L, 9L, 
9L, 9L, 9L, 9L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 10L, 
10L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L, 11L), .Label = c("Democratic People's Republic of Korea", 
"Democratic Republic of the Congo", "Dominica", "Dominican Republic", 
"Ecuador", "Egypt", "El Salvador", "Eswatini", "Fiji", "France", 
"French Guiana"), class = "factor"), year = c(1961, 1962, 1963, 
1964, 1965, 1966, 1967, 1968, 1969, 1970, 1961, 1962, 1963, 1964, 
1965, 1966, 1967, 1968, 1969, 1970, 1961, 1962, 1963, 1964, 1965, 
1966, 1967, 1968, 1969, 1970, 1961, 1962, 1963, 1964, 1965, 1966, 
1967, 1968, 1969, 1970, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 
1968, 1969, 1970, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 
1969, 1970, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 
1970, 1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 
1961, 1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1961, 
1962, 1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970, 1961, 1962, 
1963, 1964, 1965, 1966, 1967, 1968, 1969, 1970), value = c(1.245, 
1.305, 1.43, 1.505, 1.315, 1.465, 1.365, 1.32, 1.62, 1.61, 0.37, 
0.36, 0.35, 0.35, 0.35, 0.39, 0.41, 0.425, 0.43, 0.4281, 0.00013, 
0.00013, 0.00014, 0.00014, 0.00015, 0.00015, 0.00016, 0.00016, 
0.00016, 0.00016, 0.050233, 0.048464, 0.045583, 0.043198, 0.0375, 
0.0425, 0.038548, 0.04, 0.043, 0.045, 0.153047, 0.138365, 0.191953, 
0.12878, 0.191363, 0.174905, 0.227769, 0.173892, 0.211189, 0.256067, 
1.61713, 2.00369, 1.867, 1.934212, 2.141, 2.376, 2.167, 2.3, 
2.368, 2.397, 0.1763, 0.2139, 0.207077, 0.191611, 0.203006, 0.265914, 
0.20884, 0.25755, 0.278967, 0.363078, 0.029991, 0.03486, 0.031751, 
0.030481, 0.031751, 0.035017, 0.062595, 0.051709, 0.058107, 0.062595, 
0.00022, 0.00022, 0.00025, 4e-04, 4e-04, 4e-04, 0.001996, 0.00375, 
0.002, 0.000711, 2.48, 1.86656, 3.87707, 2.1088, 3.4678, 4.3402, 
4.15219, 5.38958, 5.73, 7.491, 2e-04, 0.000405, 7e-05, 9.5e-05, 
9.5e-05, 0.000111, 0.00011, 8.5e-05, 1e-04, 0.000225)), class = c("tbl_df", 
"tbl", "data.frame"), row.names = c(NA, -110L))

Here is my code

library(ggplot2)
library(tidyverse)

plot_data %>%
  ggplot(aes(x=year, y=value, fill=country)) + 
  geom_area()

I am not sure how to do this, but I started by making a rank based on the last year.

ordered_plot_data = plot_data %>% 
  filter(year == last(year)) %>% 
  arrange(desc(value)) %>% 
  mutate(rank = row_number())

So say I wanted to have three countries shown and the rested grouped into "others":

n_countries = 3

first_part = ordered_plot_data %>% 
  top_n(n_countries, value)

last_part = ordered_plot_data %>%
  top_n(-(length(unique(ordered_plot_data$country))-n_countries), value) %>% 
  summarise(country = "Other",
            year = first(year),
            value = sum(value),
            rank = n_countries + 1)

joined_data = rbind(first_part, last_part)

This gives me grouped data which is ordered but only for 2017. So I thought that I could use this somehow and for each year group according to the grouping I have made from 2017, but of course this just seem way too complicated and I over my head I would like some help with an easier way to solve this.


回答1:


The key thing is that you need to use that ordering to sort a factor variable. By default the first level of a factor is plotted at the top so you want it to go from "Other" through to the highest value. The following code should work for you!

library(ggplot2)
library(tidyverse)

plot_order = plot_data %>% 
  mutate(country = as.character(country)) %>%
  filter(year == last(year)) %>% 
  arrange(desc(value)) %>% 
  mutate(rank = row_number())

n_countries = 3

final_plot <- plot_data %>% 
  mutate(country = as.character(country)) %>%
  mutate(plot_label = ifelse(country %in% plot_order$country[1:n_countries], country, 'Other')) %>%
  mutate(plot_label = factor(plot_label, levels = c('Other', rev(plot_order$country[1:n_countries])))) %>%
  group_by(plot_label, year) %>%
  summarise(value = sum(value)) 

final_plot %>%
  ggplot(aes(x=year, y=value, fill=plot_label)) + 
  geom_area()


来源:https://stackoverflow.com/questions/58221360/group-lowest-values-and-sort-this-stacked-area-graph

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!