#-------------------------------------------------- # 1. Advanced functions # # Things to learn: # matching order (full names, partial names, position) # ... slurps up all the extra arguments # anonymous functions f <- function(x,count=10) { paste(rep(x,length=count)) } f('me') # use the default value for count f('me',count=3) # override the default value for count f(count=3,'me') # named arguments can be put anywhere in the argument list f(co=3,'me') # named arguments can be abbreviated f <- function(x,count=10,...) { cat('You passed an extra',length(list(...)),'arguments\n') paste(rep(x,length=count), ...) } f(count=3,'me','and you') # extra arguments are slurped into ..., and can be passed on f(count=3,'me',collapse='-') # extra arguments may be named or unnamed (function(x) {y <- x+1; y^2})(10) #---------------------------------------- # 2. Lattice Graphics # # Things to learn: # xyplot (draws a scatter plot) print(load('../Data/iraq.Rdata')) diary[1:5,c('date','type','category','civiliankia')] library(lattice) # load in the graphics library # A simple scatterplot. # Here civiliankia and date are columns from the diary data frame, # so we need to tell xyplot that the data is drawn from diary. xyplot(cumsum(civiliankia)~date, data=diary) # The default is to draw circles. To draw lines instead, xyplot(cumsum(civiliankia)~date, data=diary, type='l') # Speed it up by only plotting a subset n <- nrow(diary) xyplot(cumsum(civiliankia)~date, data=diary, subset=seq(1,n,length=1000)) # Add in some extra lines for other columns from the data frame xyplot(cumsum(civiliankia) + cumsum(hostnationkia) + cumsum(enemykia) + cumsum(friendlykia) ~ date, data=diary, subset = seq(1,n,length=1000)) # Add a legend, and make the y axis label more sensible xyplot(cumsum(civiliankia) + cumsum(hostnationkia) + cumsum(enemykia) + cumsum(friendlykia) ~ date, data=diary, subset = seq(1,n,length=1000), auto.key=TRUE, ylab='kia') #---------------------------------------- # 3. Grouping and conditioning # # Things to learn: # y~x|cond, groups=g # For more sophisticated graphics, it's helpful # to work with the data in 'long form' diarym[1:10,] diarym$date <- diarym$year + (diarym$mth+1)/12 # This says: split the data frame into pieces, one for each value of count, # and for each piece draw a separate line. Here count is a column which # takes values civiliankia, civilianwia, friendlykia, friendlywia, etc. xyplot(n~date, groups=count, data=diarym, type='l', auto.key=TRUE) # There are too many lines. It'd be easier to read if we had two panels, # one for kia and one for wia, and four lines in each. # First, we need to add extra columns (who=civilian,friendly,... and how=kia,mia). nn <- nchar(as.character(diarym$count)) diarym$who <- factor(substr(diarym$count,1,nn-3)) diarym$how <- factor(substr(diarym$count,nn-2,nn)) diarym[1:10,] # Now we can plot it. The syntax n~date|how, groups=who, says: # split the data into pieces, one for each possible pair of values (how,who), where how and who # are factors. Draw one panel for each level of how (kia or wia). Within each panel, # draw one line for each level of who (civilian or friendly or ...). xyplot(n~date|how, groups=who, data=diarym, type='l', auto.key=TRUE) # It's very simple to pivot, e.g. plot one panel for each level of who, # one line for each level of how. xyplot(n~date|who, groups=how, data=diarym, type='l', auto.key=TRUE) # Anything you want plotted you should plot by setting up an # appropriate data frame, with columns for x-coord, y-coord, and # anything you want to split by. For example, two superimpose two EDFs, samp1 <- runif(100) samp2 <- rexp(800) df <- rbind(data.frame(x=sort(samp1),y=length(samp1):1/length(samp1),sample='unif'), data.frame(x=sort(samp2),y=length(samp2):1/length(samp2),sample='exp')) xyplot(y~x, groups=sample, data=df, type='l', auto.key=TRUE) #-------------------------------------------------- # 4. Customizing what is drawn # # Things to learn: # panel # anonymous functions # The xyplot command is a wrapper which simply works out what data belongs in each panel. # It then passes the relevant data to a panel function, which is what actually does the drawing. # The default panel function for xyplot is called panel.xyplot(x,y,...) # To customize the drawing, e.g. to add a design to each panel, override the panel function. xyplot(n~date|who, groups=how, data=diarym, type='l', panel = function(x,y,...) { lrect(2007.1,0,2008.5,5000, col='grey80', border='transparent') # draw a rectangle panel.xyplot(x,y,...) # plot the lines as usual using the default panel function. }) # Any arguments that xyplot doesn't understand itself, it passes on to the panel function. # Here, xyplot doesn't know what to do with type='l' or extraarg='fiddlesticks', so it passes # them both on. panel.xyplot does know what to do with type='l', namely, draw lines rather than points. xyplot(n~date|who, groups=how, data=diarym, type='l', extraarg='fiddlesticks', panel = function(x,y,...) { lrect(2007.1,0,2008.5,5000, col='grey80', border='transparent') panel.xyplot(x,y,...) print(names(list(...))) })