I came across this paper which is a detailed study of hiring networks and discrimination practices in hiring of faculty among a large number of universities in the US. They also provided the data for other researchers to download and play.
What I did was to graph all hiring data as a weighted directed graph. If university \(y\) hired someone from university \(x\), the weight of the directed edge \(x\to y\) is increased by 1. The final graphs are huge. So, I only pictured those edges whose weight are above certain value and removed “All others” (which I am guessing, indicates Universities not from Northern American continent).
The graph is very much like a tree. Almost a pyramid, one can say. You should probably play with several threshold values to see what Iam about to observe:
The network is a lot more connected and complicated than the network for computer science, but the pyramid-like structure is still present.
The network is as not as connected compared to history or computer science, but the pyramid-like structure is again present.
Here is the code. If you are going to run the code, here are the instructions:
;; from the plain data files creates an assoc list to be fed into
;; `dot-write`
(defun weighted-edges (edges vertices attribute)
(let (res y)
(dolist (x edges res)
(setf y (mapcar (lambda (i) (elt (assoc i vertices) attribute)) x))
(if (assoc y res :test #'equal)
(incf (cdr (assoc y res :test #'equal)))
(push (cons y 1) res)))))
;; process the vertices file
(defun process-vertices (filename)
(mapcar
(lambda (x) (mapcar (lambda (i j) (funcall j i))
x
(list
#'read-from-string
#'read-from-string
(lambda (i) (if (string= i ".") 0 (read-from-string i)))
(lambda (i) (if (string= i ".") 0 (read-from-string i)))
(lambda (i) i)
(lambda (i) i))))
(read-file filename)))
;; process the edge file
(defun process-edges (filename)
(mapcar
(lambda (x) (mapcar (lambda (i j) (funcall j i))
(list (car x) (cadr x))
(list #'read-from-string #'read-from-string)))
(read-file filename)))
;; reads data file into an assoc list
(defun read-file (name)
(let (res)
(with-open-file (in name :direction :input)
(read-line in)
(do ((line (read-line in nil) (read-line in nil)))
((null line) res)
(push (cl-ppcre:split #\Tab line) res)))))
;; The graph is weighted and represented as a assoc list where items
;; are of the form '((a b) . n)' where a is the source b is the target
;; and n is the count. I also pass a threshold value. If the weight is
;; below a certain value, it will not show up in the graph as the
;; graph is very large.
(defun dot-write (graph threshold)
(let* ((num (mapcar #'cdr graph))
(a (reduce #'min num))
(b (reduce #'max num)))
(format t "digraph transition {~% node[shape=\"rectangle\"];~%")
(dolist (edge graph)
(let ((weight (* 10 (/ (+ (cdr edge) (- a)) (- b a)))))
(if (> weight threshold)
(format t
" \"~a\" -> \"~a\" [penwidth = ~2,1f];~%"
(string-trim '(#\Space) (caar edge))
(string-trim '(#\Space) (cadar edge))
weight))))
(format t "}~%")))
;; the main part of the code
(let* ((base (concatenate
'string
"data/faculty-inequality-"
(elt *posix-argv* 1)))
(vertices (process-vertices (concatenate 'string base "-vertices.csv")))
(edges (process-edges (concatenate 'string base "-edges.csv"))))
(dot-write (weighted-edges edges vertices (read-from-string (elt *posix-argv* 2)))
(read-from-string (elt *posix-argv* 3))))
AMS has the necessary data but doesn’t disclose it for public use. I would very much like to see the network.
If you are about to go into PhD, screw the US News Rankings. Get the
hiring network to determine your chances of being hired, and if there is
any, by whom.