Skip to content

Commit

Permalink
Minor fixes for the survey analysis scripts (#126)
Browse files Browse the repository at this point in the history
* Update plot_functions.R

Exclude options correctly from matrix questions.

* Update plot_functions

Update regex to correctly extract strings from multi-select questions

* Add more ordering options and minor fixes
  • Loading branch information
jayoung-lee authored Dec 18, 2023
1 parent 2d0fbd0 commit 7df3513
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 40 deletions.
8 changes: 5 additions & 3 deletions survey-analysis/plot_constants.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ primary = "#1075C2"
gray100 = "#D5D7DA"
gray600 = "#60646B"
color_palette_flutter_5 = c(flutter_blue, primary_dark, primary, gray100, gray600)
color_palette_monochrome = rep(primary, 20)
color_palette_monochrome = rep(primary, 50)
color_palette_5 = c("#003f5c", "#58508d", "#bc5090", "#ff6361", "#ffa600")
color_palette_8 = c("#003f5c", "#2f4b7c", "#665191", "#a05195", "#d45087", "#f95d6a", "#ff7c43", "#ffa600")
color_palette_19 = c("#512DA8", "#009688", "#FFC107", "#607D8B", "#FF5252", "#303F9F", "#388E3C", "#F57C00",
Expand All @@ -26,6 +26,8 @@ satisfaction_plus1 = c("Very satisfied", "Somewhat satisfied", "Neither satisfi
"I don’t have enough experience with it to answer this question")
satisfaction_wrap = c("Very \nsatisfied", "Somewhat \nsatisfied", "Neither satisfied \nnor dissatisfied",
"Somewhat \ndissatisfied", "Very \ndissatisfied")
agree = c("Strongly agree", "Somewhat agree", "Neither agree nor disagree", "Somewhat disagree", "Strongly disagree")
agree_wrap = c("Strongly\nagree", "Somewhat\nagree", "Neither agree\nnor disagree", "Somewhat\ndisagree", "Strongly\ndisagree")
usefulness = c("Extremely useful", "Very useful", "Somewhat useful", "Slightly useful", "Not at all useful")
difficulty = c("Very easy", "Somewhat easy", "Neither easy nor difficult", "Somewhat difficult", "Very difficult")
frequency = c("Almost always", "Often", "Sometimes", "Rarely", "Nearly never")
Expand All @@ -37,7 +39,7 @@ dev_stage = c("Published a complete production app", "Published a demo
"I am not developing an app for this platform in Flutter")
experience_level = c("No experience", "Awareness", "Novice", "Intermediate", "Advanced", "Expert")
tenure = c("Less than 3 months", "3 to 6 months", "6 to 12 months", "Over a year")
company_size = c("1 person", "2-9 employees", "10-99 employees", "100-999 employees",
company_size = c("1 employee", "2-9 employees", "10-99 employees", "100-999 employees",
"1,000-9,999 employees", "Over 10,000 employees")
team_size = c("Just me", "2-4", "5-9", "10-19", "20-49", "More than 50")
mau = c("1-999", "1,000 - 9,999", "10,000 - 99,999", "100,000 - 999,999", "1million+")
mau = c("1-999", "1,000-9,999", "10,000-99,999", "100,000-999,999", "1 million+")
118 changes: 81 additions & 37 deletions survey-analysis/plot_functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -23,33 +23,38 @@ f.setcolors <- function(colors, length) {
}

# ------------------------------ Presets ------------------------------

add_conf_intv <- geom_errorbar(aes(ymin = p - me, ymax = p + me),
position = position_dodge(width = 0.9),
width = 0.1,
colour = "grey40")
add_text <- geom_text_repel(aes(label = paste0(round(100 * p), "% ")),
add_text <- geom_text_repel(aes(label = paste0(round(100 * p, digits = 1), "% ")),
position = position_dodge(width = 0.9),
direction = "x",
bg.color = "grey30",
bg.r = 0.01,
size = 3,
hjust = 0,
colour = "white")
add_text_stacked <- geom_text_repel(aes(label = paste0(round(100*p), "% ")),
hjust = 1,
vjust = 1,
add_text_stacked <- geom_text_repel(aes(label = paste0(round(100*p, digits = 1), "% ")),
vjust = 0,
hjust = 0.5,
size = 3,
colour = "white",
bg.color = "grey30",
bg.r = 0.01,
position = "stack",
point.padding = NA,
ylim = c(0, 1))
theme_custom <- theme_minimal() +
theme(text = element_text(family = "Roboto", size = 10),
plot.title = element_text(family = "Roboto", size = 10),
axis.title = element_blank())
theme(text = element_text(family = "Roboto", size = 12),
plot.title = element_text(family = "Roboto", size = 12),
axis.title = element_blank())
theme_custom_top <- theme_custom +
theme(legend.position="top")
add_percent_scale <- scale_y_continuous(labels = scales::percent,
name = "")

wrap_text <- scale_x_discrete(labels = function(x) str_wrap(x, width = 40))

# ------------------------------ Plotting functions ------------------------------

Expand Down Expand Up @@ -107,11 +112,11 @@ f.singlechoice <- function(qNum,
geom_bar(aes(fill = rating), stat = "identity", width = 0.8) +
add_conf_intv + add_text +
ggtitle(plot_title)+
scale_x_discrete(limits = rev(levels(set$rating))) +
scale_x_discrete(limits = rev(levels(set$rating))) + # , labels = function(x) str_wrap(x, width = 40)
scale_y_continuous(labels = scales::percent) +
scale_fill_manual(values = palette, guide = F) + # c(primary, gray600)
scale_fill_manual(values = palette, guide = "none") + # c(primary, gray600)
coord_flip() +
theme_custom
theme_custom

if(!is.null(filename)) {
ggsave(paste0("figures/", filename, ".png"),
Expand Down Expand Up @@ -144,7 +149,7 @@ f.singlechoice_breakout <- function(qNum,
data = NULL,
title = NULL,
orders = NULL,
by = NULL,
orders_bo = NULL,
colors = NULL,
labels = NULL,
q_exclude = c(),
Expand Down Expand Up @@ -174,25 +179,37 @@ f.singlechoice_breakout <- function(qNum,
group_by(category) %>%
mutate(category.n = paste0(category, "\n(N = ", sum(n), ")"))

# TODO: Make it possible to order the categories too (add another parameter)
if(is.null(orders)) {
rating_order_by_n <- set %>%
group_by(rating) %>%
summarise(sump = sum(p)) %>%
arrange(desc(sump)) %>%
select(rating) %>%
dplyr::select(rating) %>%
sapply(factor)
set$rating <- factor(set$rating, levels = rating_order_by_n)
category_order_by_n <- set %>% ungroup() %>%
filter(rating == rating_order_by_n[1]) %>%
arrange(desc(p)) %>%
select(category.n) %>%
dplyr::select(category.n) %>%
sapply(factor)
set$category.n <- factor(set$category.n, levels = category_order_by_n)
} else {
set$rating <- factor(set$rating, levels = orders)
category_order_by_factor <- set %>% ungroup() %>%
filter(rating == levels(set$rating)[1]) %>%
arrange(desc(p)) %>%
dplyr::select(category.n) %>%
sapply(factor)
set$category.n <- factor(set$category.n, levels = category_order_by_factor)
}

if(!is.null(orders_bo)) {
set$category <- factor(set$category, levels = orders_bo)
x = set[order(set$category), "category.n"]
set$category.n <- factor(set$category.n, levels = unique(x)$category.n)
}


palette <- f.setcolors(colors, length(unique(set$rating)))

if(is.null(labels)) {
Expand All @@ -201,11 +218,12 @@ f.singlechoice_breakout <- function(qNum,

p <- ggplot(set, aes(x = category.n, y = p, fill = rating)) +
geom_bar(position = "fill", stat = "identity", width = 0.8) +
ggtitle(plot_title)+
ggtitle(plot_title) +
scale_fill_manual(values = palette, labels = labels) +
guides(fill = guide_legend(reverse = T)) +
add_text_stacked + add_percent_scale +
coord_flip() + theme_custom_top
coord_flip() +
theme_custom_top

if(!is.null(filename)) {
ggsave(paste0("figures/", filename, ".png"),
Expand Down Expand Up @@ -240,14 +258,18 @@ f.multiplechoice <- function(qNum,
height = 4) {

if(is.null(data)) data <- all

select <- dplyr::select

choices <- sub('.+-(.+)',
'\\1',
questions %>%
select(starts_with(qNum), -ends_with("TEXT"), -ends_with("RANK")))
choices <- str_remove(
str_extract(
questions %>%
select(starts_with(paste0(qNum,"_")), -ends_with("TEXT"), -ends_with("RANK")),
"-[1-9a-zA-Z].+"),
"-")

set.wide <- data %>%
select(starts_with(qNum)) %>%
select(starts_with(paste0(qNum,"_"))) %>%
select(-ends_with("TEXT"), -ends_with("RANK")) %>%
filter_all(any_vars(.!="")) %>%
rename_at(vars(starts_with(qNum)), ~choices)
Expand Down Expand Up @@ -283,14 +305,14 @@ f.multiplechoice <- function(qNum,
p <- ggplot(set , aes(x = category, y = p)) +
geom_bar(stat = "identity", aes(fill = category), width = 0.8) +
ggtitle(plot_title) +
scale_fill_manual(values = palette, guide = F) +
scale_fill_manual(values = palette, guide = "none") +
add_conf_intv + add_text + add_percent_scale +
xlab("") +
coord_flip() +
theme_custom
theme_custom + wrap_text

if(!is.null(filename)) ggsave(paste0("figures/", filename, ".png"), p, width = width, height = height)

print(set)
return(p)
}

Expand All @@ -307,25 +329,34 @@ f.multiplechoice <- function(qNum,
# labels* (Add a vector of labels, if you want to include custom labels for a smaller legend.)
# width, height (Set the size of output plot)

# filename = NULL; data = NULL; exclude = c(); title = NULL; orders = NULL; colors = NULL; labels = NULL; width = 8; height = 4

f.matrix <- function(qNum,
filename = NULL,
data = NULL,
exclude = c(),
title = NULL,
orders = NULL,
orders2 = NULL,
colors = NULL,
labels = NULL,
width = 8,
height = 4) {
height = 4,
table = FALSE) {

if(is.null(data)) data <- all

select <- dplyr::select

choices <- sub('.+-(.+)',
'\\1',
questions %>% dplyr::select(starts_with(qNum)) %>% dplyr::select(-ends_with("TEXT")))
choices <- str_remove(
str_extract(
questions %>%
select(starts_with(paste0(qNum,"_")), -ends_with("TEXT"), -ends_with("RANK")),
"-[a-zA-Z].+"),
"-")

set.wide <- data %>%
select(starts_with(qNum)) %>%
select(starts_with(paste0(qNum,"_"))) %>%
select(-ends_with("TEXT")) %>%
rename_at(vars(starts_with(qNum)), ~choices) %>%
filter_all(any_vars(.!=""))
Expand All @@ -335,13 +366,13 @@ f.matrix <- function(qNum,
set <- set.wide %>%
gather("category") %>%
group_by(category, value) %>%
filter(value != "", !value %in% exclude) %>%
filter(value != "", !value %in% exclude, !category %in% exclude) %>%
tally() %>%
mutate(p = n/sum(n)) %>%
mutate(me = 1.96 * sqrt(p * (1-p) / n))

# TODO: Make it possible to order the categories too (add another parameter)
if(is.null(orders)) {
if(is.null(orders) & is.null(orders2)) {
value_order_by_n <- set %>%
group_by(value) %>%
summarise(sump = sum(p)) %>%
Expand All @@ -355,14 +386,26 @@ f.matrix <- function(qNum,
select(category) %>%
sapply(factor)
set$category <- factor(set$category, levels = category_order_by_n)
} else {
} else if (!is.null(orders) & is.null(orders)) {
set$value <- factor(set$value, levels = orders)
category_order <- set %>%
filter(value == orders[1]) %>%
arrange(desc(p)) %>%
select(category) %>%
sapply(factor)
set$category <- factor(set$category, levels = category_order)
set$category <- factor(set$category, levels = category_order)
} else if(is.null(orders) & !is.null(orders2)) {
value_order_by_n <- set %>%
group_by(value) %>%
summarise(sump = sum(p)) %>%
arrange(desc(sump)) %>%
select(value) %>%
sapply(factor)
set$value <- factor(set$value, levels = value_order_by_n)
set$category <- factor(set$category, levels = orders2)
} else if(!is.null(orders) & !is.null(orders2)) {
set$value <- factor(set$value, levels = orders)
set$category <- factor(set$category, levels = orders2)
}

palette = f.setcolors(colors, length(unique(set$value)))
Expand All @@ -384,12 +427,13 @@ f.matrix <- function(qNum,
add_text_stacked +
add_percent_scale +
coord_flip() +
theme_custom_top + guides(fill = guide_legend(reverse = T))
theme_custom_top + guides(fill = guide_legend(reverse = T)) +
wrap_text

if(!is.null(filename)) ggsave(paste0("figures/", filename, ".png"),
p,
width = width,
height = height)

return(p)
if(table == TRUE) {return(list(set, p))} else {return (p)}
# return(p)
}

0 comments on commit 7df3513

Please sign in to comment.