Skip to content

Instantly share code, notes, and snippets.

@alyssafrazee
Last active December 26, 2015 04:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save alyssafrazee/7094055 to your computer and use it in GitHub Desktop.
Save alyssafrazee/7094055 to your computer and use it in GitHub Desktop.
These are R functions written to check whether your proposed committee (either preliminary oral exam committee or committee of thesis readers) meets the official school guidelines on committee composition. You create "faculty" objects, which have some attributes like their primary departments and ranks (assistant/associate/full professor), and t…
faculty = function(name, dept, rank = c("assistant","associate","full","scientist"), sph = TRUE, advisor = FALSE, mydept = TRUE, alt = FALSE, joint = "none"){
# tell me about your faculty members (make a "faculty" object for each one)
if(advisor & alt){
stop("Your advisor cannot be an alternate - he/she must be on the main committee.")
}
rank = match.arg(rank)
return(list(name=name, dept=dept, rank=rank, sph=sph, advisor=advisor, mydept=mydept, alt=alt, joint=joint))
}
# helper function:
checkMain = function(mainframe, mydept, type=c("prelim", "finaldefense")){
type = match.arg(type)
if(type=="prelim"){
if(nrow(mainframe)!=5) stop("you need 5 main committee members.")
if(length(unique(mainframe$dept)) < 3) stop("at least 3 departments of the university must be represented.")
if(length(unique(mainframe$dept[mainframe$sph==TRUE])) < 2) stop("at least 2 departments from SPH must be represented.")
if(sum(unlist(mainframe$mydept))>3)
stop("no more than 3 members of your own department can serve. note: your advisor is considered
an inside examiner, even if he/she is not in your department")
}
if(sum(unlist(mainframe$advisor)) < 1) stop("your advisor must be on your committee.")
chair = mainframe[which(mainframe$mydept==FALSE & mainframe$rank=="full"),]
if(dim(chair)[1]==0) chair = mainframe[which(mainframe$mydept==FALSE & mainframe$rank=="associate"),]
if(dim(chair)[1]==0){
stop("your committee is missing a chair. the chair must be from outside your department and
must hold the rank of full or associate professor.")
}
if(sum(unlist(mainframe$rank) == "scientist" | unlist(mainframe$rank == "adjunct")) > 1){
stop("only one scientist/adjunct faculty may serve on the committee.")
}
if(type=="finaldefense"){
if(length(unique(mainframe$dept)) < 3) stop("at least 3 departments of the university must be represented.")
if(length(unique(mainframe$dept[mainframe$sph==TRUE])) < 2) stop("at least 2 departments from SPH must be represented.")
if(sum(unlist(mainframe$mydept)) == 1){
warning("you need approval of the Committee on Academic Standards in order to have just one departmental thesis reader.")
}else{
if(sum(unlist(mainframe$mydept)) < 2) stop("you must have 2 readers from your department.")
}
if(sum(unlist(mainframe$advisor)) < 1) stop("your advisor must be on your committee.")
if(sum(unlist(mainframe$dept)!=mydept & unlist(mainframe$joint)!=mydept)<1) stop("at least one thesis reader must have neither a primary nor joint appointment in your department.")
chair = mainframe[which(mainframe$mydept==FALSE & mainframe$rank=="full"),]
if(dim(chair)[1]==0) chair = mainframe[which(mainframe$mydept==FALSE & mainframe$rank=="associate"),]
if(dim(chair)[1]==0){
stop("your committee is missing a chair. the chair must be from outside your department and
must hold the rank of full or associate professor.")
}
if(sum(unlist(mainframe$rank) == "scientist" | unlist(mainframe$rank == "adjunct")) > 1){
stop("only one scientist/adjunct faculty may serve on the committee.")
}
}
return(list(mainframe=mainframe, chair=chair))
}
checkCommittee = function(..., mydept, type=c("prelim", "finaldefense")){
# check committees of different faculty combos
cdframe = as.data.frame(rbind(...), row.names=FALSE)
cdframe$mydept[which(cdframe$advisor==TRUE)] = TRUE
mainframe = subset(cdframe, cdframe$alt==FALSE)
altframe = subset(cdframe, cdframe$alt==TRUE)
### preliminary orals checker:
if(type=="prelim"){
if(nrow(cdframe)!=7){
stop("preliminary oral exam committees need 7 members: 5 main, 2 alternate")
}
mainobj = checkMain(mainframe, mydept, type="prelim")
mainframe = mainobj$mainframe
chair = mainobj$chair
if(dim(altframe)[1] != 2) stop("you need 2 alternates.")
if(sum(unlist(altframe$mydept)) != 1){
stop("you must have one inside alternate and one outside alternate.")
}
if(sum(unlist(altframe$rank) != "assistant" &
unlist(altframe$rank) != "associate" & unlist(altframe$rank) != "full") > 0){
stop("alternates must hold the rank of assistant professor or higher.")
}
message("main committee ok! checking committee if one alternate is needed...")
possiblesickies = which(unlist(mainframe$advisor) == FALSE)
# remove one committee member at a time and test their respective alternates:
for(sickie in possiblesickies){
mf.new = mainframe[-sickie,]
thealt = ifelse(mainframe$mydept[sickie]==TRUE, which(altframe$mydept==TRUE), which(altframe$mydept==FALSE))
mf.new = rbind(mf.new, altframe[thealt,])
mf.new = try(checkMain(mf.new, mydept, type="prelim"), silent=TRUE)
if(class(mf.new)=="try-error"){
sname = as.character(mainframe$name[sickie])
stop(paste(sname,"cannot be replaced by an alternate with the current setup. Try again!"), call. = FALSE)
}
}
message("committee ok if one alternate needed! checking committee if two alternates are needed...")
# remove two committee members at a time and test their alternates:
sick.combos = combn(possiblesickies, 2)
for(k in 1:dim(sick.combos)[2]){
mf.new = mainframe[-sick.combos[,k],]
mf.new = rbind(mf.new, altframe)
mf.new = checkMain(mf.new, mydept, type="prelim")
}
}
if(type=="finaldefense"){
if(nrow(mainframe)!=4 & nrow(mainframe)!=5){
stop("thesis committees need 4 or 5 members (usually 4).")
}
mainobj = checkMain(mainframe, mydept, type="finaldefense")
chair = mainobj$chair
}
message("Congratulations! Valid Committee.")
print(cdframe)
message("Anticipated chair(s):")
print(chair)
#return(list(members=cdframe, type=type)
}
#### DOCUMENTATION ####
# users should be (a) creating faculty objects and (b) running checkCommittee.
# the other functions here are internal.
### the faculty function
# arguments:
# name: string, faculty name (only used in printing, so can be however you identify this faculty member)
# dept: string, name of department where faculty has his/her primary appointment
# rank: string, faculty rank. should be "assistant","associate","full", or "scientist"
# sph: boolean, whether or not faculty's primary appointment is in the School of Public Health. Default TRUE.
# advisor: boolean, whether or not this faculty is your primary advisor. Default FALSE.
# mydept: boolean, whether this faculty is primarily appointed in your department. Default TRUE,
# alt: boolean, whether you're considering this faculty member as an alternate. Currently only used in preliminary exam mode. Default FALSE.
# joint: string, name of department where faculty has his/her joint appointment. Only used in thesis committee mode. Currently only supports one joint appointment, but is only important if the joint appointment is in the student's primary department.
# return:
# a list with elements named the same as the arguments.
### the checkCommittee function
# arguments:
# ...: several faculty objects created with the faculty function.
# mydept: string, name of student's primary department
# type: string, which type of committee is being formed ("prelim" or "finaldefense")
# return:
# none, but either exits with error if committee is not valid, or prints the valid committee.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment