In January 2021, the Equality, Diversity, and Inclusion (EDI) team committee designed and administered a survey to obtain feedback on the efficacy of the EDI team and EDI initiatives more generally.
This notebook analyzes the results. If you would like to perform your own analysis, please email Michael Petersen (michael.petersen@roe.ac.uk) for assistance.
We have omitted the demographic responses. We are confident that the reponses constitute a representative sample of IfA members. Additionally, no cross-tabs are reported in this analysis (i.e. no separation along demographic lines). An internal analysis did not indicate any significant results as a function of different demographic elements.
from IPython.display import HTML
HTML('''<script>
code_show=true;
function code_toggle() {
if (code_show){
$('div.input').hide();
} else {
$('div.input').show();
}
code_show = !code_show
}
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Click here to toggle on/off the raw code."></form>''')
# standard python modules
import numpy as np
# enable markdown printing
from IPython.display import Markdown, display
def printmd(string):
"""wrap markdown printing"""
display(Markdown(string))
# how-to
#printmd('**bold**')
#printmd('_italics_')
# plotting utilities
import matplotlib.pyplot as plt
import matplotlib as mpl
%matplotlib inline
# adjust rcparams to MSP style
mpl.rcParams['xtick.labelsize'] = 10
mpl.rcParams['ytick.labelsize'] = 10
mpl.rcParams['font.weight'] = 'medium'
mpl.rcParams['axes.linewidth'] = 1.5
mpl.rcParams['xtick.major.width'] = 1.5
mpl.rcParams['xtick.minor.width'] = 0.75
mpl.rcParams['xtick.minor.visible'] = True
mpl.rcParams['ytick.major.width'] = 1.5
mpl.rcParams['ytick.minor.width'] = 0.75
mpl.rcParams['ytick.minor.visible'] = True
# definition to read questions from the google forms format
def summarize_answer(question,\
multiple=True,\
delimiter=b'., ',\
criteria=0,\
significance=5):
"""summarize an answer to a question
inputs
----------
question : (list) Responses to a question in list format.
multiple : (boolean) True if the question allowed multiple responses
delimiter : (string) Safeguard to delimit the google forms format
criteria : (boolean evaluation) Allow for cross-tab analysis
significance : (integer) How many responses must be recorded for reporting
returns
----------
none -- printed results only.
"""
if criteria!=0:
question = question[criteria]
if multiple:
#answerlist = np.array([np.array(q.split(b',')) for q in question)
flatanswers = np.array([])
for x in np.array([np.array(q.split(delimiter)) for q in question]):
flatanswers = np.concatenate([flatanswers,x])
else:
flatanswers = question
flatanswers = np.array([q.strip(b'.').strip(b'') for q in flatanswers])
answers = np.unique(flatanswers[flatanswers!=b''])
nanswers = np.zeros(answers.size)
for ans in flatanswers:
nanswers[ans==answers] += 1
for ans in (-1.*nanswers).argsort():
if nanswers[ans] < significance:
printmd('******* - {0}'.format(\
answers[ans].decode().lstrip()\
))
continue
try:
printmd('**'+str(int(nanswers[ans]))+'** - {0}'.format(\
answers[ans].decode().lstrip()\
))
except:
printmd('**'+str(int(nanswers[ans]))+'** - {0}'.format(\
answers[ans]\
))
Read the file format from Google Forms, and organize into a keyed dictionary.
keys = ["timestamp",\
"ifa",\
"history",\
"position",\
"gender",\
"inclusivity",\
"importance",\
"opinion",\
"non_attendence",\
"old_initiatives",\
"new_initiatives",\
"changes",\
"comments",\
"emails"]
fmts = ['S200','S200','S200','S200','S200',\
'i4','i4','i4',\
'S500','S500','S500','S5000','S5000','S500']
# read in the survey responses
Stats = np.genfromtxt('ROE_EDI_Responses',\
dtype={'names': list(keys),\
'formats': fmts},
delimiter='\t',skip_header=1)
# Read in the question prompts specifically
f= open('ROE_EDI_Responses'); a = f.readline()
# reorganize into a dictionary
QDict = {}
for ikey,key in enumerate(keys):
QDict[key] = a.split('\t')[ikey]
def make_numerical_figure(key):
fig = plt.figure(figsize=(6,4))
ax1 = fig.add_axes([0.15,0.45,0.8,0.48])
temprange = np.arange(1,7,1)
tempval = np.zeros(temprange.size)
for x in Stats[key]:
if x > 0:
tempval[x-1] += 1
ax1.plot(temprange,tempval,color='black',drawstyle='steps-mid')
ax1.set_ylabel('# of responses',size=12)
ax1.set_xlabel('score',size=12)
ax1.set_title(QDict[key],size=12)
ax1.tick_params(axis="y",which='both',direction="in"); ax1.tick_params(axis="x",which='both',direction="in",pad=5); ax1.yaxis.set_ticks_position('both'); ax1.xaxis.set_ticks_position('both')
_ = ax1.set_xticks(temprange[0:-1])
make_numerical_figure('inclusivity')
make_numerical_figure('importance')
make_numerical_figure('opinion')
Responses to questions regarding ongoing initiatives.
# which questions?
initiatives = ["non_attendence","old_initiatives","new_initiatives"]
for qq in initiatives:
printmd('_'+QDict[qq]+'_')
summarize_answer(Stats[qq],delimiter=b', ',significance=1)
print('')
# open response questions
# which questions?
programkeys = ["changes","comments"]
for qq in programkeys:
printmd('_'+QDict[qq]+'_')
summarize_answer(Stats[qq],significance=1)
print('')
Demographic answers have been omitted. Please contact the organisers if you have any specific questions.
# which questions?
#demographics = ["ifa","history","position","gender"]
#for qq in demographics:
# printmd('_'+QDict[qq]+'_')
# summarize_answer(Stats[qq],delimiter=b', ',significance=5)
# print('')