Winter 2025 Intermediate R Workshop Survey Responses

Number of responses

Code
library(tidyverse)
library(bslib)
library(shiny)
library(bsicons)
source("scripts/helper_functions.R")

# list of workshop IDs to filter results
workshops <- c("2025-02-18-ucsb-intermediater")

results <- read_csv("data-joined/all_workshops.csv") %>% 
  filter(workshop %in% workshops)
  
# Fix comma separator
results <- results %>% 
  mutate(findout_select.pre = str_replace_all(
  findout_select.pre, 
  "Twitter, Facebook, etc.", 
  "Twitter; Facebook; etc."))

pre_survey <- results %>%
  select(ends_with(".pre"))

post_survey <- results %>%
  select(ends_with(".post"))

shoreline <- read_csv("data/shoreline/2025-02-19-ucsb-intermediater-shoreline.csv") %>% 
  filter(`RSVP'ed`=='Yes')

n_pre <- sum(apply(post_survey, 1, function(row) all(is.na(row))))
n_post <- sum(apply(pre_survey, 1, function(row) all(is.na(row))))
n_total <- nrow(results)
n_both <- nrow(results) - n_pre - n_post

layout_columns(
  value_box(
    title = "RSVP'ed Yes - Shoreline", value = nrow(shoreline), ,
    theme = NULL, showcase = bs_icon("card-checklist"), showcase_layout = "left center",
    full_screen = FALSE, fill = TRUE, height = NULL
  ),
  value_box(
    title = "Total survey responses", value = n_total, ,
    theme = NULL, showcase = bs_icon("people-fill"), showcase_layout = "left center",
    full_screen = FALSE, fill = TRUE, height = NULL
  ),
  value_box(
    title = "Both pre- and post-", value = n_both, , theme = NULL,
    showcase = bs_icon("arrows-expand-vertical"), showcase_layout = "left center",
    full_screen = FALSE, fill = TRUE, height = NULL
  ),
  value_box(
    title = "Only pre-workshop", value = n_pre, ,
    theme = NULL, showcase = bs_icon("arrow-left-short"), showcase_layout = "left center",
    full_screen = FALSE, fill = TRUE, height = NULL
  ),
  value_box(
    title = "Only post-workshop", value = n_post, , theme = NULL,
    showcase = bs_icon("arrow-right-short"), showcase_layout = "left center",
    full_screen = FALSE, fill = TRUE, height = NULL
  )
)

RSVP'ed Yes - Shoreline

18

Total survey responses

12

Both pre- and post-

3

Only pre-workshop

7

Only post-workshop

2

Departments (Shoreline info)

Code
name_var <- shoreline %>% select(starts_with("Please")) %>% names()
depts_2 <- shoreline %>% rename(dept_select.pre = name_var) %>% 
  select(dept_select.pre) %>% 
  separate_rows(dept_select.pre, sep=",") %>%
  mutate(dept_select.pre = str_trim(dept_select.pre)) %>%
  count(dept_select.pre, name = "count") %>% 
  mutate(percent = (count / nrow(shoreline)) * 100,
         text = sprintf("%.0f (%.0f%%)", count, percent))

ggplot(depts_2, aes(y=reorder(dept_select.pre, count), x=count)) +
    geom_col() +
    geom_label(aes(label = text, hjust = -0.1),
               size = 3) +
    labs(x = "# respondents", y = element_blank()) +  
    theme_minimal() +
    theme(
      panel.grid.minor = element_blank(),
      panel.grid.major.y = element_blank()
      ) +
    expand_limits(x = c(0,max(depts_2$count)*1.1))

Current occupation / Career stage (Shoreline info)

Code
name_var <- shoreline %>% select(starts_with("What is")) %>% names()
ocup_2 <- shoreline %>% rename(occupation.pre = name_var) %>% 
  select(occupation.pre) %>% 
  separate_rows(occupation.pre, sep=",") %>%
  mutate(occupation.pre = str_trim(occupation.pre)) %>%
  count(occupation.pre, name = "count") %>% 
  mutate(percent = (count / nrow(shoreline)) * 100,
         text = sprintf("%.0f (%.0f%%)", count, percent))

ggplot(ocup_2, aes(y=reorder(occupation.pre, count), x=count)) +
    geom_col() +
    geom_label(aes(label = text, hjust = -0.1),
               size = 3) +
    labs(x = "# respondents", y = element_blank()) + 
    theme_minimal() +
    theme(
      panel.grid.minor = element_blank(),
      panel.grid.major.y = element_blank()
      ) +
    expand_limits(x = c(0,max(ocup_2$count)*1.2))

Motivation - Why are you participating in this workshop?

Code
motiv <- results %>% select(motivation_select.pre) %>% 
  separate_rows(motivation_select.pre, sep=",")  %>% 
  mutate(motivation_select.pre = str_trim(motivation_select.pre)) %>%
  count(motivation_select.pre, name = "count") %>% 
  drop_na() %>% 
  mutate(percent = (count / (n_total - n_post)) * 100,
         text = sprintf("%.0f (%.0f%%)", count, percent))

ggplot(motiv, aes(y=reorder(motivation_select.pre, count), x=count)) +
    geom_col() +
    geom_label(aes(label = text, hjust = -0.1),
               size = 3) +
    labs(x = "# respondents", y = element_blank()) + 
    theme_minimal() +
    theme(
      panel.grid.minor = element_blank(),
      panel.grid.major.y = element_blank()
      ) +
    expand_limits(x = c(0,max(motiv$count)*1.2))

How did you find out about this workshop?

Code
findw <- results %>% select(findout_select.pre) %>% 
  separate_rows(findout_select.pre, sep=",")  %>% 
  mutate(findout_select.pre = str_trim(findout_select.pre)) %>%
  count(findout_select.pre, name = "count") %>% 
  drop_na() %>% 
  mutate(percent = (count / (n_total - n_post)) * 100,
         text = sprintf("%.0f (%.0f%%)", count, percent))

ggplot(findw, aes(y=reorder(findout_select.pre, count), x=count)) +
    geom_col() +
    geom_label(aes(label = text, hjust = -0.1),
               size = 3) +
    labs(x = "# respondents", y = element_blank()) + 
    theme_minimal() +
    theme(
      panel.grid.minor = element_blank(),
      panel.grid.major.y = element_blank()
      ) +
    expand_limits(x = c(0,max(findw$count)*1.2))

What you most hope to learn?

Code
results %>% group_by(workshop) %>% 
  select(workshop, hopes.pre) %>% 
  drop_na()
workshop hopes.pre
2025-02-18-ucsb-intermediater I want to increase my comfort with R coding language and skills.
2025-02-18-ucsb-intermediater Further advance my comprehension of R and how to leverage it for Data Analysis as it applies to Project Managment and Data Wrangling.
2025-02-18-ucsb-intermediater Advance my R skills and feel more comfortable processing statistical analysis using R
2025-02-18-ucsb-intermediater I hope to become more familiar with manipulating raw data in R (such as pulling out certain columns of data, averaging raw values and plotting means with standard errors, etc) and using new libraries for simple statistical analysis (ANOVA, regressions)
2025-02-18-ucsb-intermediater becoming proficient at For Loops
2025-02-18-ucsb-intermediater I’d like to learn how to better store and access the various files that I am working with and creating, especially when I am learning how to write the code and my script files are often filled with my trials and errors. I want to gain confidence to delete the stuff that didn’t work as intended
2025-02-18-ucsb-intermediater skills in R that will help me get a new job
2025-02-18-ucsb-intermediater To gain confidence with writing for loops for diverse scenarios

Learning environment in the workshop

Code
orderedq <- c("Strongly Disagree", "Somewhat Disagree", "Neither Agree or Disagree","Somewhat Agree", "Strongly Agree")
addNA(orderedq)
Code
agree_questions <- results %>% 
  select(join_key, agree_apply.post,    agree_comfortable.post, agree_clearanswers.post,
         agree_instr_enthusiasm.post, agree_instr_interaction.post, agree_instr_knowledge.post
) %>% 
  filter(!if_all(-join_key, is.na))

n_agree_questions <- nrow(agree_questions)
  
agree_questions <- agree_questions %>%
  pivot_longer(cols = -join_key, names_to = "Question", values_to = "Response") %>% 
  mutate(Response = factor(Response, levels = orderedq),
         Question = recode(Question,
                     "agree_apply.post" = "Can immediatly apply 
 what they learned",
                     "agree_comfortable.post" = "Comfortable learning in 
 the workshop environment",
                     "agree_clearanswers.post" = "Got clear answers 
 from instructors",
                     "agree_instr_enthusiasm.post" = "Instructors were enthusiastic",
                     "agree_instr_interaction.post" = "Comfortable interacting 
 with instructors",
                     "agree_instr_knowledge.post" = "Instructors were knowledgeable 
 about the material"
      ))

summary_data <- agree_questions %>%
  count(Question, Response, name = "count") %>% 
  mutate(percent = (count / n_agree_questions) * 100,
         text = sprintf("%.0f (%.0f%%)", count, percent))

ggplot(summary_data, aes(x = Question, y = count, fill = Response)) +
  geom_col(position = "fill", color = "black", show.legend = TRUE) +
  scale_y_continuous(labels = scales::percent_format()) + 
  scale_fill_manual(values = c("Strongly Disagree" = "#d01c8b", 
                               "Somewhat Disagree" = "#f1b6da", 
                               "Neither Agree or Disagree" = "#f7f7f7", 
                               "Somewhat Agree" = "#b8e186", 
                               "Strongly Agree" = "#4dac26"), 
                    na.translate = TRUE, na.value = "#cccccc", 
                    breaks = orderedq, drop = FALSE) +
  geom_text(aes(label = text), size = 3,
             position = position_fill(vjust = 0.5)) +
  labs(y = "# respondents (Percentage)", x = element_blank(), fill = "Responses",
       subtitle = paste0("Number of responses: ", n_agree_questions)) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        plot.subtitle = element_text(hjust = 0.5, size = 12))

How an instructor or helper affected your learning experience

Code
results %>% 
  group_by(workshop) %>% 
  select(workshop, instructor_example.post) %>%
  drop_na()
workshop instructor_example.post
2025-02-18-ucsb-intermediater The instructors did a good job of slowly going through the code and providing a few tips that novices can use.
2025-02-18-ucsb-intermediater The instructors were so familiar with the material that it was hard for them to step outside the mindset of a programmer and see how someone without full training in coding might need additional steps
2025-02-18-ucsb-intermediater I gained more familiarity with the structure of for loops and the instances when a function may be better than a for loop and when using functions in dplyr may actually achieve coding goals quicker than a for loop.
2025-02-18-ucsb-intermediater one on one time and super friendly
2025-02-18-ucsb-intermediater They had clear and concise lessons and had an effective system for ensuring everyone was keeping up with the material.

Skills and perception comparison

Code
# Calculate mean scores and make graph for all respondents (only_matched=FALSE)
tryCatch(
  {
mean_nresp <- get_mean_scores_nresp(results, only_matched=FALSE)
graph_pre_post(mean_nresp$mean_scores, mean_nresp$n_resp_pre, mean_nresp$n_resp_post, mean_nresp$n_resp_pre_post, only_matched=FALSE)
},
error = function(cond) {
message("Could not do the plots as there are no pre or post results to show")
}
)

Code
# Calculate mean scores and make graph for only matched respondents in pre and post (only_matched=TRUE)
tryCatch(
  {
mean_nresp <- get_mean_scores_nresp(results, only_matched=TRUE)
graph_pre_post(mean_nresp$mean_scores, mean_nresp$n_resp_pre, mean_nresp$n_resp_post, mean_nresp$n_resp_pre_post, only_matched=TRUE)
},
error = function(cond) {
message("Could not do the plots as there are no pre or post results to show")
}
)

Workshop Strengths

Code
results %>% 
  group_by(workshop) %>% 
  select(workshop, workshop_strengths.post) %>% 
  drop_na()
workshop workshop_strengths.post
2025-02-18-ucsb-intermediater The opportunity to see R in action and think through how to solve problems. There was help when you needed it.
2025-02-18-ucsb-intermediater friendly, responsive to questions
2025-02-18-ucsb-intermediater I liked that the workshop alternated instructors to provide variety in the way information was shared and taught. I appreciated that there were challenges and also a short break during the workshop.
2025-02-18-ucsb-intermediater just glad you have them. keep em coming
2025-02-18-ucsb-intermediater Simple yet effective lessons, used real world data with practical applications as a basis for example.

Ways to improve the workshop

Code
results %>% 
  group_by(workshop) %>% 
  select(workshop, workshop_improved.post) %>% 
  drop_na()
workshop workshop_improved.post
2025-02-18-ucsb-intermediater I have a lot of experience with data analysis (in another coding language), so I was able to follow pretty closely what was going on. I felt like others might not have had as much experience, so they were lost as to what the goal of some of the commands were. It might be good to think carefully about where some people might not know what the goal of a command is. Perhaps you expect people to come in with that knowledge, which is fine, but it was the sense I got from some of the questions that were asked.
2025-02-18-ucsb-intermediater if an instructor was coming from a non-coding background they might be able to present the material in a different way. Also it was hard for me to think about immediate applications for my data project. I would like to come prepared with my own data and write code that is pertinent, as i had a hard time making the leap of how I would apply it easily
2025-02-18-ucsb-intermediater I think something that could be useful for folks to walk away with are more examples utilizing for loops, functions and if and else statements. So maybe, creating like a part 2 for the workshop to get into more details and examples.
2025-02-18-ucsb-intermediater more of them, evenings might also be good
2025-02-18-ucsb-intermediater I understand the focus was on developing coding skills, but I hope in future lessons we’re able to follow through on the example to see the end result of the practical application for the skills we’ve learned.

How likely are you to recommend this workshop? Scale 0 - 10

Code
orderedq <- c("Detractor", "Passive", "Promoter")

nps <- results %>% 
  count(recommend_group.post, recommende_score.post, name = "count") %>% 
  drop_na() %>% 
  mutate(recommend_group.post = factor(recommend_group.post, levels = orderedq),
         percent = (count/sum(count)) * 100,
         text = sprintf("%.0f (%.0f%%)", count, percent))

nps %>% 
ggplot(aes(x=recommende_score.post, y=count, fill=recommend_group.post)) +
  geom_col(color="black", show.legend = TRUE) +
  scale_fill_manual(values = c("Detractor" = "#af8dc3", "Passive" = "#f7f7f7", "Promoter" = "#7fbf7b"), breaks = c("Detractor", "Passive", "Promoter"), drop = FALSE) +
  geom_label(aes(label = text, vjust = -0.5), fill = "white", size= 3) +
  scale_x_continuous(breaks = 1:10) +
  labs(x = "NPS Score", y = "# respondents", subtitle = paste0("Number of responses: ", sum(nps$count), "
 Mean score: ", format(weighted.mean(nps$recommende_score.post, nps$count), digits = 3))) +
  theme_minimal() +
  theme(
    panel.grid.minor = element_blank(),
    panel.grid.major.x = element_blank(),
    plot.subtitle = element_text(hjust = 0.5, size = 12)
  ) +
  expand_limits(x = c(1,10),
                y = c(0, max(nps$count)*1.1))

Topic Suggestions

Code
results %>% 
  group_by(workshop) %>% 
  select(workshop, suggest_topics.post) %>% 
  drop_na()
workshop suggest_topics.post
2025-02-18-ucsb-intermediater Any useful and potentially complex commands could be good to focus on. I thought that this was well-paced and didn’t try to do too much. I found it helpful.
2025-02-18-ucsb-intermediater programming for non-programmers? :)
2025-02-18-ucsb-intermediater none at this time, thank you
2025-02-18-ucsb-intermediater Intermediate / advanced topics pertaining to geospatial and environmental data analysis. Combining R with geospatial softeare like ArcGIS and QGIS. Rendering models and point clouds from photogrammetric / LiDAR survey. Data collection and preparation of raw sensor data.