Find the present document at the following link:
Qualtrics will be used for survey design and collection.
GitHub will be used for storing data and analyses.
R will be used for data analysis and visualization.
R is a free, open-source programming language used for statistical computing and data visualization.
This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents. R Markdown also helps keeps data analyses reproducible.
The present document will present example plots and the R code I used to generate them. We would receive this data output from the surveys we give bargaining units, and we can analyze this data to generate easy-to-understand data visualizations.
Below, on the right-hand side of each plot, click “Show” to view the code I used to generate them.
“A data analysis is reproducible if all the information (data, files, etc.) required is available for someone else to re-do your entire analysis. This includes:
From: R Programming for Research - Brooke Anderson, Rachel Severson, and Nicholas Good; Colorado State University
Link here: https://geanders.github.io/RProgrammingForResearch/reproducible-research-1.html
These projects, and others like them, can be replicated nationwide.
The following are examples of visualizations we can get from each project (using fake data).
We can customize these data visualizations, track changes over time, combine to visualize associations, etc.
The following questions are example questions; we can further develop the questions based on focus groups, staff feedback, etc.
The survey can also be used as an organizing tool to:
The next few examples will use items from the survey we just viewed.
The following plot represents how the sample responded regarding changing their teaching due to recent legislation.
library(tidyverse)
climate1 <- read.csv("~/GGPLOT/climate1.csv")
View(climate1)
my_ggp <- climate1%>%
ggplot(aes(x = answer, y = count))+
geom_col(aes(fill = answer))+
scale_fill_gradient2(low = "white",
high = "purple") +
xlab("Responses")+
ylab("Count")+
labs(title="'I have felt compelled to change the way I teach",
subtitle = " due to recent higher education legislation.'")+
coord_flip()+
theme_set(theme_minimal())+
theme_dark(base_size = 14)+
theme(
plot.title = element_text(size = 16.5),
plot.subtitle = element_text(size = 15),
axis.title.x = element_text(size = 15),
axis.title.y = element_text(size = 15),
axis.text=element_text(size=10)
)+
scale_x_discrete(limits = c("1", "2", "3",
"4", "5", "6",
"7"),
labels = c("Strongly disagree",
"Disagree",
"Slightly disagree", "Neither agree nor disagree", "Slightly Agree",
"Agree", "Strongly Agree"))
my_ggp
Out of 1,140 respondents:
We can look at how the sample responded regarding considering moving out of state due to recent legislation.
climate3 <- read.csv("~/GGPLOT/climate3.csv")
View(climate3)
my_ggp <- climate3%>%
ggplot(aes(x = answer, y = count))+
geom_col(aes(fill = answer))+
scale_fill_gradient2(low = "white",
high = "purple") +
xlab("Responses")+
ylab("Count")+
labs(title="'I am considering moving out of state",
subtitle = "due to recent higher education legislation.'")+
coord_flip()+
theme_set(theme_minimal())+
theme_dark(base_size = 14)+
theme(
plot.title = element_text(size = 18),
plot.subtitle = element_text(size = 15),
axis.title.x = element_text(size = 15),
axis.title.y = element_text(size = 15),
axis.text=element_text(size=12)
)+
scale_x_discrete(limits = c("1", "2", "3",
"4", "5", "6",
"7"),
labels = c("Strongly disagree",
"Disagree",
"Slightly disagree", "Neither agree nor disagree", "Slightly Agree",
"Agree", "Strongly Agree"))
my_ggp
Out of 1,140 respondents:
We can also analyze the relationship between 2 variables of the survey - for example, the 2 previous items that we just plotted.
library(smplot2)
library(tidyverse)
climate2 <- read.csv("~/GGPLOT/climate2.csv")
my_ggp <- climate2%>%
ggplot(aes(x=changeT, y=moveF)) +
geom_point(size=3)+
geom_smooth(method=lm, linetype="dashed",
color="black", fill="purple")+
xlab("'Compelled to change Teaching' agreement")+
ylab("'Considering Moving States' agreement")+
labs(title = "Association between 'change teaching' & 'considering moving out of state'",
subtitle = "(Correlation between the previous 2 survey items)")+
theme(plot.title = element_text(size = 30),
plot.subtitle = element_text(size = 20)
)+
scale_x_discrete(limits = c("1", "2", "3",
"4", "5", "6",
"7"),
labels = c("1",
"2",
"3", "4", "5",
"6", "7"))+
scale_y_discrete(limits = c("1", "2", "3",
"4", "5", "6",
"7"),
labels = c("1",
"2",
"3", "4", "5",
"6", "7"))+
sm_statCorr(corr_method = "spearman",
linetype = "dashed"
)
my_ggp
We can also learn a lot just from existing data, like membership data (i.e., this project does not consist of survey design or data collection). We can look at both chapter densities and membership recruitment statistics.
We can look at membership densities and compare side-by-side with each chapter.
chpdensity.uni <- read.csv("~/GGPLOT/chpdensity.uni.csv")
View(chpdensity.uni)
my_ggp <- chpdensity.uni%>%
ggplot(aes(x = density, y = chapter))+
geom_col(fill = "lightblue")+
theme_dark(base_size = 14)+
geom_text(aes(label = density), vjust = 0.6, color = "white", size = 4.5,
fontface = "bold")+
scale_x_continuous(limits = c(0,100))+
xlab("% Density")+
ylab("Chapter")+
labs(title="March 2025 Chapter Densities: Universities",
subtitle = "Fake Data Example")+
geom_vline(xintercept = 60, color = "red", linewidth = 1)+
theme(
plot.title = element_text(size = 20),
plot.subtitle = element_text(size = 15),
axis.title.x = element_text(size = 15),
axis.title.y = element_text(size = 15),
axis.text=element_text(size=12)
)
my_ggp
To probe further, we could also look at new member recruitment statistics for the past 5 years; for example – within the (hypothetical) chapters that did not reach 60% density.
chptime <- read.csv("~/GGPLOT/chptime.csv")
View(chptime)
ggplot()+
geom_line(chptime, mapping = aes(x=year,y=newmembers, color = chapter), linewidth = 2)+
geom_point(chptime, mapping = aes(x=year,y=newmembers,colors = chapter), size = 4)+
labs(x="Year",y="New UFF Members")+
labs(title="New Member Recruitment",
subtitle = "2019-2024; UFF chapters below 60% density")+
theme_dark(base_size = 14)+
theme(
plot.title = element_text(size = 25),
plot.subtitle = element_text(size = 15),
axis.title.x = element_text(size = 15),
axis.title.y = element_text(size = 15),
axis.text=element_text(size=14)
)+
scale_color_discrete()+
scale_y_continuous(limits=c(0,250))
Like the Climate Survey (Project #1), a Bargaining Survey can also be used as an organizing tool to: | | • sign up non-members | | • increase involvement among existing members | | • initiate follow-up contact | | • inform bargaining unit of importance of keeping their union
In a bargaining survey, we can present to respondents a list of commonly-reported bargaining issues, and have them rate the importance of each issue.
We can also include a write-in option for issues they believe should be prioritized, that are not already on the list we provide them.
library(usmapdata)
library(maps)
library(dplyr)
set.seed(2522)
grouped_data <- us_map() |>
mutate(
group = sample(
c('income increases', 'paid parental leave', 'tenure protections', 'academic freedom'),
size = 51,
replace = TRUE
)
)
grouped_data |>
ggplot() +
geom_sf(aes(fill = group)) +
theme_minimal(base_size = 18)+
labs(title="Bargaining Priorities",
subtitle = "Faculty unions' top votes, by state")
We could also survey bargaining teams regarding recent issues they face during bargaining.
bargaining <- read.csv("~/GGPLOT/bargaining.csv")
View(bargaining)
my_ggp <- bargaining%>%
ggplot(aes(x = issue, y = count))+
geom_col(aes(fill = issue))+
scale_fill_gradient2(low = "white",
high = "purple") +
xlab("Responses")+
ylab("Count")+
labs(title="Top-rated issues during bargaining",
subtitle = "UFF faculty bargaining teams")+
theme_set(theme_minimal())+
theme_dark(base_size = 14)+
theme(
plot.title = element_text(size = 18),
plot.subtitle = element_text(size = 15),
axis.title.x = element_text(size = 15),
axis.title.y = element_text(size = 15),
axis.text=element_text(size=12)
)+
scale_x_discrete(limits = c("1", "2", "3",
"4", "5"),
labels = c("Issue 1",
"Issue 2",
"Issue 3", "Issue 4", "Issue 5"))
my_ggp