Archive for January, 2011

Plan B

| Gabriel |

Over at OrgTheory, Brayden discusses the lack of a meaningful “plan B” for people whose academic career doesn’t pan out. I’m convinced that one very concrete way you see the repercussions of the lack of a plan B is that so many people are willing to work as lecturers for very little money and under unpleasant conditions (no job security, half your time on the freeway, very heavy teaching loads, little prestige, etc). These are talented people, they are after all PhDs, and it seems like they could have more stable and remunerative lives outside of academia. The fact that they don’t exercise this option reflects either a strong nonpecuniary attachment to academia or a more objective lack of salvage value to the highly asset specific human and social capital they developed in graduate school. That is, staying in academia under bad conditions reflects either emotional or practical barriers to a “plan B.”

The AAUP likes to think that we can solve this by organizing lecturers and demanding better contracts for them and/or a greater ratio of ladder:contingent faculty. This may be true on the margin, but the big picture is that academic labor has a right-shifted supply curve and this drives down the market clearing price. Politics and institutions can only take you so far away from the economic fundamentals, especially in a sector whose primary stakeholders (i.e., ladder faculty) would resist redistribution of compensation and privilege and whose other major stakeholders (i.e., state governments and tuition-paying students) are already straining under Baumol’s disease and wouldn’t welcome a further rise in total payroll implied by an adjunct labor contract. You see a similar set of dynamics with artists (also chapter 4 of Creative Industries).

The dirty secret of academia is that we elite research faculty get to have large graduate programs, low teaching loads, and cheap course-buyouts because there is a large pool of people who are so attached to academia that rather than pursue “plan B” they willingly form a spot market for teaching at about $7000 total compensation per class (or less than half the cost of having a ladder assistant professor teach the class). Giving our graduate students the emotional and practical resources to take plan B seriously would undermine our power as people who depend on a flexible labor force and our self-esteem as people whose self-image is based on training a new generation of scholars, but would be an act of humanity to the people who spend five to ten years being trained by us but nonetheless find it doesn’t work out as planned.

January 27, 2011 at 3:20 pm 11 comments

Shufflevar update

| Gabriel |

Thanks to Elizabeth Blankenspoor (Michigan) I corrected a bug with the “cluster” option in shufflevar. I’ve submitted the update to SSC but it’s also here:

*1.1 GHR January 24, 2011

*changelog
*1.1 -- fixed bug that let one case per "cluster" be misallocated (thanks to Elizabeth Blankenspoor)

capture program drop shufflevar
program define shufflevar
	version 10
	syntax varlist(min=1) [ , Joint DROPold cluster(varname)]
	tempvar oldsortorder
	gen `oldsortorder'=[_n]
	if "`cluster'"!="" {
		local bystatement "by `cluster': "
	}
	else {
		local bystatement ""
	}
	if "`joint'"=="joint" {
		tempvar newsortorder
		gen `newsortorder'=uniform()
		sort `cluster' `newsortorder'
		foreach var in `varlist' {
			capture drop `var'_shuffled
			quietly {
				`bystatement' gen `var'_shuffled=`var'[_n-1]
				`bystatement' replace `var'_shuffled=`var'[_N] if _n==1
			}
			if "`dropold'"=="dropold" {
				drop `var'
			}
		}
		sort `oldsortorder'
		drop `newsortorder' `oldsortorder'
	}
	else {
		foreach var in `varlist' {
			tempvar newsortorder
			gen `newsortorder'=uniform()
			sort `cluster' `newsortorder'
			capture drop `var'_shuffled
			quietly {
				`bystatement' gen `var'_shuffled=`var'[_n-1]
				`bystatement' replace `var'_shuffled=`var'[_N] if _n==1
			}
			drop `newsortorder'
			if "`dropold'"=="dropold" {
				drop `var'
			}
		}
		sort `oldsortorder'
		drop `oldsortorder'
	}
end

January 24, 2011 at 7:30 pm 6 comments

Growl in R and Stata

| Gabriel |

Growl is a system notification tool for Mac that lets applications, the system itself, or hardware display brief notification, usually in the top-right corner. The translucent floating look reminds me of the more recent versions of KDE.

Anyway, one of the things it’s good for is letting programs run in the background and let you know when something noteworthy has happened. Of course, a large statistics batch would qualify. I was running a 10 minute job in the R package igraph and got tired of checking to see when it was done so I found this tip. In a nutshell, it says to download Growl, including the command-line tool GrowlNotify from the “Extras” folder, then create this R function.

growl <- function(m = 'Hello world')
system(paste('growlnotify -a R -m \'',m,'\' -t \'R is calling\'; echo \'\a\' ', sep=''))

Since the R function “system()” is equivalent to the Stata command “shell,” I realized this would work in Stata as well and so I wrote this ado file.* You call it just by typing “growl”. It takes as an (optional) argument whatever you’d like to see displayed in Growl, such as “Done with first analysis” or “All finished” but by default displays “Stata needs attention.” Note that while Stata already bounces in the dock when it completes a script or hits an error, you can also have Growl appear at various points during the run of a script.

I’ve only tested it with StataMP, but I’d appreciate it if people who use Growl and other versions of Stata would post their results in the comments. If it proves robust I’ll submit it to SSC.

Here’s the Stata code. The most important line is #32 and if you were doing it by hand you’d do it as a one-liner but the rest of this stuff allows argument passing and compatibility with the different versions (small, IC, SE, MP) of Stata:

*1.0 GHR Jan 19, 2011
capture program drop growl
program define growl
	version 10
	set more off
	syntax [anything]

	if "`anything'"=="" {
		local message "Stata needs attention"		
	}
	else {
		local message "`anything'"
	}
	
	local appversion "Stata"
	if "`c(flavor)'"=="Small" {
		local appversion "smStata"
	}
	else {
		if `c(SE)'==1 {
			if `c(MP)'==1 {
				local appversion "StataMP"
			}
			else {
				local appversion "StataSE"
			}
		}
		else {
			local appversion "Stata"
		}
	}
	shell growlnotify -a `appversion' -m \ "`message'" \ `appversion' \
end

*Most programming/scripting languages and a few GUI applications have a similar system call and you can likewise get Growl to work with them. For instance, Perl also has a function called system(). In shell scripting of course you can just use the “growlnotify” command directly.

January 20, 2011 at 5:10 am 10 comments

Diacriticals in Zotero and Bibtex

| Gabriel |

I collect citations in Zotero (which is great for scraping citations from worldcat, jstor, etc.) but because I use Lyx rather than Word, I actually use citations in Bibtex. Unfortunately this creates some problems with diacriticals (aka, accent marks). I had been temporarily solving this by simplifying the offending characters to be plain ASCII characters but I figured out that I can solve things by hand-editing the Bibtex files.

For instance, consider these citations:

Dávila, Arlene. 2001. Latinos, Inc.: The Marketing and Making of a People. Berkeley CA: University of California Press.

Denrell, Jerker, and Balázs Kovács. 2008. “Selective Sampling of Empirical Settings in Organizational Studies.” Administrative Science Quarterly 53:109-144.

Zotero can handle both of them natively, but when you export to Bibtex the author fields appear like this:

	author = {Arlene Da ́vila},
	author = {Jerker Denrell and Balázs Kovács},

In the case of Kovács the diacriticals are already applied to the vowels and in the case of Dávila the diacritical mark is after the vowel instead of before and isn’t backslashed. If you render this, “Da ́vila” crashes LaTeX and “Kovács” renders but looks like comic strip profanity rather than “Kovács.”

The best solution is to handle entries with diacriticals in a hand-edited Bibtex file. In particular, the two entries should look like this:

	author = {Arlene D\'avila},
	author = {Jerker Denrell and Bal\'azs Kov\'acs},

It renders beautifully and you don’t have to insult speakers of Spanish or Magyar by dropping the diacriticals.

January 18, 2011 at 5:22 am 5 comments

Dropbox, Exploiting the Alias vs Symlink Distinction

| Gabriel |

Yesterday I described how I started using Dropbox by keeping my file system as is and adding symbolic links to ~/Dropbox. (As described in that post, this is a good strategy if you mostly use one computer but a bad idea if you frequently use multiple computers and/or use Dropbox to collaborate).

Today I have an even simpler tip. Dropbox follows symbolic links but ignores aliases. This means that if you want to exclude a subdirectory from being archived (and hence counting against your disk quota) you can move it to a directory that is not linked to Dropbox and add an alias to the original location. For instance, in many of my project directories about half the space is taken up by a “lit” subdirectory where I put PDFs of related literature. I can move all of these to be subdirectories of “~/Documents/litreviews” (which is not linked to ~/Dropbox) and then add aliases to the respective project directories (which are linked).

Since I don’t usually do anything with article PDFs that would benefit from symbolic links this is no big deal, but for other kinds of files (eg, datasets or graphs) it could cause a problem. For instance, if I have two overlapping projects I’ll often have a symbolic link to let them share a data and/or output directory and I expect Stata, R, and Lyx to follow that link. Anyway, the point is that this tip is most useful for files that:

  • you don’t need off-site access to (perhaps because you can always find them again on JSTOR)
  • are large or numerous enough that your disk quota takes an appreciable hit
  • you don’t otherwise use through software that can read symbolic links but not aliases

January 13, 2011 at 4:02 am

Dropbox

| Gabriel |

I’ve started playing with Dropbox lately. This is useful both as backup and as a user-friendly (but limited capacity) alternative to RCS on the Subversion model. The way it works is that Dropbox creates a folder called ~/Dropbox, then syncs everything in that folder to the cloud. The trouble is how I integrate it into my existing file system. Here are a few options:

  1. Hard links. That is, basically have the same file be located in two places at once. This seems ideal but is actually a bad idea since hard links can be broken pretty easily and you end up with two files rather than one file in two places. The only thing I’m comfortable using hard links for is incremental backup (as in my time-stamped scraping workflow), but I try not to use them in an active file system where all sorts of programs are doing God knows what to the file system.
  2. Symbolic links to ~/Dropbox. That is, keep my files where they were and put a symbolic link in ~/Dropbox. This is really easy to script and generally low hassle. The downside to this is that it can screwed up if you’re using Dropbox to sync between two computers.
  3. Symbolic links from ~/Dropbox. That is, keep the file in ~/Dropbox and put a symbolic link in the original location. The appeal is that it solves the problem noted above. The problem is that this kills any relative paths from the document. For instance, my book is a Lyx file that links to rather than contains the graphs. The graphs are specified as relative paths and so Latex can’t find them if I keep the file itself in ~/Dropbox and put a symlink in ~/Documents/book. Furthermore, in any kind of file browsing at the original location, the file type shows up as a symbolic link rather than a “Lyx Document,” “Stata do-file,” or whatever. I can still tell what it is by the icon and extension, but I can’t sort by file type.
  4. Two copies, synced with Unison. Instead of linking, keep a copy of the file in both the original location and in ~/Dropbox. Then cron Unison to ensure that they are always current. The problem with this is that I’m using Dropbox in part to avoid having to learn how to script Unison.

Of these, #4 (Unison) strikes me as the most elegant but for my needs #2 (symlinks in ~/Dropbox) is the most practical and I’m too busy right now to really get my geek on. I’m almost always using my MacBook and on those rare occasions when I’m using another computer, I’ll just treat the main directories on the Dropbox cloud as read-only and then manually sync the updates to my Macbook’s original file system (and by extension, ~/Dropbox and the Dropbox cloud). If I ever get into a situation of regularly using multiple computers, I’ll probably do the Unison thing. Alternately, I could just pay $20/month to buy such a massive Dropbox account that I could basically treat it as my ~/Documents folder, which would eliminate the issue altogether.

Anyways, for now, I’m just keeping everything where it is and adding symbolic links to ~/Dropbox. To make this really easy, I used Automator to save this script as a right-clickable Finder (or PathFinder) service so I can easily send a symbolic link of a file to my ~/Dropbox directory.

#bin/bash
for f in "$@"
do
	FILENAME=`basename $f`
	DIRPATH=`dirname $f | sed 's/  *//g' | sed 's/\//\./g' | sed 's/^.//'` 
	ln -s "$f" ~/Dropbox/$DIRPATH.$FILENAME
done

This script creates a symbolic link inside ~/Dropbox. The symbolic link is named for the full path of the linked file, but with spaces suppressed and with all “/” (except the leading one) turned into “.” . For instance, if I apply the service to a file called:

/Users/rossman/Documents/book/book.lyx

it creates a symbolic link to this file called

/Users/rossman/Dropbox/Users.rossman.Documents.book.book.lyx

It also works on directories, eg, this:

/Users/rossman/Documents/miscservice/peerreview

gets this link:

/Users/rossman/Dropbox/Users.rossman.Documents.miscservice.peerreview

January 12, 2011 at 5:03 am 4 comments

Bright light city gonna set my soul on fire

| Gabriel |

January 4, 2011 at 1:32 pm 1 comment

Older Posts


The Culture Geeks