Столбцы, созданные с помощью geom_col
, формируются с использованием position_stack
, который складывает положительные и отрицательные значения отдельно, где положительные значения складываются вверх, а отрицательные значения вниз. Центральная группа, Neutral
в этом примере, настраивается на диапазон 0, устанавливая ее равной половине ее первоначального значения, а затем отображая ее как положительное и отрицательное значение. Кроме того, порядок групп необходимо изменить на положительные значения.
Этот подход будет полезен для представления результатов некоторых опросов, с которыми я работаю, поэтому я превратил его в функцию, чтобы сделать его более общим.
library(tidyverse)
#
# summarize groups and save counts in variable quality_cnt
#
diamonds_cnt <- diamonds %>%
mutate(quality = fct_recode(cut, "Very_Poor" = "Fair", "Poor" = "Good",
"Neutral" = "Very Good", "Good" = "Premium", "Excellent" = "Ideal")) %>%
select(color, clarity, quality) %>%
group_by(color, clarity, quality) %>% summarize(quality_cnt = n())
# make function to plot counts
plot_ratings <- function(survey, rated_item, rating_cnt, rating, rating_cat, facet = "wrap") {
#
# Input:
# rated_item = unquoted variable name of rated items
# rating = unquoted variable name of ratings for each rated_items;
# variable should be a factor ordered from lowest to highest
# rating_cnt = unquoted variable name of counts or frequencies for each rated_item
# rated_cat = unquoted variable name of categories of rated items
# facet = "grid" for all panels on one row or
# "wrap" to spread panels across multiple rows
#
# make arguments quosures
#
rated_item <- enquo(rated_item)
rating_cnt <- enquo(rating_cnt)
rating <- enquo(rating)
rating_cat <- enquo(rating_cat)
#
# If number of rating levels is odd, find middle rating
#
rating_levels <- levels(pull(survey, !!rating))
mid_level <- ceiling(length(rating_levels)/2)
mid_rating <- ifelse(length(rating_levels)%%2 == 1, rating_levels[mid_level], NA_character_)
#
# make local variabels for use with aes
# plot positive and negative columns separately
#
survey <- survey %>% mutate( rating_plt = !!rating, rating_cnt_plt = !!rating_cnt)
sp <- ggplot(survey, aes_(x = rated_item, fill = rating)) +
geom_col(data=filter(survey, !!rating %in% tail(rating_levels, mid_level)),
aes( y = ifelse(rating_plt == mid_rating, .5*rating_cnt_plt, rating_cnt_plt)),
position = position_stack(reverse = TRUE )) +
geom_col(data=filter(survey, !!rating %in% head(rating_levels, mid_level)),
aes( y = ifelse(rating_plt == mid_rating, -.5*rating_cnt_plt, -rating_cnt_plt)),
position = "stack") +
labs(y = rating_cnt) +
scale_fill_brewer(palette = "RdYlGn", direction = -1) +
coord_flip() +
switch(facet,
grid = facet_grid( facets=rating_cat, scales = "free_x"),
wrap = facet_wrap( facets=rating_cat, scales = "free_x"))
plot(sp)
}
#
# Use function to make charts
#
plot_ratings(diamonds_cnt, rated_item = color, rating_cnt = quality_cnt,
rating = quality, rating_cat = clarity, facet = "wrap")
, который дает график