简体   繁体   中英

How to change the positioning of one category in ggplot from top to bottom while keeping the order of the cells?

Although it seems to me a small issue, but i cannot get my head around it. I have the following data with three main variables: i) education (factor): represents three different level of education(1, 2, 3). ii) share (numeric): represents the % of people in the country for each level of education. iii) country (factor): represents 30 countries.

I plot the share of education in each country by re_ordering the lowest level of education by countries that have the lowest share in it to the ones that have the highest. The issue is while ggplot plot the order right, I would like the same positioning of the below upper-secondary (red color) to show at the bottom of the graph instead of at the top. It is more intuitive to read the graph in the order of below-upper secondary (bottom), upper-secondary (middle), tertiary (top). Could someone please guide through it?

Here is the code:

x$lab <- as.character(x$cntry2)
x$country = as.numeric(x$cntry2)
x$educ2= x$educ
x$educ = as.integer(x$educ)
x$educ = as.factor(x$educ)


labs <- x[!duplicated(x$country),]
labs <- labs[,c('country','lab')]

country_order <- x %>% 
  filter(educ == 1) %>%
  mutate(country = fct_reorder(factor(country), share, .desc = FALSE)) %>% 
  pull(country) %>%
  levels()
df2 <- x %>%
  mutate(country = fct_relevel(factor(country), country_order))


ggplot(df2, aes(x=country, y=share)) + 
  geom_col(aes(fill=educ2), color = "black") +
  labs(fill= "educ") +   
  theme_classic() +
  xlab("Country")+ ylab("%") +
  scale_x_discrete(labels=labs$lab[match(country_order,labs$country)]) +
  theme( 
    legend.position="bottom",
  )

Here is the data:

structure(list(educ = structure(c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 
    3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 
    1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 
    3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L
    ), .Label = c("1", "2", "3"), class = "factor"), cntry2 = structure(c(1L, 
    1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L, 4L, 4L, 4L, 5L, 5L, 5L, 6L, 6L, 
    6L, 7L, 7L, 7L, 8L, 8L, 8L, 9L, 9L, 9L, 10L, 10L, 10L, 11L, 11L, 
    11L, 12L, 12L, 12L, 13L, 13L, 13L, 14L, 14L, 14L, 15L, 15L, 15L, 
    16L, 16L, 16L, 17L, 17L, 17L, 18L, 18L, 18L, 19L, 19L, 19L, 20L, 
    20L, 20L, 21L, 21L, 21L, 22L, 22L, 22L, 23L, 23L, 23L, 24L, 24L, 
    24L, 25L, 25L, 25L, 26L, 26L, 26L, 27L, 27L, 27L, 28L, 28L, 28L, 
    29L, 29L, 29L), .Label = c("AU", "BE", "BG", "CH", "CY", "CZ", 
    "DK", "EE", "ES", "FI", "FR", "GR", "HR", "HU", "IE", "IS", "IT", 
    "LT", "LU", "LV", "NL", "NO", "PO", "PT", "RO", "SE", "SK", "SV", 
    "UK"), class = "factor"), share = c(14.9585723390695, 64.8311026131294, 
    20.2103250478011, 20.3203525363306, 37.9050825638106, 41.7745648998589, 
    20.5482068669118, 58.6719831908696, 20.7798099422186, 11.0478359908884, 
    52.7334851936219, 36.2186788154898, 24.5876872718117, 41.546015359436, 
    33.8662973687524, 8.1806499751285, 77.2156358812801, 14.6037141435914, 
    18.43684842358, 44.6831364124597, 36.8800151639603, 13.0409077472315, 
    58.1917820678991, 28.7673101848694, 42.6745525429736, 24.1881534644693, 
    33.1372939925571, 16.4818187731737, 46.3084628894816, 37.2097183373447, 
    22.0091736220768, 47.7329122490413, 30.2579141288819, 31.6958715347475, 
    40.8370856615852, 27.4670428036673, 19.5171138871772, 65.7890314268108, 
    14.693854686012, 15.620426612099, 63.1486925776748, 21.2308808102263, 
    27.79203576455, 33.4878715125424, 38.7200927229075, 29.0666986564299, 
    41.950575815739, 28.9827255278311, 36.0270124068613, 47.1984225312789, 
    16.7745650618598, 8.18044159594323, 60.960664858964, 30.8588935450928, 
    37.0050817095017, 37.4766935985084, 25.5182246919899, 15.7399902739504, 
    59.1482759419216, 25.111733784128, 19.2624176167015, 43.4944817814291, 
    37.2431006018693, 17.6501727404436, 44.6784798840967, 37.6713473754597, 
    10.0113985848549, 69.2765124631697, 20.7120889519754, 64.5252051582649, 
    21.4536928487691, 14.021101992966, 21.8502998519559, 62.6627857375856, 
    15.4869144104584, 11.4840104928012, 55.3435190932938, 33.172470413905, 
    4.21056255594574, 74.1410176960683, 21.648419747986, 15.6869892409901, 
    61.3851490387442, 22.9278617202657, 14.2357801080394, 49.3703276303246, 
    36.393892261636), lab = c("AU", "AU", "AU", "BE", "BE", "BE", 
    "BG", "BG", "BG", "CH", "CH", "CH", "CY", "CY", "CY", "CZ", "CZ", 
    "CZ", "DK", "DK", "DK", "EE", "EE", "EE", "ES", "ES", "ES", "FI", 
    "FI", "FI", "FR", "FR", "FR", "GR", "GR", "GR", "HR", "HR", "HR", 
    "HU", "HU", "HU", "IE", "IE", "IE", "IS", "IS", "IS", "IT", "IT", 
    "IT", "LT", "LT", "LT", "LU", "LU", "LU", "LV", "LV", "LV", "NL", 
    "NL", "NL", "NO", "NO", "NO", "PO", "PO", "PO", "PT", "PT", "PT", 
    "RO", "RO", "RO", "SE", "SE", "SE", "SK", "SK", "SK", "SV", "SV", 
    "SV", "UK", "UK", "UK"), country = c(1, 1, 1, 2, 2, 2, 3, 3, 
    3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 
    10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 14, 14, 14, 15, 15, 
    15, 16, 16, 16, 17, 17, 17, 18, 18, 18, 19, 19, 19, 20, 20, 20, 
    22, 22, 22, 23, 23, 23, 24, 24, 24, 25, 25, 25, 26, 26, 26, 27, 
    27, 27, 28, 28, 28, 29, 29, 29, 30, 30, 30), educ2 = structure(c(1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 
    3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 
    1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 
    2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 
    3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 1L, 2L, 3L, 
    1L, 2L, 3L, 1L, 2L, 3L), .Label = c("Below upper-secondary", 
    "Upper-secondary", "Tertiary"), class = "factor")), row.names = c(NA, 
    -87L), class = c("tbl_df", "tbl", "data.frame"))

You can use forcats::fct_rev :

library(ggplot2)

ggplot(x, aes(x=country, y=share, 
              fill = forcats::fct_rev(factor(as.integer(educ2))))) + 
  geom_col(color = "black") +
  labs(fill= "educ")  +
  theme_classic() +
  xlab("Country")+ ylab("%") +
  theme(legend.position="bottom")

在此处输入图像描述

I have removed the code for filtering and labelling of x-axis to keep this simple. You can add that in as in your post if needed.


To just reverse the color you can use position = position_stack(reverse = TRUE)

ggplot(x, aes(x=country, y=share, 
              fill = factor(as.integer(educ2)))) + 
  geom_col(color = "black", position = position_stack(reverse = TRUE)) +
  labs(fill= "educ")  +
  theme_classic() +
  xlab("Country")+ ylab("%") +
  theme(legend.position="bottom")

在此处输入图像描述

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM