#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create:
# README
# Snotes.tex
# S.sty
# fancyheadings.sty
# parskip.sty
# titlepage.sty
# This archive created: Tue Dec 18 16:26:39 1990
export PATH; PATH=/bin:/usr/bin:$PATH
echo shar: "extracting 'README'" '(1731 characters)'
if test -f 'README'
then
echo shar: "will not over-write existing file 'README'"
else
sed 's/^ X//' << \SHAR_EOF > 'README'
XThis is Version 1.1 of
X
X "Notes on `S: a Programming Environment for Data
X Analysis and Graphics'"
X
Xby Bill Venables, (wvenable@spam.adelaide.edu.au). It replaces all prior
Xversions, some of which were unlabelled.
X
XThese notes are intended to serve as a simple introduction to S, without
Xtoo much gross oversimplification. They do not replace the manual in any
Xway but rather are intended to smooth the way to an easier relationship
Xwith the manual.
X
XThe shar file contains the following files
X
X README This file.
X Snotes.tex The S notes themselves - A Latex file.
X S.sty Some definitions for the notes.
X fancyheadings.sty for special headings.
X parskip.sty for some paragraph features.
X titlepage.sty for a separate titlepage.
X
XThe last three .sty files may well be available on your system anyway.
X
XThe document is designed to be printed on A4 paper and subsequently
Xphoto-reduced to half size and produced as a small booklet of A5 size. For
Xthis reason the default pointsize is 12pt.
X
XIf you intend to produce the document on Quarto sized paper the
X"\textheight" parameter in "S.sty" should be changed to from 9.3in to 8.5in,
Xand the pointsize could be changed from "12pt" to "11pt" near the head of
Xthe main document, "Snotes.tex".
X
XIf in addition, you intend to print the document on one side of the paper
Xonly, the "twoside" option near the head of "Snotes.tex" could simply be
Xremoved.
X
XI have no objection to anyone copying and redistributing these notes and
Xusing them for any educational purpose, so long as the copyright notices
Xremain intact. Where necessary, a small charge just to cover the costs of
Xreproduction and distribution is, of course, quite acceptable, but I do
Xobject to their sale for profit.
SHAR_EOF
if test 1731 -ne "`wc -c < 'README'`"
then
echo shar: "error transmitting 'README'" '(should have been 1731 characters)'
fi
fi
echo shar: "extracting 'Snotes.tex'" '(78244 characters)'
if test -f 'Snotes.tex'
then
echo shar: "will not over-write existing file 'Snotes.tex'"
else
sed 's/^ X//' << \SHAR_EOF > 'Snotes.tex'
X% -*-latex-*-
X% Document name: Snotes.tex
X%
X% Version 1.1 16 December, 1990.
X%
X% LaTeX version: Lucien W. Van Elsen [lwvanels@FIONAVAR.mit.edu]
X% and W. Venables [wvenable@spam.adelaide.edu.au]
X% Creation Date: 16 Dec., 1990.
X\documentstyle[12pt,parskip,titlepage,twoside,fancyheadings,S]{article}
X
X\pagestyle{fancy}
X\setlength\headrulewidth{0pt}
X\renewcommand{\sectionmark}[1]{\markboth{#1}{#1}}
X\cfoot{\small\sf\thepage}
X\raggedbottom
X\pagenumbering{roman}
X
X\title{Notes on\\[0.5cm]
X{\sl S: A Programming Environment}\\[0.5cm]
X{\sl for Data Analysis and Graphics}}
X\author{W. Venables\\Department of Statistics\\
XThe University of Adelaide\\[0.5cm]
XEmail: {\tt wvenable@spam.adelaide.edu.au}\\[0.5cm]
X\copyright\ W. Venables, 1990.}
X\date{16th December, 1990 }
X\begin{document}
X\maketitle
X\centerline{\huge\bf Preface}
X\addcontentsline{toc}{section}{Preface}
X\lhead[\fancyplain{}{}]{}
X\rhead[\fancyplain{}{}]{}
X\bigskip
XThese notes were originally intended only for local consumption at the
XUniversity of Adelaide, South Australia. After some encouraging comments
Xfrom students, the author decided to release them to a larger readership in
Xthe hope that in some small way they promote good data analysis. \s. is no
Xpanacea, of course, but in offering simply a coherent suite of general and
Xflexible tools to devise precisely the right kind of analysis, rather than a
Xcollection of packaged standard analyses, in my view it represents the
Xsingle complete environment most conducive to good data analysis so far
Xavailable.
X
XSome evidence of the local origins of these notes is still awkwardly
Xapparent. For example they use the Tektronics graphics emulations on
Xterminals and workstations, which at the time of writing is still the only
Xone available to the author. The {\sf X11} windowing system, which allows
Xseparate windows for characters and graphics simultaneously to be
Xdisplayed, is much to be preferred and it will be used in later versions.
XAlso the local audience would be very familiar with {\sf MINITAB}, {\sf
XMATLAB}, {\sf Glim} and {\sf Genstat}, and various echoes of these persist.
XAt one point some passing acquaintance with the Australian States is
Xassumed, but the elementary facts are given in a footnote for foreign
Xreaders.
X
XComments and corrections are always welcome. Please address email
Xcorrespondence to the author at {\tt wvenable@spam.adelaide.edu.au}.
X
XThe author is indebted to many people for useful contributions, but in
Xparticular Lucien W.~Van~Elsen, who did the basic \TeX{} to \LaTeX{}
Xconversion and Rick Becker who offered an authoritative and extended
Xcritique on an earlier version. Responsibility for this version, however,
Xremains entirely with the author, and the notes continue to enjoy a fully
Xunofficial and unencumbered status.
X
XThese notes may be freely copied and redistributed for any educational
Xpurpose provided the copyright notice remains intact. Where appropriate, a
Xsmall charge to cover the costs of production and distribution, only, may
Xbe made.
X
X\bigskip
X\rightline{\vbox{\hbox{Bill Venables,}
X \hbox{University of Adelaide,}
X \hbox{16th December, 1990.}}}
X
X\newpage
X
X\tableofcontents
X
X\newpage
X\lhead[\fancyplain{}{\small\sf\thepage}]{\fancyplain{}{\small\sf\rightmark}}
X\rhead[\fancyplain{}{\small\sf\leftmark}]{\fancyplain{}{\small\sf\thepage}}
X\cfoot{}
X
X\section{Introduction}
X\pagenumbering{arabic}
X
X\s. is an integrated suite of software facilities for data manipulation,
Xcalculation and graphical display. Among other things it has
X
X \begin{itemize}
X \item an effective data handling and storage facility,
X \item a suite of operators for calculations on arrays, in particular
X matrices,
X \item a large, coherent, integrated collection of intermediate tools for
X data analysis,
X \item graphical facilities for data display either at a terminal or on
X hardcopy, and
X \item a well developed, simple and effective programming language which
X includes conditionals, loops, user defined recursive functions and
X input and output facilities. (Indeed most of the system supplied
X functions are themselves written in the \s. language.)
X \end{itemize}
X
XThe term ``environment'' is intended to characterize it as a fully planned
Xand coherent system, rather than an incremental accretion of very specific
Xand inflexible tools, as is frequently the case with other data analysis
Xsoftware.
X
XThe name \s. is, as with many names within the {\sf UNIX} world, left as a
Xcryptic enigma, and probably a weak pun. However it does {\sl not\/} stand
Xfor ``Statistics''!
X
X\subsection{Reference Manuals}
X
XThe basic reference is {\sl The New \s. Language: A Programming Environment
Xfor Data Analysis and Graphics\/} by Richard A.~Becker, John M.~Chambers
Xand Allan R.~Wilks.
X
XIt is not the intention of these notes to replace this manual. Rather these
Xnotes are intended as a brief introduction to the \s. programming language
Xand a minor amplification of some important points. Ultimately the user of
Xthe \s. package will need to consult this reference manual, probably
Xfrequently.
X
X\subsection{Using \s. at a Terminal}
X
XWhen you use the \s. program it issues a prompt when it expects input
Xcommands. The default prompt is ``\/{\tt>}'', which is sometimes the same
Xas the shell prompt, and so it may appear that nothing is happening.
XHowever, as we shall see, it is easy to change to a different \s. prompt if
Xyou wish. In these notes we will assume that the shell prompt is
X``\/{\tt\$}''.
X
XIn using \s. the suggested procedure for the first occasion is as follows:
X
X \begin{enumerate}
X \item Create a separate sub-directory, say {\tt job1}, to hold data
X files on which you will use the \s. package for this problem. This
X will be the working directory whenever you use \s. for this
X particular problem.
X
X\Shell mkdir job1
X
X\Shell cd job1
X
X \item Place any data files you wish to use with \s. in {\tt job1}.
X
X \item Create a sub-directory of {\tt job1} called {\tt .Data} for use
Xby \s..
X
X\Shell mkdir .Data
X
X \item Start the \s. program with the command
X
X\Shell \s.
X
X \item At this point \s. commands may be issued (see later).
X
X \item To quit the \s. program the command is
X
X\Sprompt q()
X
X\Shell
X
X \end{enumerate}
X
XThe procedure is simpler using \s. after the first time:
X
X Make {\tt job1} the working directory and start the program as
Xbefore:
X
X\Shell cd job1
X
X\Shell \s.
X
X Use the \s. program, terminating with the {\tt q()} command at the
Xend of the session.
X
X\subsection{An Introductory Session}
X
XThe sample session given below is presented largely without explanation and
Xis intended to show by example some of the capabilities of the system.
XWork through the session given by the commands on the left of the page.
XSome clues as to what is going on are given at the right hand side of the page.
X
X{\tabskip=0pt
X\halign to \hsize{\vphantom{\vrule height 4ex depth 0pt width
X0pt}\tt#\hfil\tabskip=\hsize plus 0pt minus
X1fil&\vtop{\noindent\hsize=3.25truein\small\rm#}\tabskip=0pt\cr
X\$ cd job1&Change to an \s. directory (if necessary)\cr
X\$ S&Start the session on \s.\cr
X> tek4014()&Declare the graphics device type (assuming you are at a
Xgraphics terminal with Tektronics 4014 emulation).\cr
X> x <- 1:20&Generate $x-$values (`{\tt<-}' = `less minus')\cr
X> y <- x + 2*rnorm(x)&Generate some $y-$values\cr
X> cbind(x,y)&Print $x-$and $y-$values as a matrix\cr
X> \{plot(x,y)&Point plot of $y$ versus $x$, but nothing happens yet\dots\cr
X+ abline(0,1,lty=3)&Add a dashed line, with intercept 0 and slope 1, (but
Xstill nothing\dots) \cr
X+ abline(lsfit(x,y))&Add the least squares regression line, (not even
Xyet\dots)\cr
X+ lines(spline(x,y))\}&and also an exact spline fit, and show it all at
Xlast.\cr
X> &(At this point you may need to change back from graphics mode to character
Xmode at your terminal.)\cr
X> x <- rnorm(50)&Generate 50 `random' $x-$coordinates \cr
X> y <- rnorm(x)&Generate the same number of $y-$coordinates \cr
X> hull <- chull(x,y)&Find the convex hull of the points in the plane \cr
X> \{plot(x,y)&Plot a scatter diagram, \dots\cr
X+ polygon(x[hull],y[hull],dens=15)\}&Mark in the convex hull, and
Xdisplay.\cr
X> x <- seq(-pi,pi,len=50)&Generate a sequence of 50 points in the range
X$ -\pi \leq x \leq \pi$, equally spaced.\cr
X> f <- 1/(1+x\pow2)&Calculate a function of $x$\cr
X> z <- f \%o\% cos(x)&Now $z = f(x)*\cos(y)$, a function in the plane\cr
X> contour(x,x,z)&Make a contour map\cr
X> contour(x,x,z,nint=15,add=T)&Add more lines to the contour map\cr
X> za <- (z-t(z))/2&{\tt t(\dots)} is the matrix transpose function, so {\sl
Xza\/} is the ``skew-symmetric part of $z$"\cr
X> contour(x,x,za,nint=15)&Make a contour map\cr
X> persp(za)&Draw up a perspective diagram\cr
X> th <- seq(-pi,pi,len=100)& Get 100 equally spaced points on the circle\cr
X> plot(cos(th),sin(th),type="l")&Draw in a ``circle" and note the
Xdistortion due to unequal axes (``{\tt l}"=``ell'')\cr
X> par(pty="s")&Specify that the graph must be square\cr
X> plot(cos(th),sin(th),type="l")&Now it looks more like a circle.\cr
X> w <- rnorm(100)+rnorm(100)*1i; w&A sample of 100 complex numbers with
Xindependent standard normal real and imaginary parts, and look at them\cr
X> w <- ifelse(Mod(w)>1, 1/w, w)&Map any points outside the unit disc
Xinside.\cr
X> \{plot(cos(th),sin(th),type="l",&Put in the unit disc. Nothing happens
Xyet\dots\ \cr
X> xlab="Re(w)",ylab="Im(w)")&Set up axis labels at the same time\cr
X> points(Re(w),Im(w),pch="+")\}&Add the sample points and display. \cr
X> usa()&Geographical display\cr
X> q()&Finish session\cr
X\$\quad logout&and logout\cr}}
X
X\subsection{\s. and {\sf UNIX}}
X
X\s. allows escape to the operating system at any time in the session. If a
Xcommand, on a new line, begins with an exclamation mark then the rest of
Xthe line is interpreted as a {\sf UNIX} command. So for example to look
Xthrough a data file without leaving \s. you could use
X
X\Sprompt !more curious.dat
X
XWhen you finish paging the file the \s. session is resumed.
X
XIn fact the integration of \s. into {\sf UNIX} is very complete. For
Xexample, there is a command, {\tt unix(\dots)}, that executes any unix
Xcommand, (specified as a character string argument), and passes on any
Xoutput from the command as a character string to the program. Essentially
Xthe full power of the operating system remains easily available to the user
Xof the \s. program during any session.
X
X\subsection{Getting Help with Functions and Features}
X
X\s. has an inbuilt help facility similar to the {\tt man} facility of {\sf
XUNIX}. To get more information on any specific named function, for example
X{\tt solve} the command is
X
X\Sprompt help(solve)
X
XFor a feature specified by special characters, the argument must be
Xenclosed in double quotes, making it a `character string':
X
X\Sprompt help("[[")
X
XThe facilities available in \s. run to several hundred, but some are only
Xused in very special situations. The appendix to these notes provides a
Xlist of names of \s. functions and features.
X
X\subsection{\s. Commands. Case Sensitivity.}
X
XTechnically \s. is a {\sl function language\/} with a very simple syntax.
XIt is {\sl case sensitive\/} as are most {\sf UNIX} based packages, so {\tt
XA} and {\tt a} are different variables.
X
XElementary commands consist of either {\sl expressions\/} or {\sl
Xassignments\/}. If an expression is given as a command, it is evaluated,
Xprinted, and the value is lost. An assignment also evaluates an expression
Xand passes the value to a variable but the result is not printed
Xautomatically.
X
XCommands are separated either by a semi-colon, {\tt ;}, or by a newline.
XIf a command is not complete at the end of a line, \s. will give a
Xdifferent prompt, namely
X
X\Contd \
X
Xon second and subsequent lines and continue to read input until
Xthe command is syntactically complete.
X
X\subsection{Recall and Correction of Previous Commands: {\tt fep}}
X
XThere is no automatic recall of past commands, however if the \s. session
Xis passed though a `front end processor' such as {\tt fep},
X
X\Shell fep \s.
X
Xcommands may be recalled and modified at will. The facilities
Xoffered by {\tt fep} are quite extensive and repay becoming familiar with
Xthem.
X
XOne small point to notice is that to use the {\tt !} shell escape facility
Xyou must precede the {\tt !} by a blank character, since otherwise it will
Xbe interpreted by {\tt fep} as a recall command. (The author is indebted
Xto Peter Dalgaard for this remark.) Also, if the shell escape is to use an
Xeditor, it may be necessary to use the somewhat enigmaticly named
X``toggle transparency'' feature of {\tt fep}.
X
XUse of a front end processor, if possible, is strongly recommended.
X
X\subsection{Executing Commands from an External File. Diverting Output}
X
XIf commands are stored on an external file, say {\tt commands.inp} in the
Xworking directory {\tt job1}, they may be executed at any time in an \s.
Xsession with the command
X
X\Sprompt source("commands.inp")
X
XThis can provide a useful adjunct to the interactive use of the
Xprogram. Similarly
X
X\Sprompt sink("record.lis")
X
Xwill divert all subsequent output from the terminal to an external
Xfile, {\tt record.lis}. The command
X
X\Sprompt sink()
X
Xrestores it to the terminal once again.
X
X\subsection{Data Directories. Removing Unwanted Objects.}
X
XAll objects created during your \s. sessions are stored, in a special form,
Xin the {\tt .Data} sub-directory of your working directory {\tt job1}, say.
XEach object is held as a separate file of the same name and so may be
Xmanipulated by the usual {\sf UNIX} commands such as {\tt rm}, {\tt cp} and
X{\tt mv}. This means that if you resume your \s. session at a later time,
Xobjects created in previous sessions are still available, which is a highly
Xconvenient feature.
X
XThis also explains why it is recommended that you should use separate
Xworking directories for different jobs. Common names for objects are
Xsingle letter names like {\tt x}, {\tt y} and so on, and if two problems
Xshare the same {\tt .Data} sub-directory the objects will become mixed up
Xand you may overwrite one with another.
X
XIn \s., to get a list of names of the objects currently defined use the
Xcommand
X
X\Sprompt ls()
X
Xwhose result is a character vector of the names.
X
XWhen \s. looks for an object, it searches in turn through a sequence of
Xdirectories known as the {\sl search list}. Usually the first entry in the
Xsearch list is the {\tt .Data} sub-directory of the current working
Xdirectory. The names of the directories currently on the search list are
Xheld in the character vector object {\tt .Search.list}, which can be
Xdisplayed as usual by simply naming it
X
X\Sprompt .Search.list
X
XThe names of the objects held in any directory on the search list can be
Xdisplayed by giving the {\tt ls} function an argument. For example {\tt
Xls(pos=2)} lists the contents of the second directory in the search list.
X
XExtra search directories can be added to this list with the {\tt
Xattach(\dots)} function and removed with the {\tt detach(\dots)} function,
Xdetails of which can be found in the manual or the {\tt help} facility.
X
XTo remove objects permanently the function {\tt rm} is available:
X
X\Sprompt rm(x,y,z,in,junk,temp)
X
XThe function {\tt remove(\dots)} can be used to remove objects
Xwith non-stan\-dard names. Also the ordinary {\sf UNIX} facility, {\tt
Xrm}, may be used to remove the appropriate files in the {\tt .Data}
Xdirectory, as mentioned above.
X
X\section{Simple Data Manipulation. Constants and Vectors}
X
X\subsection{Vectors}
X
X\s. operates on named {\sl data structures\/}. The simplest such structure
Xis the {\sl vector\/}, which is a single entity consisting of an ordered
Xcollection of numbers. To set up a vector named {\tt x}, say, consisting
Xof five numbers, namely $10.4$, $5.6$, $3.1$, $6.4$ and $21.7$, use the \s.
Xcommand
X
X\Sprompt x <- c(10.4, 5.6, 3.1, 6.4, 21.7)
X
XThis is an {\sl assignment\/} statement using the {\sl
Xfunction\/} {\tt c(\dots)} taking an arbitrary number of vector {\sl
Xarguments\/} and whose value is a vector got by concatenating its arguments
Xend to end.
X
XA number occurring by itself in an expression is taken as a vector of
Xlength one.
X
XNotice that the assignment operator is {\bf not} the usual {\tt =}
Xoperator, which is reserved for another purpose. It consists of the two
Xcharacters {\tt<} (`less than') and {\tt-} (`minus') occurring strictly
Xside-by-side and it `points' to the structure receiving the value of the
Xexpression. Assignments can also be made in the other direction, using the
Xobvious change in the assignment operator. So the same assignment could be
Xmade using
X
X\Sprompt c(10.4, 5.6, 3.1, 6.4, 21.7) -> x
X
XIf an expression is used as a complete command, the value is printed {\sl
Xand lost\/}. So now if we were to use the command
X
X\Sprompt 1/x
X
Xthe reciprocals of the five values would be printed at the
Xterminal (and the value of {\tt x}, of course, unchanged).
X
XThe further assignment
X
X\Sprompt y <- c(x,0,x)
X
Xwould create a vector {\tt y} with $11$ entries consisting of two
Xcopies of {\tt x} with a zero in the middle place.
X
X\subsection{Vector Arithmetic}
X
XVectors can be used in arithmetic expressions, in which case the operations
Xare performed element-by-element. Vectors occurring in the same expression
Xneed not all be of the same length. If they are not, the value of the
Xexpression is a vector with the same length as the longest vector which
Xoccurs in the expression. Shorter vectors in the expression are {\sl
Xrecycled\/} as often as need be (perhaps fractionally) until they match the
Xlength of the longest vector. In particular a constant is simply repeated.
XSo with the above assignments the command
X
X\Sprompt v <- 2*x + y + 1
X
Xgenerates a new vector {\tt v} of length $11$ constructed by
Xadding together, element-by-element, {\tt 2*x} repeated $2.2$ times, {\tt
Xy} repeated just once, and {\tt 1} repeated $11$ times.
X
XThe elementary arithmetic operators are the usual {\tt+}, {\tt-}, {\tt*},
X{\tt/} and {\tt\pow} for raising to a power. In addition all of the common
Xarithmetic functions are available. {\tt log}, {\tt exp}, {\tt sin}, {\tt
Xcos}, {\tt tan}, {\tt sqrt}, and so on, all have their usual meaning. {\tt
Xmax} and {\tt min} select the largest and smallest elements of an vector
Xrespectively. {\tt range} is a function whose value is a vector of length
Xtwo, namely {\tt c(min(x),max(x))}. {\tt length(x)} is the number of
Xelements in {\tt x}, {\tt sum(x)} gives the total of the elements in {\tt
Xx} and {\tt prod(x)} their product.
X
XTwo statistical functions are {\tt mean(x)} which evaluates to {\tt
Xsum(x)/length(x)} and {\tt var(x)} which gives the value {\tt
Xsum((x-mean(x))\pow2)/(length(x)-1)}, or sample variance. If the argument
Xto {\tt var(\dots)} is an $n\times p$ matrix the value is a $p\times p$
Xsample covariance matrix got by regarding the rows as independent
X$p-$variate sample vectors.
X
X{\tt sort(x)} returns a vector of the same size as {\tt x} with the
Xelements arranged in increasing order; however there are other more
Xflexible sorting facilities available (see {\tt order(\dots)} which
Xproduces a permutation to do the sorting).
X
X{\tt rnorm(x)} is a function which generates a vector (or more generally an
Xarray) of pseudo-random standard normal deviates, of the same size as {\tt
Xx}.
X
X\subsection{Generating Regular Sequences of Numbers. Named Arguments}
X
X\s. has a number of facilities for generating commonly used sequences of
Xnumbers. For example {\tt 1:30} is the vector {\tt c(1,2,\dots,29,30)}.
XThe colon operator has highest priority within an expression, so, for
Xexample {\tt 2*1:15} is the vector {\tt c(2,4,6,\dots,28,30)}. Put {\tt n
X<- 10} and compare the sequences \quad {\tt 1:n-1} \quad and \quad {\tt
X1:(n-1)}.
X
XThe construction {\tt 30:1} may be used to generate a backwards sequence.
X
XThe function {\tt seq(\dots)} is a more general facility for generating
Xsequences. It has five arguments, only some of which may be specified in
Xany one call. The first two arguments, if given, specify the beginning and
Xend of the sequence, and if these are the only two arguments given the
Xresult is the same as the colon operator. That is {\tt seq(2,10)} is the
Xsame vector as {\tt 2:10}.
X
XParameters to {\tt seq(\dots)}, and to many other \s. functions, can also
Xbe given in named form, in which case the order in which they appear is
Xirrelevant. The first two parameters may be named {\tt from={\sl value}}
Xand {\tt to={\sl value}}; thus {\tt seq(1,30)}, {\tt seq(from=1,to=30)} and
X{\tt seq(to=30,from=1)} are all the same as {\tt 1:30}. The next two
Xparameters to {\tt seq(\dots)} may be named {\tt by={\sl value}} and {\tt
Xlength={\sl value}}, which specify a step size and a length for the
Xsequence respectively. If neither of these is given, the default {\tt
Xby=1} is assumed.
X
XFor example
X
X\Sprompt seq(-5,5,by=.2) -> s3
X
Xgenerates in {\tt s3} the vector {\tt
Xc(-5.0,-4.8,-4.6,\dots,4.6,4.8,5.0)}. Similarly
X
X\Sprompt s4 <- seq(length=51,from=-5,by=.2)
X
Xgenerates the same vector in {\tt s4}.
X
XThe fifth parameter may be named {\tt along={\sl vector}}, which if used
Xmust be the only parameter, and creates a sequence {\tt 1, 2, \dots,
Xlength({\sl vector\/})}, or the empty sequence if the vector is empty (as
Xit can be).
X
XA related function is {\tt rep(\dots)} which can be used for replicating a
Xstructure in various complicated ways. The simplest form is
X
X\Sprompt s5 <- rep(x,times=5)
X
Xwhich will put five copies of {\tt x} end-to-end in {\tt s5}.
X
X\subsection{Logical Vectors. Missing Values}
X
XAs well as numerical vectors, \s. allows manipulation of logical
Xquantities. The elements of a logical vectors have just two possible
Xvalues, represented formally as {\tt F} (for `false') and {\tt T} (for
X`true').
X
XLogical vectors are generated by {\sl conditions\/}. For example
X
X\Sprompt temp <- x>13
X
Xsets {\tt temp} as a vector of the same length as {\tt x} with
Xvalues {\tt F} corresponding to elements of {\tt x} where the condition is
X{\sl not\/} met and {\tt T} where it is.
X
XThe logical operators are {\tt <}, {\tt <=}, {\tt >}, {\tt >=}, {\tt ==}
Xfor exact equality and {\tt !=} for inequality. In addition if {\tt c1}
Xand {\tt c2} are logical expressions, then {\tt c1$\,$\&$\,$c1} is their
Xintersection, {\tt c1$\,$|$\,$c2} is their union and {\tt !$\,$c1} is the
Xnegation of {\tt c1}.
X
XLogical vectors may be used in ordinary arithmetic, in which case they are
X{\sl coerced\/} into numeric vectors, {\tt F} becoming {\tt 0} and {\tt T}
Xbecoming {\tt 1}. However there are situations where logical vectors and
Xtheir coerced numeric counterparts are not equivalent, for example see the
Xnext subsection.
X
XIn some cases the components of a vector may not be completely known. When
Xan element or value is ``not available'' or a ``missing value'' in the
Xstatistical sense, a place within a vector may be reserved for it by
Xassigning it the special value {\tt NA}. In general any operation on an
X{\tt NA} becomes an {\tt NA}. The motivation for this rule is simply that
Xif the specification of an operation is incomplete, the result cannot be
Xknown and hence is not available.
X
XThe function {\tt is.na(x)} gives a logical vector of the same size as {\tt
Xx} with value {\tt T} if and only if the corresponding element in {\tt x}
Xis {\tt NA}.
X
X\Sprompt ind <- is.na(z)
X
XNotice that the logical expression {\tt x == NA} is quite different from
X{\tt is.na(x)} since {\tt NA} is not really a value but a marker for a
Xquantity that is not available. Thus {\tt x == NA} is a vector of the same
Xlength as {\tt x} {\sl all\/} of whose values are {\tt NA} as the logical
Xexpression itself is incomplete and hence undecidable.
X
X\subsection{Character vectors}
X
XCharacter quantities and character vectors are used frequently in \s., for
Xexample as plot labels. Where needed they are denoted by a sequence of
Xcharacters delimited by the double quote character. E. g. {\tt
X"x-values"}, {\tt "New iteration results"}.
X
XCharacter vectors may be concatenated into a vector by the {\tt c(\dots)}
Xfunction; examples of their use will emerge frequently.
X
XThe {\tt paste(\dots)} function takes an arbitrary number of character
Xstring arguments and concatenates them into a single character string. Any
Xnumbers given among the arguments are coerced into character strings in the
Xevident way, that is, in the same way they would be if they were printed.
XThe arguments are by default separated in the result by a single blank
Xcharacter, but this can be changed by the named parameter, {\tt sep={\sl
Xstring\/}}, which changes it to {\tt {\sl string\/}}, possibly empty.
X
XFor example
X
X\Sprompt labs <- paste(c("X","Y"), 1:10, sep="")
X
Xmakes {\tt labs} the character vector {\tt ("X1", "Y2", "X3",
X\dots, "X9", "Y10")}. Note particularly that recycling of short lists
Xtakes place here too; thus {\tt c("X", "Y")} is repeated $5$ times to match
Xthe sequence.
X
X\subsection{Index Vectors. Selecting and Modifying Subsets of a Data Set}
X
XSubsets of the elements of a vector may be selected by appending to the
Xname of the vector an {\sl index vector\/} in square brackets. More
Xgenerally any expression that evaluates to a vector may have subsets of its
Xelements similarly selected be appending an index vector in square brackets
Ximmediately after the expression.
X
XSuch index vectors can be any of three distinct types.
X
X\begin{description}
X
X\item[1. A logical vector.] In this case the index vector must be of the
Xsame length as the vector from which elements are to be selected. Values
Xcorresponding to {\tt T} in the index vector are selected and those
Xcorresponding to {\tt F} omitted. For example
X
X\Sprompt y <- x[!is.na(x)]
X
Xcreates (or re-creates) an object {\tt y} which will contain the
Xnon-missing values of {\tt x}, in the same order. Note that if {\tt x} has
Xmissing values, {\tt y} will be shorter than {\tt x}. Also
X
X\Sprompt (x+1)[(!is.na(x)) \& x>0] -> z
X
Xcreates an object {\tt z} and places in it the values of the vector {\tt
Xx+1} for which the corresponding value in {\tt x} was both non-missing and
Xpositive.
X
X\item[2. A vector of positive integral quantities.] In this case the
Xvalues in the index vector must lie in the the set $\{${\tt 1, 2, \dots,
Xlength(x)}$\}$. The corresponding elements of the vector are selected and
Xconcatenated, {\sl in that order\/}, in the result. The index vector can
Xbe of any length and the result is of the same length as the index vector.
XFor example {\tt x[6]} is the sixth component of {\tt x} and
X
X\Sprompt x[1:10]
X
Xselects the first 10 elements of {\tt x}, (assuming {\tt length(x)}
X$\geq$ {\tt 10}). Also
X
X\Sprompt c("x","y")[rep(c(1,2,2,1),times=4)]
X
X(an admittedly unlikely thing to do) produces a character vector of
Xlength 16 consisting of {\tt "x", "y", "y", "x"} repeated four times.
X
X\item[3. A vector of negative integral quantities.] In this case the
Xindex vector specifies the values to be {\sl excluded\/} rather than
Xincluded. Thus
X
X\Sprompt y <- x[-(1:5)]
X
Xgives {\tt y} all but the first five elements of {\tt x}.
X
X\end{description}
X
XAn indexed expression can also appear on the receiving end of an
Xassignment, in which case the assignment operation is performed {\sl only
Xon those elements of the vector\/}. The expression must be of the form
X{\tt vector[{\sl index\_vector\/}]} as having an arbitrary expression in
Xplace of the vector name does not make much sense here.
X
XThe vector assigned must match the length of the index vector, and in the
Xcase of a logical index vector it must again be the same length as the
Xvector it is indexing.
X
XFor example
X
X\Sprompt x[is.na(x)] <- 0
X
Xreplaces any missing values in {\tt x} by zeros and
X
X\Sprompt y[y<0] <- -y[y<0]
X
Xhas the same effect as
X
X\Sprompt y <- abs(y)\footnote{Note that {\tt abs(\ldots)} does not work as
Xexpected with complex arguments. The appropriate function for the complex
Xmodulus is {\tt Mod(\ldots)}.}
X
X\section{Objects, their Modes and Attributes.}
X
XThe entities \s. operates on are technically known as {\sl objects\/}.
XExamples are vectors of numeric (real) or complex values, vectors of
Xlogical values and vectors of character strings. These are known as
X`atomic' structures since their components are all of the same type, or
X{\sl mode\/}, namely {\sl numeric\/}\footnote{{\sl numeric\/} mode is
Xactually an amalgam of three distinct modes, namely {\sl integer\/}, {\sl
Xsingle\/} precision and {\sl double\/} precision, as explained in the
Xmanual.}, {\sl complex\/}, {\sl logical\/} and {\sl character\/}
Xrespectively.
X
XVectors must have their values {\sl all of the same mode\/}. Thus any
Xgiven vector must be unambiguously either {\sl logical\/}, {\sl numeric\/},
X{\sl complex} or {\sl character\/}. The only mild exception to this rule
Xis the special ``value'' listed as {\tt NA} for quantities not available.
XNote that a vector can be empty and still have a mode. For example the
Xempty character string vector is listed as {\tt character(0)} and the empty
Xnumeric vector as {\tt numeric(0)}.
X
X\s. also operates on objects called {\sl lists\/}, which are of mode {\sl
Xlist\/}. These are ordered sequences of objects which individually can be
Xof any mode. {\sl lists\/} are known as `recursive' rather than atomic
Xstructures since their components can themselves be lists in their own
Xright.
X
XThe other recursive structures are those of mode {\sl function\/} and {\sl
Xexpression}. {\sl Functions} are either the functions that form part of
Xthe \s. system or user written functions, which we discuss in some detail
Xlater in these notes. {\sl Expressions\/} as objects form an advanced part
Xof \s. which will not be discussed in these notes.
X
XThe mode of an object defines a general class to which it belongs. This is
Xa special case of an {\sl attribute\/} of an object. The {\sl attributes\/}
Xof an object provide specific information about the object itself. Another
Xattribute of every object is its {\sl length\/}. The functions {\tt
Xmode({\sl object\/})} and {\tt length({\sl object\/})} can be used to find
Xout the mode and length of any defined structure. More importantly these
Xfunctions can be used on the left hand side of an assignment to change the
Xattributes of an object; when this change is one of mode only, the process
Xis known as {\sl coercion\/}.
X
XFor example, if {\tt z} is complex vector of length 100, then in an
Xexpression {\tt mode(z)} is the character string {\tt"complex"} and {\tt
Xlength(z)} is {\tt 100}. Also the assignment
X
X\Sprompt mode(z) <- "numeric"
X
Xcoerces the vector to be numeric by discarding the complex parts and
Xretaining the real parts. The further assignment
X
X\Sprompt length(z) <- 10
X
Xtruncates it down to the first ten values, and then
X
X\Sprompt length(z) <- 100
X
Xlengthens it to a structure of 100 values again by padding it out with
X{\tt NA}s. A final assignment
X
X\Sprompt mode(z) <- "character"
X
Xcoerces it into a vector, not of numbers, but of character strings with the
Xvalues of the numbers as if they were to be printed. (The values {\tt NA}
Xare converted to the character string {\tt "NA"}.)
X
X{\sl mode\/} and {\sl length\/} are intrinsic attributes of all objects.
XOther attributes can be associated with an object, but need to be
Xexplicitly defined in some way. The most important of these is the {\sl
Xdim\/} attribute, which gives the dimension property of an array. If you
Xgive a numeric or complex vector a {\sl dim\/} attribute, you convert it
Xinto a multi-way array, as we shall see later.
X
XThe function {\tt attributes({\sl object\/})} gives a list of all the
Xnon-intrinsic attributes currently defined for that object. The function
X{\tt attr({\sl object},{\sl name\/})} can be used to select a specific
Xattribute. When it is used on the left hand side of an assignment it can
Xbe used either to associate a new attribute with {\tt {\sl object\/}} or to
Xchange an existing one. For example
X
X\Sprompt attr(z,"dim") <- c(10,10)
X
Xallows \s. to treat {\tt z} as if it were a $10\times10$ matrix.
X
X\section{Categories}
X
XA category is used to specify a discrete classification of the components
Xof other vectors of the same length, and as such is the direct counterpart
Xof the {\sl factor\/} concept in many statistical languages.
X
XSuppose, for example, we have a sample of 30 tax accountants from the all
Xstates and territories\footnote{Foreign readers should note that there are
Xeight states and territories in Australia, namely the Australian Capital
XTerritory, New South Wales, the Northern Territory, Queensland, South
XAustralia, Tasmania, Victoria and Western Australia.} and their individual
Xstate of origin is specified by a character vector of state mnemonics as
X
X\begin{verbatim}
X> state <- c("tas", "sa", "qld", "nsw", "nsw", "nt", "wa", "wa",
X+ "qld", "vic", "nsw", "vic", "qld", "qld", "sa", "tas",
X+ "sa", "nt", "wa", "vic", "qld", "nsw", "nsw", "wa",
X+ "sa", "act", "nsw", "vic", "vic", "act")
X\end{verbatim}
X
X\noindent (We will see later there are much less painful ways of entering
Xsuch a vector!)
X
XFor some purposes it is convenient to represent such information by a
Xnumeric vector with the distinct values in the original (in this case the
Xstate labels) represented by a small integer. Such a numeric vector is
Xcalled a {\sl category}. However at the same time it is important to
Xpreserve the correspondence of these new integer labels with the originals.
XThis is done via the {\sl levels\/} attribute of the category.
X
XMore formally, when a category is formed from such a vector the {\sl sorted
Xunique values} in the vector form the {\sl levels\/} attribute of the
Xcategory, and the values in the category are in the set {\tt 1, 2, \dots,
Xk} where {\tt k} is the number of unique values. The value at position
X{\tt j} in the factor is {\tt i} if the {\tt i}$^{\hbox{th}}$ sorted unique
Xvalue occurred at position {\tt j} of the original vector.
X
XHence the assignment
X
X\Sprompt stcode <- category(state)
X
Xcreates a category with values and attributes as follows
X
X\begin{verbatim}
X> stcode
X [1] 6 5 4 2 2 3 8 8 4 7 2 7 4 4 5 6 5 3 8 7 4 2 2 8 5 1 2 7 7 1
X attr(, "levels"):
X [1] "act" "nsw" "nt" "qld" "sa" "tas" "vic" "wa"
X\end{verbatim}
X
XNotice that in the case of a character vector, ``sorted'' means sorted in
Xalphabetical order.
X
X\subsection{The Function {\tt tapply(\ldots)} and Ragged Arrays}
X
XTo continue the previous example, suppose we have the incomes of the same
Xtax accountants in another vector (in suitably large units of money)
X
X\begin{verbatim}
X> incomes <- c(60, 49, 40, 61, 64, 60, 59, 54, 62, 69, 70, 42, 56,
X+ 61, 61, 61, 58, 51, 48, 65, 49, 49, 41, 48, 52, 46,
X+ 59, 46, 58, 43)
X\end{verbatim}
X
XTo calculate the sample mean income for each state we can now use the special
Xfunction {\tt tapply(\ldots)}:
X
X\Sprompt incmeans <- tapply(incomes, stcode, mean)
X
Xgiving a means vector with the components labeled by the levels
X
X\begin{verbatim}
X> incmeans
X act nsw nt qld sa tas vic wa
X 44.5 57.333 55.5 53.6 55 60.5 56 52.25
X\end{verbatim}
X
XSuppose further we needed to calculate the standard errors of the state
Xincome means. To do this we need to write an \s. function to calculate the
Xstandard error for any given vector. We discuss functions more fully later
Xin these notes, but since there is an in built function {\tt var(\ldots)}
Xto calculate the sample variance, such a function is a very simple one
Xliner, specified by the assignment:
X
X\Sprompt stderr <- function(x) sqrt(var(x)/length(x))
X
XAfter this assignment, the standard errors are calculated by
X
X\Sprompt incster <- tapply(incomes, stcode, stderr)
X
Xand the values calculated are then
X
X\begin{verbatim}
X> incster
X act nsw nt qld sa tas vic wa
X 1.5 4.3102 4.5 4.1061 2.7386 0.5 5.244 2.6575
X\end{verbatim}
X
XAs an exercise you may care to find the usual 95\% confidence limits for
Xthe state mean incomes. To do this you should use {\tt tapply(\ldots)}
Xonce more with the {\tt length(\ldots)} function to find the sample sizes,
Xand the {\tt qt(\ldots)} function to find the percentage points of the
Xappropriate $t-$distributions.
X
XThe function {\tt tapply(\ldots)} can be used to handle more complicated
Xindexing of a vector by multiple categories. For example, we might wish to
Xsplit the tax accountants by both state and sex. However in this simple
Xinstance what happens can be thought of as follows. The values in the
Xvector are collected into groups corresponding to the distinct entries in
Xthe category. The function is then applied to each of these groups
Xindividually. The value is a vector of function results, labeled by the
Xlevels attribute of the category.
X
XThe combination of a vector and a labeling category is an example of what
Xis called a {\sl ragged array}, since the subclass sizes are possibly
Xirregular. When the subclass sizes are all the same the indexing may be
Xdone implicitly and much more efficiently, as we see in the next section.
X
X\section{Arrays and Matrices}
X
X\subsection{Arrays}
X
XAn array can be considered as a multiply subscripted collection of data
Xentries, for example numeric. \s. allows simple facilities for creating
Xand handling arrays, and in particular the special case of matrices.
X
XA dimension vector is a vector of positive integers. If its length is {\tt
Xk} then the array is {\tt k}--dimensional. The values in the dimension
Xvector give the upper limits for each of the {\tt k} subscripts. The lower
Xlimits are always 1.
X
XA vector can be used by \s. as an array only if it has a dimension vector
Xas its {\sl dim\/} attribute. Suppose, for example, {\tt z} is a vector of
X$1500$ elements. The assignment
X
X\Sprompt attr(z,"dim") <- c(3,5,100)
X
Xgives it the {\sl dim\/} attribute that allows it to be treated as a
X$3\times5\times100$ array.
X
XOther functions such as {\tt matrix(\dots)} and {\tt array(\dots)}
Xare available for simpler and more natural looking assignments in special
Xcases.
X
X\Sprompt z <- array(z, dim=c(3,5,100))
X
XThe values in the data vector give the values in the array in the same
Xorder as they would occur in Fortran, that is, with the first subscript
Xmoving fastest and the last subscript slowest.
X
XFor example if the dimension vector for an array, say {\tt a} is {\tt
Xc(3,4,2)} then there are $3\times4\times2=24$ entries in {\tt a} and the
Xdata vector holds them in the order {\tt a[1,1,1], a[2,1,1], \dots,
Xa[2,4,2], a[3,4,2]}.
X
XIndividual elements of an array may be referenced, as above, by giving the
Xname of the array followed by the subscripts in square brackets, separated
Xby commas.
X
XMore generally, subsections of an array may be specified by giving a
Xsequence of {\sl index vectors\/} in place of subscripts; however {\sl if
Xany index position is given an empty index vector, then the full range of
Xthat subscript is taken\/}.
X
XContinuing the above example, {\tt a[2,,]} is a $4\times2$ array with
Xdimension vector {\tt c(4,2)} and data vector
X
X\begin{centering}
X
X{{\tt a[2,1,1]}, {\tt a[2,2,1]}, {\tt a[2,3,1]}, {\tt a[2,4,1]},
X {\tt a[2,1,2]}, {\tt a[2,2,2]}, {\tt a[2,3,2]}, {\tt a[2,4,2]},}
X
X\end{centering}
X
Xin that order. {\tt a[,,]} stands for the entire array, which
Xis the same as omitting the subscripts entirely and using {\tt a} alone.
X
XFor any array, say {\tt Z}, the dimension vector may be referenced
Xexplicitly as {\tt dim(Z)} (on either side of an assignment).
X
XAlso, if an array name is given with just {\sl one subscript or index
Xvector\/}, then the corresponding values of the data vector only are used;
Xin this case the dimension vector is ignored.
X
XArrays can also be constructed from vectors by the {\tt array} function,
Xwhich has the form
X
X\Sprompt Z <- array({\sl data\_vector\/},{\sl dim\_vector\/})
X
XFor example, if the vector {\tt h} contains 24 numbers then
Xthe command
X
X\Sprompt Z <- array(h, c(3,4,2))
X
Xwould use {\tt h} to set up $3\times4\times2$ array in {\tt Z}.
XAt this point {\tt dim(Z)} stands for the dimension vector {\tt c(3,4,2)},
Xand {\tt Z[1:24]} stands for the data vector as it was in {\tt h}, and {\tt
XZ[]} with an empty subscript or {\tt Z} with no subscript stands for the
Xentire array as an array.
X
XArrays may be used in arithmetic expressions and the result is an array
Xformed by element-by-element operations on the data vector. The dimension
Xvectors of operands generally need to be the same, and this becomes the
Xdimension vector of the result. So if {\tt A}, {\tt B} and {\tt C} are all
Xsimilar arrays, then
X
X\Sprompt D <- 2*A*B + C + 1
X
Xmakes {\tt D} a similar array with data vector the result of the
Xevident element-by-element operations.
X
X\subsection{The Outer Product of Two Arrays}
X
XAn important operation on arrays is the {\sl outer product}. If {\tt a}
Xand {\tt b} are two numeric arrays, their outer product is an array whose
Xdimension vector is got by concatenating their two dimension vectors,
X(order is important), and whose data vector is got by forming all possible
Xproducts of elements of the data vector of {\tt a} with those of {\tt b}.
XThe outer product is formed by the special operator {\tt\%o\%}:
X
X\Sprompt ab <- a \%o\% b
X
XIn particular the outer product of two ordinary vectors is a doubly
Xsubscripted array (i.e. a matrix, of rank at most 1). Notice that the
Xouter product operator is of course non-commutative.
X
X\subsection{Generalized Transpose of an Array}
X
XThe function {\tt aperm(a,perm)} may be used to permute an array, {\tt a}.
XThe argument {\tt perm} must be a permutation of the integers $\{${\tt 1,
X2, \dots, k}$\}$, where {\tt k} is the number of subscripts in {\tt a}.
XThe result of the function is an array of the same size as {\tt a} but with
Xold dimension given by {\tt perm[j]} becoming the new {\tt j}th dimension.
XThe easiest way to think of this operation is as a generalization of
Xtransposition for matrices. Indeed if {\tt A} is a matrix, (i.e. a doubly
Xsubscripted array) then {\tt B} given by
X
X\Sprompt B <- aperm(A, c(2,1))
X
Xis just the transpose of {\tt A}. For this special case a
Xsimpler function {\tt t(\dots)} is available, so we could have used {\tt B
X<- t(A)}.
X
X\subsection{Matrix Facilities. Multiplication, Inversion and Solving
XLinear Equations.}
X
XAs noted above, a matrix is just an array with two subscripts. However it
Xis such an important special case it needs a separate discussion. \s.
Xcontains many operators and functions that are available only for matrices.
XFor example {\tt t(X)} is the matrix transpose function, as noted above.
XThe functions {\tt nrow(A)} and {\tt ncol(A)} give the number of rows and
Xcolumns in the matrix {\tt A} respectively.
X
XThe operator {\tt \%*\%} is used for matrix multiplication. An $n\times1$
Xor $1\times n$ matrix may of course be used as an $n-$vector if in the
Xcontext such is appropriate. Conversely vectors which occur in matrix
Xmultiplication expressions are automatically promoted either to row or
Xcolumn vectors, whichever is multiplicatively coherent.
X
XIf, for example, {\tt A} and {\tt B} are square matrices of the same size,
Xthen
X
X\Sprompt A * B
X
Xis the matrix of element-by-element products and
X
X\Sprompt A \%*\% B
X
Xis the matrix product. If {\tt x} is a vector, then
X
X\Sprompt x \%*\% A \%*\% x
X
Xis a quadratic form.\footnote{Note that {\tt x \%*\% x} is ambiguous, as it
Xcould mean either ${\bf x'x}$ or ${\bf xx'}$, where ${\bf x}$ is the column
Xform. In such cases the smaller matrix seems implicitly to be the
Xinterpretation adopted, so the scalar ${\bf x'x}$ is in this case the
Xresult. The matrix ${\bf xx'}$ may be calculated either by {\tt cbind(x)
X\%*\% x} or {\tt x \%*\% rbind(x)} since the result of {\tt rbind(\ldots)}
Xor {\tt cbind(\ldots)} is always a matrix.}
X
XThe function {\tt crossprod(\dots)} forms ``crossproducts'', meaning that
X
X\Sprompt crossprod(X,y) {\rm is the same as} t(X) \%*\% y
X
Xbut the operation is more efficient. If the second argument to {\tt
Xcrossprod(\dots)} is omitted it is taken to be the same as the first.
X
XOther important matrix functions include {\tt solve(A,b)} for solving
Xequations, {\tt solve(A)} for the matrix inverse, {\tt svd(\dots)} for the
Xsingular value decomposition, {\tt qr(\dots)} for QR~decomposition and {\tt
Xeigen(\dots)} for eigenvalues and eigenvectors of symmetric matrices.
X
XThe meaning of {\tt diag(\dots)} depends on its argument. {\tt
Xdiag(vector)} gives a diagonal matrix with elements of the vector as the
Xdiagonal entries. On the other hand {\tt diag(matrix)} gives the vector of
Xmain diagonal entries of {\tt matrix}. This is the same convention as that
Xused for {\tt diag(\dots)} in {\tt MATLAB}. Also, somewhat confusingly, if
X{\tt k} is a single numeric value then {\tt diag(k)} is the $k\times k$
Xidentity matrix!
X
XA surprising omission from the suite of matrix facilities is a function for
Xthe determinant of a square matrix, however the absolute value of the
Xdeterminant is easy to calculate for example as the product of the singular
Xvalues. (See later.)
X
X\subsection{Forming Partitioned Matrices. {\tt cbind(\ldots)} and {\tt
Xrbind(\ldots)}.}
X
XMatrices can be built up from given vectors and matrices by the functions
X{\tt cbind(\ldots)} and {\tt rbind(\ldots)}. Roughly {\tt cbind(\ldots)}
Xforms matrices by binding together matrices horizontally, or column-wise,
Xand {\tt rbind(\ldots)} vertically, or row-wise.
X
XIn the assignment
X
X\Sprompt X <- cbind(arg$_1$, arg$_2$, arg$_3$, \dots)
X
Xthe arguments to {\tt cbind(\ldots)} must be either vectors of any length,
Xor matrices with the same column size, that is the same number of rows.
XThe result is a matrix with the concatenated arguments {\tt arg$_1$}, {\tt
Xarg$_2$}, \dots forming the columns.
X
XIf some of the arguments to {\tt cbind(\ldots)} are vectors they may be
Xshorter than the column size of any matrices present, in which case they
Xare cyclically extended to match the matrix column size (or the length of
Xthe longest vector if no matrices are given).
X
XThe function {\tt rbind(\ldots)} does the corresponding operation for rows.
XIn this case any vector argument, possibly cyclically extended, are of
Xcourse taken as row vectors.
X
XSuppose {\tt X1} and {\tt X2} have the same number of rows. To combine
Xthese by columns into a matrix {\tt X}, together with an initial column of
X{\tt1}s we can use
X
X\Sprompt X <- cbind(1,X1,X2)
X
XThe result of {\tt rbind(\ldots)} or {\tt cbind(\ldots)} always has matrix
Xstatus. Hence {\tt cbind(x)} and {\tt rbind(x)} are possibly the simplest
Xways explicitly to allow the vector {\tt x} to be treated as a column or row
Xmatrix respectively.
X
X\section{Lists and their Uses}
X
X\subsection{Objects of Mode List}
X
XAn \s. {\sl list} is an object consisting of an ordered collection of
Xobjects known as its {\sl components}.
X
XThere is no particular need for the components to be of the same mode or
Xtype, and, for example, a list could consist of a numeric vector, a logical
Xvalue, a matrix, a complex vector, a character array, a function, and so
Xon.
X
XComponents are always {\sl numbered\/} and may always be referred to as
Xsuch. Thus if {\tt St} is the name of a list with four components, these
Xmay be individually referred to as {\tt St[[1]]}, {\tt St[[2]]}, {\tt
XSt[[3]]} and {\tt St[[4]]}. If, further, {\tt St[[3]]} is a triply
Xsubscripted array then {\tt St[[3]][1,1,1]} is its first entry and {\tt
Xdim(St[[3]])} is its dimension vector, and so on.
X
XIf {\tt St} is a list, then the function {\tt length(St)} gives the number
Xof (top level) components it has.
X
XComponents of lists may also be {\sl named}, and in this case the component
Xmay be referred to either by giving the component name as a character
Xstring in place of the number in double square brackets, or, more
Xconveniently, by giving an expression of the form
X
X\Sprompt {\sl name\/}\${\sl component\_name}
X
Xfor the same thing.
X
XThis is a very useful convention as it makes it easier to get the right
Xcomponent if you forget the number. So if the components of {\tt St} above
Xhad been named, and the names were {\tt x}, {\tt y}, {\tt coefficients} and
X{\tt covariance} they could be referred to as {\tt St\$y}, {\tt
XSt\$covariance} and so on, (or indeed as {\tt St[["y"]]}, {\tt
XSt[["covariance"]]} \dots{} but this form is rarely if ever needed).
X
XIt is very important to distinguish {\tt St[[1]]} from {\tt St[1]}.
X``{\tt[[\ldots]]}'' is the operator used to select a single element,
Xwhereas ``{\tt[\ldots]}'' is a general subscripting operator. Thus the
Xformer is the {\sl first object in the list} {\tt St}, and if it is a named
Xlist the name is {\sl not\/} included. The latter is a {\sl sublist of the
Xlist {\tt St} consisting of the first entry only. If it is a named list,
Xthe name is transferred to the sublist.}
X
XThe names of components may be abbreviated down to the minimum number of
Xletters needed to identify them uniquely. Thus {\tt St\$coefficients} may
Xbe minimally specified as {\tt St\$coe} and {\tt St\$covariance} as {\tt
XSt\$cov}.
X
XThe vector of names is in fact simply an attribute of the list like any
Xother and may be handled as such. Other structures besides lists may, of
Xcourse, similarly be given a {\sl names\/} attribute also.
X
X\subsection{Constructing and Modifying Lists}
X
XNew lists may be formed from existing objects by the function {\tt
Xlist(\dots)}. An assignment of the form
X
X\Sprompt St <- list({\sl name\/}$_1$={\sl comp\/}$_1$, {\sl name\/}$_2$={\sl comp\/$_2$}, \dots,{\sl name\/}$_m$={\sl comp\/}$_m$)
X
Xsets up a list {\tt St} of $m$ components using {\tt {\sl
Xcomp\/}$_1$}, \dots, {\tt {\sl comp\/}$_m$} for the components and giving
Xthem names as specified by the argument names, (which can be freely
Xchosen). If these names are omitted, the components are numbered only.
XThe components used to form the list are {\sl copied} when forming the new
Xlist and the originals are not affected.
X
XLists, like any subscripted object, can be extended by specifying
Xadditional components. For example
X
X\Sprompt St[5] <- list(matrix=Mat)
X
X\subsection{Some Functions Returning a List Result}
X
X\subsubsection{Eigenvalues and Eigenvectors}
X
XFunctions and expressions in \s. must return a single result, and in many
Xcases this will be a list with named components. For example, the function
X{\tt eigen(Sm)} calculates the eigenvalues and eigenvectors of a symmetric
Xmatrix {\tt Sm}. The result of this function is a list of two components
Xnamed {\tt values} and {\tt vectors}. The assignment
X
X\Sprompt ev <- eigen(Sm)
X
Xwill assign this list to {\tt ev}. Then {\tt ev\$val} is the
Xvector of eigenvalues of {\tt Sm} and {\tt ev\$vec} is the matrix of
Xcorresponding eigenvectors. Had we only needed the eigenvalues we could
Xhave used the assignment:
X
X\Sprompt evals <- eigen(Sm)\$values
X
X\noindent{\tt evals} now holds the vector of eigenvalues and the second
Xcomponent is discarded. If the expression
X
X\Sprompt eigen(Sm)
X
Xis used by itself as a command the two components are printed, with
Xtheir names, at the terminal.
X
X\subsubsection{Singular Value Decomposition}
X
XThe function {\tt svd(M)} takes an arbitrary matrix argument, {\tt M}, and
Xcalculates the singular value decomposition of {\tt M}. This consists of a
Xmatrix of orthonormal columns {\tt U} with the same column space as {\tt
XM}, a second matrix of orthonormal columns {\tt V} whose column space is
Xthe row space of {\tt M} and a diagonal matrix of positive entries {\tt D}
Xsuch that {\tt M = U \%*\% D \%*\% t(V)}. {\tt D} is actually returned as
Xa vector of the diagonal elements. The result of {\tt svd(M)} is actually
Xa list of three components named {\tt d}, {\tt u} and {\tt v}, with evident
Xmeanings. If {\tt M} is in fact square, then, it is not hard to see that
X
X\Sprompt absdetM <- prod(svd(M)\$d)
X
Xcalculates the absolute value of the determinant of {\tt M}. If this
Xcalculation were needed often with a variety of matrices it could be
Xdefined as an \s. function
X
X\Sprompt absdet <- function(M) prod(svd(M)\$d)
X
Xafter which we could use {\tt absdet(\ldots)} as just another \s. function.
XAs a further trivial but potentially useful example, you might like to
Xconsider writing a function, say {\tt tr(\ldots)}, to calculate the trace
Xof a square matrix. [Hint: You will not need to use an explicit loop.
XLook again at the {\tt diag(\ldots)} function.]
X
XFunctions will be discussed formally later in these notes.
X
X\subsubsection{Least Squares Fitting and the $QR$ Decomposition}
X
XThe function {\tt lsfit(\dots)} returns a list giving results of a least
Xsquares fitting procedure. An assignment such as
X
X\Sprompt ans <- lsfit(X,y)
X
Xgives the results of a least squares fit where {\tt y} is the
Xvector of observations and {\tt X} is the design matrix. See the help
Xfacility for more details, and also for the follow-up function {\tt
Xls.summary(\dots)}. Note that a grand mean term is automatically included
Xand need not be included explicitly as a column of {\tt X}.
X
XAnother closely related function is {\tt qr(\dots)} and its allies.
XConsider the following assignments
X
X\Sprompt Xplus <- qr(X)
X
X\Sprompt b <- qr.coef(Xplus, y)
X
X\Sprompt fit <- qr.fitted(Xplus, y)
X
X\Sprompt res <- qr.resid(Xplus, y)
X
XThese compute the orthogonal projection of {\tt y} onto the range of
X{\tt X} in {\tt fit}, the projection onto the orthogonal complement in {\tt
Xres} and the coefficient vector for the projection in {\tt b}, that is,
X{\tt b} is essentially the result of the {\tt MATLAB} `backslash' operator.
X
XIt is not assumed that {\tt X} has full column rank. Redundancies will be
Xdiscovered and removed as they are found.
X
X
X
X\section{Reading from Data Files. The {\tt scan(\ldots)} Function.}
X
XAtomic data objects will usually be read as values from external files.
XThis is done most conveniently with the {\tt scan(\dots)} function, used as
Xfollows.
X
XSuppose the data vectors are of equal length and are to be read in in
Xparallel. Further suppose that there are three vectors, the first of mode
Xcharacter and the remaining two of mode numeric, and the file is {\tt
Xinput.dat}. The first step is to use {\tt scan(\dots)} to read in the
Xthree vectors as a list, as follows
X
X\Sprompt in <- scan("input.dat",list("",0,0))
X
XThe second argument is a dummy list structure that establishes
Xthe mode of the three vectors to be read. The result, held in {\tt in}, is
Xa list whose components are the three vectors read in. To separate the
Xdata items into three separate vectors, use assignments like
X
X\Sprompt label <- in[[1]]; x <- in[[2]]; y <- in[[3]]
X
XMore conveniently, the dummy list can have named components, in which case
Xthe names can be used to access the vectors read in. For example
X
X\Sprompt in <- scan("input.dat",list(id="", x=0, y=0))
X
X\Sprompt label <- in\$id; x <- in\$x; y <- in\$y
X
XIf the second argument is a single value and not a list, a single vector is
Xread in, all components of which must be of the same mode as the dummy
Xvalue.
X
X\Sprompt X <- matrix(scan("light.dat", 0), ncol=5, byrow=T)
X
XThere are more elaborate input facilities available and these are detailed
Xin the manual.
X
X\section{Graphical Procedures}
X
XThe graphical facilities are the core of \s.. Results are best when \s. is
Xused with a graphics terminal, although even a simple {\sf ASCII} terminal
Xcan be quite effective.
X
XOn a graphics terminal the steps involved are as follows:
X
X \begin{enumerate}
X \item The type of terminal, or {\sl device\/}, is declared to \s. at
X the beginning of the session. For example with a {\sf Visual
X 603} or {\sf Visual 500} terminal, which has Tektronics 4014
X graphics emulation, the command:
X
X\Sprompt tek4014()
X
Xis used to declare the device.
X
X \item A command is issued to construct a plot from data lists. For
Xexample
X
X\Sprompt plot(x,y)
X
Xspecifies a simple point plot where {\tt x} and {\tt y} are
Xvectors giving the $x-$ and $y-$co\-ord\-i\-nates of the points respectively.
X(The command includes a default automatic choice of axes, scales, titles
Xand plotting characters, all of which can be overridden with additional
X{\sl graphical parameters} that could be included as named arguments in the
Xcommand.)
X
X\item Further commands may be given with the terminal in graphics mode, but
Xit is rather more convenient to change back to 80 column character mode.
XSubsequent graphical commands may either add to an existing plot or re-draw a
Xnew plot, erasing the old one.
X
XYou should learn quickly the procedure for switching back from graphical
Xmode to character mode on your terminal. Note, however, that when you do so
Xyou will erase or shift the plot just displayed, so it is not possible to
Xmodify it further.
X \end{enumerate}
X
X\subsection{Graphical Parameters}
X
XFunctions producing graphical output usually have optional additional named
Xarguments that can be specified to override some default parameter settings
Xand hence modify the characteristics of a plot. A short list of the main
Xones is as follows:
X
X\bigskip
X\tabskip=0pt
X\halign to \hsize{\tt#\hfil\tabskip=100 pt plus 100pt minus 99 pt&\vtop
X{\hsize=5truein\parindent=0pt\baselineskip=14pt\relax
X\parskip=0pt #}\tabskip=0pt\cr
Xaxes=L&If {\tt FALSE} all axes are suppressed. Default {\tt TRUE}, axes are
Xautomatically constructed.\cr
X\noalign{\bigskip}
Xtype="c"&Type of plot desired. Values for {\tt c} are:
X
X{\tt p} for points only, (the default for function {\tt plot}),
X
X{\tt l} for lines only,
X
X{\tt b} for both points and lines, (the lines miss the points),
X
X{\tt o} for overlaid points and lines,
X
X{\tt h} for high density vertical line plotting, and
X
X{\tt n} for no plotting, (but axes are still found and set).\cr
X\noalign{\bigskip}
X\vtop{\baselineskip=14pt
X\hbox{\tt xlab="string"} \hbox{\tt ylab="string"} \hbox{\tt sub="string"}
X\hbox{\tt main="string"}}&Give labels for the
X{\tt x}-- and/or {\tt y}--axes (default: the names, including prefix, of the
X{\tt x} and {\tt y} co\-ord\-in\-ate vectors).
X
X{\tt sub} specifies a title to appear under the {\tt x}--axis label and {\tt
Xmain} a title for the top of the plot in larger letters. (default: both
Xempty).\cr
X\noalign{\bigskip}
X\vtop{\baselineskip=14pt
X\hbox{\tt xlim=c(lo,hi)} \hbox{\tt ylim=c(lo,hi)}}&Approximate minimum and
Xmaximum values for {\tt x}-- and/or {\tt y}--axes settings. These values are
Xautomatically rounded to make them ``pretty'' for axis labeling.\cr
X\noalign{\bigskip}}
X
XOther graphical parameters control the background characteristics of all
Xsubsequent plots and are usually specified by a call to the function {\tt
Xpar(\ldots)}. There are a great number of these parameters and the command
X
X\Sprompt help(par)
X
Xgives a complete list of them and their meanings. Some of the more
Xcommonly adjusted ones are as follows:
X
X\tabskip=0pt
X\halign to \hsize{\tt#\hfil\tabskip=100 pt plus 100pt minus 99 pt&\vtop
X{\hsize=5truein\parindent=0pt\baselineskip=14pt\relax
X\parskip=0pt #}\tabskip=0pt\cr
Xlty=n&Line type is {\tt n}. If lines are being plotted, a variety of line
Xtypes is available; {\tt n = 1} means a solid line, {\tt n = 2, 3, \dots}
Xindicates a variety of broken line forms.\cr
X\noalign{\bigskip}
Xpch="c"&Specify the character to be used for plotting points (default: {\tt *}
Xfor graphics terminals, $\bullet$ for {\sf PostScript}).\cr
X\noalign{\bigskip}
X\vtop{\baselineskip=14pt
X\hbox{\tt mfrow=c(m,n)} \hbox{\tt mfcol=c(m,n)}}&multiple frames on the one
Xplot. Instead of plotting just one graph per screen, each screen (or page)
Xwill contain an array of {\tt m*n} graphs forming an $m \times n$ grid. If
X{\tt mfrow} is used the screen is filled row-by-row and if {\tt mfcol} is
Xused it is filled column-by-column. Useful if many graphs are to be
Xinspected simultaneously and high resolution is not necessary.\cr
X\noalign{\bigskip}
Xpty="c"&Specify the type of plotting region currently in effect. Possible
Xvalues
Xfor {\tt c} are
X
X{\tt s} to generate a square plotting region;
X
X{\tt m} (the default) to generate a maximal size plotting region.
X\cr}
X
X\subsection{Some Basic Plotting Functions}
X
XThe elementary plotting functions are as follows:
X\bigskip
X
X\tabskip=0pt
X\halign to \hsize{\tt#\hfil\tabskip=100 pt plus 100pt minus 99 pt&\vtop
X{\hsize=5truein\parindent=0pt\baselineskip=14pt\relax
X\parskip=0pt #}\tabskip=0pt\cr
Xplot(x,y,\dots)&Scatter plot of points with {\tt x}-- and {\tt
Xy}--coordinates given by the two main parameters.
X
XThe pair {\tt x,y} may be replaced by a single list with components labeled
X{\tt x} and {\tt y}, called a `plot list'.
X
XGraphical parameters are particularly useful.\cr
X\noalign{\bigskip}
Xpoints(x,y,\dots)&Add points to an existing plot (possibly using a different
Xplotting character. Follows on from a {\tt plot(\dots)} command.\cr
X\noalign{\bigskip}
Xlines(x,y,\dots)&Add lines to an existing plot. Similar to points.
X
XNote
X
X{\tt\quad > plot(x,y); lines(spline(x,y))}
X
Xwill join the points of a plot by a cubic spline interpolation function.
X(See {\tt help(spline)} for further information.)\cr
X\noalign{\bigskip}
X\vtop{\baselineskip=14pt
X\hbox{\tt text(x,y,}
X\hbox{\tt\enspace labels,\dots)}}&Add text to a plot at points given by
X{\tt x,y}. Normally {\tt labels} is an integer or character vector in which
Xcase {\tt labels[i]} is plotted at point {\tt (x[i],y[i])}. The default is
X{\tt 1:length(x)}.
X
XNote: This function is often used in the sequence
X
X{\tt\quad > plot(x,y,type="n"); text(x,y)}
X
XThe graphics parameter {\tt type="n"} suppresses the plotting of points but
Xset up the axes, and the {\tt text(\ldots)} function supplies special
Xcharacters (in this case just the integers by default) for the points.\cr
X\noalign{\bigskip}
X\vtop{\baselineskip=14pt
X\hbox{\tt abline(a,b,\dots)} \hbox{\tt abline(h=c,\dots)} \hbox{\tt
Xabline(v=c,\dots)}}&Draw a line in intercept and slope, ({\tt a},{\tt b}),
Xform across an existing plot. {\tt h=c} may be used to specify {\tt
Xy}--coordinates for the heights of horizontal lines to go across a plot, and
X{\tt v=c} similarly for the {\tt x}--coordinates for vertical lines.\cr
X\noalign{\bigskip}
X\vtop{\baselineskip=14pt
X\hbox{\tt contour(x,y,z,}
X\hbox{\tt\enspace\dots)}}&Draw a contour map, or place additional contours
Xon an existing contour map. {\tt x} and {\tt y} are vectors specifying
Xcoordinates of a grid at which the surface height is evaluated, and {\tt z}
Xis a matrix of size {\tt length(x) $\times$ length(y)} such that {\tt
Xz[i,j]} is the height of the surface at {\tt (x[i],y[j])}.
X
XAdditional parameters may be given to specify the height of contour
Xintervals, the number of contour intervals desired, whether or not to start
Xa new contour map or add to an existing one, and graphical parameters.\cr
X\noalign{\bigskip}
Xpersp(z,\dots)&Draw a quasi-three-dimensional plot of the function whose
Xheights on a regular square grid are given by the values in the square
Xmatrix {\tt z}.
X
XThe grid is considered by the function to be {\tt (-1,1) $\times$ (-1,1)}
Xand the function itself should be scaled so that it is roughly in the range
X{\tt (0,1)}.\cr
X\noalign{\bigskip}
Xpolygon(x,y,\dots)&Draw a polygon defined by the ordered vertices in ({\tt
Xx},{\tt y}), and (optionally) shade it in with hatch lines, or fill it if
Xthe graphics device allows the filling of figures.\cr}
X
X\subsection{Graphical Devices. Hardcopy Output on {\sf PostScript} Printers}
X
X\s. is useful for calculations using any terminal and for graphical
Xdisplays on a terminal with graphics capabilities. A variety of different
Xterminal types are catered for, and {\tt help(Devices)} gives more
Xinformation.
X
XRough displays are possible on any terminal and {\tt printer()} is the
Xdevice to use for a non-graphics terminal.
X
XThe command
X
X\Sprompt postscript()
X
Xwill cause subsequent graphical output automatically to be sent to a
Xprinter spooler command rather than appear on the screen. However you may
Xneed to vary the system default printing command in order to direct
Xprinting towards some specific laser printer. For example
X
X\Sprompt postscript(command="psprint -noflag",horizontal=T)
X
Xcould be appropriate on some systems. The second given parameter specifies
Xlandscape rather than portrait mode, as is usually appropriate for {\sf A4}
Xpaper.
X
XIf the device is changed to
X
X\Sprompt postscript("file.ps",horizontal=T)
X
Xgraphical output again does not appear on the screen, but is placed in a
X{\sf PostScript} file, here {\tt file.ps}, which can later be sent to the
Xlaser printer. This would only be needed if some post processing of the
Xfile were necessary which could not be achieved by a pipe in the command
Xstring.
X
XThe {\tt graphics.off()} command is used if it is necessary to flush the
Xgraphics buffer explicitly and terminate the file correctly, for example at
Xthe end of a session, but this is not needed if the device is changed back,
Xfor example to the screen.
X
XIt is important to note that if the file named in the {\tt
Xpostscript("file.ps")} command already exists, it will be overwritten.
XThis is the case even if the file was only created earlier in the same \s.
Xsession.
X
X\section{More Language Features. Loops and Conditional Execution}
X
X\subsection{Grouped Expressions}
X
X\s. is an expression language in the sense that its only command type is a
Xfunction or expression which returns a result. Even an assignment is an
Xexpression whose result is the value assigned, and it may be used wherever
Xany expression may be used; in particular multiple assignments are
Xpossible.
X
XCommands may be grouped together in braces, {\tt\char'173{}expr$_1$;
Xexpr$_2$;\dots; expr$_m$\char'175}, in which case the value of the group is
Xthe result of the last expression in the group evaluated. Since such a
Xgroup is also an expression it may, for example, be itself included in
Xparentheses and used a part of an even larger expression, and so on.
X
X\subsection{Control Statements}
X
XThe language has available a conditional construction of the form
X
X\Sprompt if ({\sl expr$_1$\/}) {\sl expr$_2$\/} else {\sl expr$_3$\/}
X
Xwhere {\sl expr$_1$\/} must evaluate to a logical value and the
Xresult of the entire expression is then evident.
X
XThere is also a {\tt for}--loop construction which has the form
X
X\Sprompt for ({\tt {\sl name\/}} in {\sl expr$_1$\/}) {\sl expr$_2$\/}
X
Xwhere {\tt {\sl name\/}} is a dummy. {\tt expr$_1$} is a vector
Xexpression, (often a sequence like {\tt 1:20}), and {\tt expr$_2$} is often
Xa grouped expression with its sub-expressions written in terms of the dummy
X{\sl name\/}. {\tt expr$_2$} is repeatedly evaluated as {\sl name} ranges
Xthrough the values in the vector result of {\tt expr$_1$}.
X
XAs an example, suppose {\tt ind} is a vector of class indicators and we
Xwish to produce separate plots of {\tt y} versus {\tt x} within classes.
XUse the {\tt help} facility to the following:
X
X\Sprompt yc <- split(y,ind); xc <- split(x,ind)
X
X\Sprompt for (i in 1:length(yc)){\char'173}plot(xc[[i]],yc[[i]]);
X
X\Contd abline(lsfit(xc[[i]],yc[[i]]))\char'175
X
X(Note the function {\tt split(\dots)} which produces a list of
Xvectors got by splitting a larger vector according to the classes specified
Xby a category. This is a useful function.)
X
XOther looping facilities include the
X
X\Sprompt repeat {\sl expr\/}
X
Xstatement and the
X
X\Sprompt while ({\sl condition\/}) {\sl expr\/}
X
Xstatement. The {\tt break} statement can be used to terminate any
Xloop abnormally, and {\tt next} can be used to discontinue one particular
Xcycle.
X
X\section{Writing Your Own Functions}
X
XAs we have seen informally along the way, the \s. language allows the user
Xto create objects of mode {\sl function\/}. These are true \s. functions
Xthat are stored in a special internal form and may be used in further
Xexpressions and so on. In the process the language gains enormously in
Xpower, convenience and elegance, and learning to write useful functions is
Xone of the main ways to make your use of \s. comfortable and productive.
X
XIt should be emphasized that most of the functions supplied as part of the
X\s. system, such as {\tt mean(\ldots)}, {\tt var(\ldots)}, {\tt
Xpostscript(\ldots)} and so on, are themselves written in \s. and thus do
Xnot differ materially from user written functions.
X
XA function is defined by an assignment of the form
X
X\Sprompt name <- function({\sl arg$_1$\/}, {\sl arg$_2$\/}, \dots) {\sl
Xexpression\/}
X
XThe {\tt {\sl expression\/}} is an \s. expression, (usually a
Xgrouped expression), that uses the arguments, {\sl arg$_i$}, to calculate a
Xvalue. The value of the expression is the value returned for the function.
X
XA call to the function then takes the form {\tt name({\sl expr\/}$_1$, {\sl
Xexpr\/}$_2$,\dots)} and may occur anywhere a function call is legitimate.
X
XFor example, consider a function to emulate directly the {\tt MATLAB}
Xbackslash command, which returns the coefficients of the orthogonal
Xprojection of the vector $y$ onto the column space of the matrix, $X$.
XThus given a vector $y^{n\times1}$ and a matrix $X^{n\times p}$ then
X$$X\backslash y =^{\rm def.} (X'X)^{-}X'y$$
Xwhere $(X'X)^{-}$ is a generalized inverse of $X'X$.
X
X\Sprompt bslash <- function(X,y) \{
X
X\Contd X <- qr(X)
X
X\Contd qr.coef(X,y) \}
X
XAfter this object is created it is permanent, like all objects,
Xand may be used in statements such as
X
X\Sprompt regcoeff <- bslash(Design, yvar)
X
Xand so on.
X
X\subsection{Assignments within Functions are Local. Frames.}
X
XNote that {\sl any ordinary assignments done within the function are local
Xand temporary and lost after exit from the function}. Thus the assignment
X{\tt X <- qr(X)} does not affect the value of the argument in the calling
Xprogram.
X
XTo understand completely the rules governing the scope of \s. assignments
Xthe reader needs to be familiar with the notion of an evaluation {\sl
Xframe}. This is a somewhat advanced, though hardly difficult, topic and is
Xnot covered further in these notes.
X
XIf global and permanent assignments are intended within a function, then
Xthe `superassignment' operator, `{\tt<<-}' can be used. See the {\tt help}
Xdocument for details, and also see the {\tt synchronize()} function.
X
X\subsection{Defining Binary Operators.}
X
XIt is interesting to note that had we given the {\tt bslash(\ldots)}
Xfunction considered above a different name, namely one of the
Xform
X$$
X\centerline{\tt \%{\sl anything\/}\%}
X$$
Xit could have been used {\sl as a binary operator} in expressions rather
Xthan in function form. Suppose, for example, we choose {\tt !} for the
Xinternal character. The function definition would then start as
X
X\Sprompt "\%!\%" <- function(X,y) \{ \dots\ \}
X
X(Note the use of quote marks.) The function could then be used as
X{\tt X \%!\% y}. (The backslash symbol itself is not a convenient choice
Xas it presents special problems in this context.)
X
X\subsection{Categories to Indicator Variables.}
X
XAs a second example of a useful function, consider a function to expand a
Xcategory into a matrix of binary variables, similar to the {\tt INDI}
Xcommand of {\tt MINITAB}:
X
X\Sprompt binary <- function(factor) \{
X
X\Contd factor <- as.category(factor)
X
X\Contd rows <- length(factor)
X
X\Contd cols <- length(levels(factor))
X
X\Contd y <- matrix(0, rows, cols,
X
X\Contd \quad\qquad dimnames = list(NULL, levels(factor)))
X
X\Contd y[cbind(1:rows,factor)] <- 1 \# See explanation below.
X
X\Contd y
X
X\Contd \}
X
XThe {\tt as.category(\dots)} coerces {\tt factor} to be a category if it
Xwas not already one. {\tt y} is initially a matrix of zeros, and the
Xassignment
X
X\Contd y[cbind(1:rows,factor)] <- 1
X
Xplaces the ones in the correct positions. It uses a feature of
Xsubscripting slightly beyond the simple model presented in these
Xintroductory notes. It could implemented much less efficiently, but perhaps
Xmore transparently, by either of the two loops
X
X\Contd for (i in 1:length(factor)) y[i, factor(i)] <- 1
X
Xor
X
X\Contd for (i in 1:cols) y[factor==i,i] <- 1
X
XThis rather neat alternative was suggested to the author by Rick Becker.
X
XIn fact explicit loops in \s. are somewhat costly. Many can and should be
Xavoided either by careful use of the subscripting facility, as here, or by
Xuse of the {\tt apply(\ldots)} function and its allies.
X
XThe last statement in the function is just the expression, {\tt y}, to give
Xthe function the correct (matrix) value. All temporary variables ({\tt
Xrows, cols, i, y}) are discarded once the calculation is complete, although
Xthe value of {\tt y} is, of course, passed on as the value of {\tt
Xbinary(fac)} after such a call.
X
X\subsection{Customizing the Environment. {\tt .First} and {\tt .Last}}
X
XAny function named {\tt .First()} in the {\tt .Data} directory has a
Xspecial status. It is automatically performed at the beginning of an \s.
Xsession and may be used to initialize the environment. For example, the
Xdefinition
X
X\Sprompt .First <- function() \{
X
X\Contd options(prompt="\$ ", continue="+\char'134t", digits=5, length=999)
X
X\Contd tek4014() \# only if you will be using a Tektronics graphics screen.
X
X\Contd par(pch = "+", las = 1)
X
X\Contd attach(paste(unix("echo \$HOME"), "/.Data", sep = ""))
X
X\Contd library(examples)
X
X\Contd \}
X
Xalters the prompt to {\tt\$} and sets up various other useful
Xthings that can then be taken for granted in the rest of the session.
XSimilarly a function {\tt .Last()}, if defined, is executed at the very end
Xof the session. An example is as follows
X
X\Sprompt .Last <- function() \{
X
X\Contd graphics.off()\hskip 1 cm \# To terminate any `postscript(\dots)' files
X
X\Contd cat(paste(unix("date"),
X"\char'134nAdios\char'134n"))\hskip 1cm \# Is it time for lunch?
X
X\Contd \}
X
X\vspace{1cm}
X
X\leftline{\large\bf APPENDIX: A List of \s. Functions}
X\addcontentsline{toc}{section}{APPENDIX: A List of \s. Functions}
X\lhead[\fancyplain{}{\small\sf\thepage}]{\fancyplain{}{\small\sf A List of
X\s. Functions}}
X\rhead[\fancyplain{}{\small\sf A List of \s.
XFunctions}]{\fancyplain{}{\small\sf\thepage}}
X\bigskip
X\vskip 10pt
X\tabskip = 2in plus 0pt minus 1 fil
X\halign to \hsize{&\tt#\hfill\cr
X! & character & interp & persp & seq \cr
X!= & Chisquare & INTPR & pexp & set.seed \cr
X$\backslash$ & chol & invisible & pf & show \cr
X* & chull & is.array & pgamma & signif \cr
X\%*\% & clorder & is.atomic & pie & sin \cr
X+ & cmdscale & is.call & plclust & single \cr
X- & col & is.category & plnorm & sinh \cr
X-> & Comparison & is.character & plogis & sink \cr
X/ & Complex & is.complex & plot & smooth \cr
X\%/\% & complex & is.double & plotfit & solve \cr
X: & Conj & is.expression & pmax & sort \cr
X< & contour & is.function & pmin & sort.list \cr
X<- & cor & is.integer & pnorm & source \cr
X<<- & cos & is.language & points & spline \cr
X<= & cosh & is.list & polygon & split \cr
X== & count.trace & is.logical & postscript & sqrt \cr
X> & crossprod & is.matrix & ppoints & Stable \cr
X>= & cumsum & is.na & prarray & stamp \cr
X\$ & cut & is.name & pratom & stars \cr
X\%o\% & cutree & is.null & prcomp & starsymb \cr
X\& & cycle & is.numeric & prefix & start \cr
X\&\& & date & is.qr & pretty & std.trace \cr
X\char'136 & DBCONVERT & is.recursive & print & stem \cr
X\_ & dbeta & is.single & printer & stop \cr
X| & DBLEPR & is.ts & prlist & storage \cr
X|| & dcauchy & is.vector & prmatrix & storage.mode \cr
Xabline & dchisq & l1fit & proc.time & structure \cr
Xabs & debugger & labclust & prod & Subscript \cr
Xacos & density & lag & prompt & substitute \cr
Xacosh & deparse & lapply & prstructure & subtree \cr
Xagain & detach & leaps & prts & sum \cr
Xaggregate & Device.Default & legend & pt & sun \cr
Xall & device.xy & length & punif & svd \cr
Xallocated & Devices & levels & q & sweep \cr
Xamatch & dexp & lgamma & qbeta & switch \cr
Xany & df & library & qcauchy & symbols \cr
Xaperm & dgamma & library.dynam & qchisq & synchronize \cr
Xappend & dget & lines & qexp & Syntax \cr
Xapply & diag & list & qf & sys.call \cr
Xapprox & diff & LOAD & qgamma & sys.calls \cr
XArg & dim & locator & qlnorm & sys.frame \cr
Xargs & dimnames & log & qlogis & sys.frames \cr
XArithmetic & discr & log10 & qnorm & sys.nframe \cr
Xarray & dist & Logic & qqnorm & sys.on.exit \cr
Xarrows & dlnorm & logical & qqplot & sys.parent \cr
Xas.array & dlogis & Logistic & qr & sys.parents \cr
Xas.call & dnorm & loglin & qr.coef & sys.status \cr
Xas.category & do.call & Lognormal & qr.fitted & sys.trace \cr
Xas.character & dotchart & logo & qr.qty & S\_alloc \cr
Xas.complex & double & lowess & qr.qy & T \cr
Xas.double & dput & ls & qr.resid & t \cr
Xas.expression & drop & ls.keep & qt & table \cr
Xas.function & dt & ls.summary & quantile & tabulate \cr
Xas.integer & dump & lsfit & query & tan \cr
Xas.list & dump.calls & MAC.to.FUN & quickvu & tanh \cr
Xas.logical & dump.frames & macro & qunif & tapply \cr
Xas.matrix & dunif & match & range & tek4014 \cr
Xas.name & duplicated & matlines & rank & tek4105 \cr
Xas.null & dyn.load & matplot & rbeta & tempfile \cr
Xas.numeric & ed & matpoints & rbind & text \cr
Xas.qr & eigen & matrix & rbiwt & time \cr
Xas.single & else & Matrix-product & rcauchy & title \cr
Xas.ts & end & max & rchisq & trace \cr
Xas.vector & eval & mean & Re & trace.on \cr
Xasin & exists & median & readline & traceback \cr
Xasinh & exp & menu & REALPR & trunc \cr
Xassign & Exponential & min & reload & TRUNC\_AUDIT \cr
XAssignment & expression & missing & remove & ts \cr
Xatan & F & Mod & rep & tslines \cr
Xatanh & faces & mode & rep.int & tsmatrix \cr
Xattach & fft & monthplot & repeat & tsp \cr
Xattr & floor & mstree & replace & tsplot \cr
Xattributes & for & mtext & restart & tspoints \cr
XAUDIT & format & mulbar & restore & twoway \cr
Xaxes & frame & names & return & Uniform \cr
Xaxis & frequency & napsack & rev & unique \cr
Xbacksolve & Gamma & nargs & rexp & unix \cr
Xbarplot & gamma & nchar & rf & unix.time \cr
XBATCH & get & ncol & rgamma & unlink \cr
XBeta & gr.display & next & rlnorm & unlist \cr
Xbind & graphics & Normal & rlogis & untrace \cr
Xbox & graphics.off & nrow & rm & usa \cr
Xboxplot & grep & numeric & rnorm & var \cr
Xbreak & hat & odometer & round & vector \cr
Xbrowser & hclust & on.exit & row & vi \cr
Xbrowser.trace & help & options & rreg & vu \cr
Xbxp & hist & order & rstab & warning \cr
Xc & history & outer & rt & warnings \cr
Xcall & hp2623 & pairs & runif & while \cr
Xcall\_S & hpgl & par & sabl & window \cr
Xcancor & identify & pardump & sablplot & world.xy \cr
Xcat & if & parse & sample & write \cr
Xcategory & ifelse & paste & sapply & xor \cr
XCauchy & Im & pbeta & scale & \cr
Xcbind & integer & pcauchy & scan & \cr
Xceiling & interactive & pchisq & segments & \cr}
X
X
X\end{document}
SHAR_EOF
if test 78244 -ne "`wc -c < 'Snotes.tex'`"
then
echo shar: "error transmitting 'Snotes.tex'" '(should have been 78244 characters)'
fi
fi
echo shar: "extracting 'S.sty'" '(605 characters)'
if test -f 'S.sty'
then
echo shar: "will not over-write existing file 'S.sty'"
else
sed 's/^ X//' << \SHAR_EOF > 'S.sty'
X\def\s.{{\tt S}}
X\def\pow{\char'136{}}
X\def\s.{{\tt S}}
X%\def\Sprompt#1\par{\hskip 1 cm{\tt> #1}\par\noindent}
X\def\Sprompt#1\par{{\tt> #1}\par\noindent}
X%\def\Shell#1\par{\hskip 1 cm{\tt\$ #1}\par\noindent}
X\def\Shell#1\par{{\tt\$ #1}\par\noindent}
X%\def\Contd #1\par{\hskip 1 cm{\tt+\hskip 0.75 truecm #1}\par\noindent}
X\def\Contd #1\par{{\tt+\hskip 0.75 truecm #1}\par\noindent}
X\def\{{{\tt\char'173}}
X\def\}{{\tt\char'175}}
X\vfuzz 3pt
X
X\marginparwidth 0pt
X\oddsidemargin 0pt
X\evensidemargin 0pt
X\marginparsep 0pt
X
X\topmargin 0pt
X
X\textwidth 6.5in
X\textheight 9.3 in
X
X\endinput
X
X
SHAR_EOF
if test 605 -ne "`wc -c < 'S.sty'`"
then
echo shar: "error transmitting 'S.sty'" '(should have been 605 characters)'
fi
fi
echo shar: "extracting 'fancyheadings.sty'" '(9673 characters)'
if test -f 'fancyheadings.sty'
then
echo shar: "will not over-write existing file 'fancyheadings.sty'"
else
sed 's/^ X//' << \SHAR_EOF > 'fancyheadings.sty'
X% fancyheadings.sty version 1.0
X% Fancy headers and footers.
X% Piet van Oostrum, Dept of Computer Science, University of Utrecht
X% Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands
X% Telephone: +31-30-531806. piet@cs.ruu.nl (mcvax!hp4nl!ruuinf!piet)
X% March, 1989.
X
X% Here is a documentstylestyle option that allows you to customize your
X% page headers and footers in an easy way. It combines features that were
X% separately available in other pagestyles, without introducing much
X% complexity. You can define:
X% - three-part headers and footers
X% - rules in header and footer
X% - headers and footers wider than \textwidth
X% - multiline headers and footers
X% - separate headers and footers for even and odd pages
X% - separate headers and footers for chapter pages
X%
X% To use this pagestyle, you must include the ``fancyheadings'' style
X% option in your \documentstyle, and issue the \pagestyle{fancy} command.
X% The \pagestyle{fancy} command should be issued after any changes made to
X% \textwidth.
X%
X% The page layout will be as follows:
X%
X% LHEAD CHEAD RHEAD
X% ----------------------------------- (rule)
X%
X% page body
X%
X%
X% ----------------------------------- (rule)
X% LFOOT CFOOT RFOOT
X%
X% The L-fields will be leftadjusted, the C-fields centered and the
X% R-fields rightadjusted.
X% Each of the six fields and the two rules can be defined separately.
X%
X% Simple use:
X%
X% The header and footer fields can be defined by commands \lhead{LHEAD}
X% and so on for the other fields. If the field depends on something in the
X% document (e.g. section titles) you must in general use the \markboth and
X% \markright commands, otherwise a title may end on the wrong page. You
X% can do this e.g. by redefining the commands \chaptermark, \sectionmark
X% and so on (see example below). The defaults for these marks are as in
X% the standard pagestyles. The marks can be put into a header or footer
X% field by referencing \leftmark and \rightmark.
X%
X% Rules in header and footer
X%
X% The thickness of the rules below the header and above the footer can be
X% changed by redefining the length parameters \headrulewidth (default
X% 0.4pt) and \footrulewidth (default 0). These may be redefined by the
X% \setlength command. A thickness of 0pt makes the rule invisible.
X% If you want to make more complicated changes, you have to redefine the
X% commands \headrule and/or \footrule.
X%
X% Headers and footers wider than \textwidth
X%
X% The headers and footers are set in a box of width \headwidth. The
X% default for this is the value of \textwidth. You can make it wider (or
X% smaller) by redefining \headwidth with the \setlength or \addtolength
X% command. The headers and footers will stick out the page on the same
X% side as the marginal notes. For example to include the marginal notes,
X% add both \marginparsep and \marginparwidth to \headwidth (see also the
X% example below).
X%
X% Multiline headers and footers
X%
X% Each of the six fields is set in an appropriate parbox, so you can put a
X% multiline part in it with the \\ command. It is also possible to put
X% extra space in it with the \vspace command. Note that if you do this you
X% will probably have to increase the \headheight or \footskip lengths.
X%
X% Separate headers and footers for even and odd pages
X%
X% If you want the headers and footers to be different on even- and
X% odd-numbered pages in the ``twoside'' style, the field-defining macros
X% can be given an optional argument, to be used on the even-numbered
X% pages, like \lhead[EVEN-LHEAD]{ODD-RHEAD}.
X%
X% Separate headers and footers for chapter pages
X%
X% LaTeX gives a \thispagestyle{plain} command for the first page of the
X% document, the first page of each chapter and a couple of other pages. It
X% might be incompatible with your pagestyle. In this case you can use a
X% slightly different version of the pagestyle, called \pagestyle{fancyplain}.
X% This pagestyle redefines the pagestyle ``plain'' to also use pagestyle
X% ``fancy'' with the following modifications:
X% - the thicknesses of the rules is defined by \plainheadrulewidth and
X% \plainfootrulewidth (both default 0).
X% - the 6 fields may be defined separately for the plain pages by
X% giving them the value \fancyplain{PLAIN-VALUE}{NORMAL-VALUE}. This
X% construct may be used in both the optional argument and the normal
X% argument. Thus \lhead[\fancyplain{F1}{F2}]{\fancyplain{F3}{F4}}
X% specifies the LHEAD value in a two-sided document:
X% F1 on an even-numbered ``plain'' page
X% F2 on an even-numbered normal page
X% F3 on an odd-numbered ``plain'' page
X% F4 on an odd-numbered normal page.
X%
X% Defaults:
X%
X% \headrulewidth 0.4pt
X% \footrulewidth 0pt
X% \plainheadrulewidth 0pt
X% \plainfootrulewidth 0pt
X%
X% \lhead[\fancyplain{}{\sl\rightmark}]{\fancyplain{}{\sl\leftmark}}
X% % i.e. empty on ``plain'' pages \rightmark on even, \leftmark on odd pages
X% \chead{}
X% \rhead[\fancyplain{}{\sl\leftmark}]{\fancyplain{}{\sl\rightmark}}
X% % i.e. empty on ``plain'' pages \leftmark on even, \rightmark on odd pages
X% \lfoot{}
X% \cfoot{\rm\thepage} % page number
X% \rfoot{}
X%
X% Examples:
X%
X% To put two lines containing the section title and the subsection title
X% in the righthandside corner, use:
X%
X% \documentstyle[fancyheadings]{article}
X% \pagestyle{fancy}
X% \renewcommand{\sectionmark}[1]{\markboth{#1}{}}
X% \renewcommand{\subsectionmark}[1]{\markright{#1}}
X% \rfoot{\leftmark\\\rightmark}
X%
X% The following definitions give an approximation of the style used in the
X% LaTeX book:
X%
X% \documentstyle[fancyheadings]{book}
X% \pagestyle{fancyplain}
X% \addtolength{\headwidth}{\marginparsep}
X% \addtolength{\headwidth}{\marginparwidth}
X% \renewcommand{\chaptermark}[1]{\markboth{#1}{#1}} % remember chapter title
X% \renewcommand{\sectionmark}[1]{\markright{\thesection\ #1}}
X% % section number and title
X% \lhead[\fancyplain{}{\bf\thepage}]{\fancyplain{}{\bf\rightmark}}
X% \rhead[\fancyplain{}{\bf\leftmark}]{\fancyplain{}{\bf\thepage}}
X% \cfoot{}
X
X%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
X\def\lhead{\@ifnextchar[{\@xlhead}{\@ylhead}}
X\def\@xlhead[#1]#2{\gdef\@elhead{#1}\gdef\@olhead{#2}}
X\def\@ylhead#1{\gdef\@elhead{#1}\gdef\@olhead{#1}}
X
X\def\chead{\@ifnextchar[{\@xchead}{\@ychead}}
X\def\@xchead[#1]#2{\gdef\@echead{#1}\gdef\@ochead{#2}}
X\def\@ychead#1{\gdef\@echead{#1}\gdef\@ochead{#1}}
X
X\def\rhead{\@ifnextchar[{\@xrhead}{\@yrhead}}
X\def\@xrhead[#1]#2{\gdef\@erhead{#1}\gdef\@orhead{#2}}
X\def\@yrhead#1{\gdef\@erhead{#1}\gdef\@orhead{#1}}
X
X\def\lfoot{\@ifnextchar[{\@xlfoot}{\@ylfoot}}
X\def\@xlfoot[#1]#2{\gdef\@elfoot{#1}\gdef\@olfoot{#2}}
X\def\@ylfoot#1{\gdef\@elfoot{#1}\gdef\@olfoot{#1}}
X
X\def\cfoot{\@ifnextchar[{\@xcfoot}{\@ycfoot}}
X\def\@xcfoot[#1]#2{\gdef\@ecfoot{#1}\gdef\@ocfoot{#2}}
X\def\@ycfoot#1{\gdef\@ecfoot{#1}\gdef\@ocfoot{#1}}
X
X\def\rfoot{\@ifnextchar[{\@xrfoot}{\@yrfoot}}
X\def\@xrfoot[#1]#2{\gdef\@erfoot{#1}\gdef\@orfoot{#2}}
X\def\@yrfoot#1{\gdef\@erfoot{#1}\gdef\@orfoot{#1}}
X
X\newdimen\headrulewidth
X\newdimen\footrulewidth
X\newdimen\plainheadrulewidth
X\newdimen\plainfootrulewidth
X\newdimen\headwidth
X\newif\if@fancyplain \@fancyplainfalse
X\def\fancyplain#1#2{\if@fancyplain#1\else#2\fi}
X
X% Initialization of the head and foot text.
X
X\headrulewidth 0.4pt
X\footrulewidth\z@
X\plainheadrulewidth\z@
X\plainfootrulewidth\z@
X
X\lhead[\fancyplain{}{\sl\rightmark}]{\fancyplain{}{\sl\leftmark}}
X% i.e. empty on ``plain'' pages \rightmark on even, \leftmark on odd pages
X\chead{}
X\rhead[\fancyplain{}{\sl\leftmark}]{\fancyplain{}{\sl\rightmark}}
X% i.e. empty on ``plain'' pages \leftmark on even, \rightmark on odd pages
X\lfoot{}
X\cfoot{\rm\thepage} % page number
X\rfoot{}
X
X% Put together a header or footer given the left, center and
X% right text, fillers at left and right and a rule.
X% The \lap commands put the text into an hbox of zero size,
X% so overlapping text does not generate an errormessage.
X
X\def\@fancyhead#1#2#3#4#5{#1\hbox to\headwidth{\vbox{\hbox
X{\rlap{\parbox[b]{\headwidth}{\raggedright#2\strut}}\hfill
X\parbox[b]{\headwidth}{\centering#3\strut}\hfill
X\llap{\parbox[b]{\headwidth}{\raggedleft#4\strut}}}\headrule}}#5}
X
X
X\def\@fancyfoot#1#2#3#4#5{#1\hbox to\headwidth{\vbox{\footrule
X\hbox{\rlap{\parbox[t]{\headwidth}{\raggedright#2\strut}}\hfill
X\parbox[t]{\headwidth}{\centering#3\strut}\hfill
X\llap{\parbox[t]{\headwidth}{\raggedleft#4\strut}}}}}#5}
X
X\def\headrule{{\if@fancyplain\headrulewidth\plainheadrulewidth\fi
X\hrule\@height\headrulewidth\@width\headwidth \vskip-\headrulewidth}}
X
X\def\footrule{{\if@fancyplain\footrulewidth\plainfootrulewidth\fi
X\vskip-0.3\normalbaselineskip\vskip-\footrulewidth
X\hrule\@width\headwidth\@height\footrulewidth\vskip0.3\normalbaselineskip}}
X
X\def\ps@fancy{
X\let\@mkboth\markboth
X\@ifundefined{chapter}{\def\sectionmark##1{\markboth
X{\uppercase{\ifnum \c@secnumdepth>\z@
X \thesection\hskip 1em\relax \fi ##1}}{}}
X\def\subsectionmark##1{\markright {\ifnum \c@secnumdepth >\@ne
X \thesubsection\hskip 1em\relax \fi ##1}}}
X{\def\chaptermark##1{\markboth {\uppercase{\ifnum \c@secnumdepth>\m@ne
X \@chapapp\ \thechapter. \ \fi ##1}}{}}
X\def\sectionmark##1{\markright{\uppercase{\ifnum \c@secnumdepth >\z@
X \thesection. \ \fi ##1}}}}
X\def\@oddhead{\@fancyhead\relax\@olhead\@ochead\@orhead\hss}
X\def\@oddfoot{\@fancyfoot\relax\@olfoot\@ocfoot\@orfoot\hss}
X\def\@evenhead{\@fancyhead\hss\@elhead\@echead\@erhead\relax}
X\def\@evenfoot{\@fancyfoot\hss\@elfoot\@ecfoot\@erfoot\relax}
X\headwidth\textwidth}
X\def\ps@fancyplain{\ps@fancy \let\ps@plain\ps@plain@fancy}
X\def\ps@plain@fancy{\@fancyplaintrue\ps@fancy}
SHAR_EOF
if test 9673 -ne "`wc -c < 'fancyheadings.sty'`"
then
echo shar: "error transmitting 'fancyheadings.sty'" '(should have been 9673 characters)'
fi
fi
echo shar: "extracting 'parskip.sty'" '(1208 characters)'
if test -f 'parskip.sty'
then
echo shar: "will not over-write existing file 'parskip.sty'"
else
sed 's/^ X//' << \SHAR_EOF > 'parskip.sty'
X% This is PARSKIP.STY by H.Partl, TU Wien, as of 19 Jan 1989.
X% Document Style Option to be used with any style and with any size.
X% It produces the following Paragraph Layout:
X% Zero Parindent and non-zero Parskip. The stretchable glue in \parskip
X% helps LaTeX in finding the best place for page breaks.
X
X\parskip=0.5\baselineskip \advance\parskip by 0pt plus 2pt
X\parindent=\z@
X
X% To accompany this, the vertical spacing in the list environments is changed
X% to use the same as \parskip in all relevant places (for normalsize only):
X% \parsep = \parskip
X% \itemsep = \z@ % add nothing to \parskip between items
X% \topsep = \z@ % add nothing to \parskip before first item
X
X\def\@listI{\leftmargin\leftmargini
X \topsep\z@ \parsep\parskip \itemsep\z@}
X\let\@listi\@listI
X\@listi
X
X\def\@listii{\leftmargin\leftmarginii
X \labelwidth\leftmarginii\advance\labelwidth-\labelsep
X \topsep\z@ \parsep\parskip \itemsep\z@}
X
X\def\@listiii{\leftmargin\leftmarginiii
X \labelwidth\leftmarginiii\advance\labelwidth-\labelsep
X \topsep\z@ \parsep\parskip \itemsep\z@}
X
X% Note that listiv, listv and listvi don't change vertical parameters.
X
X\endinput
X
X
SHAR_EOF
if test 1208 -ne "`wc -c < 'parskip.sty'`"
then
echo shar: "error transmitting 'parskip.sty'" '(should have been 1208 characters)'
fi
fi
echo shar: "extracting 'titlepage.sty'" '(601 characters)'
if test -f 'titlepage.sty'
then
echo shar: "will not over-write existing file 'titlepage.sty'"
else
sed 's/^ X//' << \SHAR_EOF > 'titlepage.sty'
X% titlepage.sty 27 Jan 85
X\def\maketitle{\begin{titlepage}
X\let\footnotesize\small \let\footnoterule\relax \setcounter{page}{0}
X\null
X\vfil
X\vskip 60pt \begin{center}
X{\LARGE \@title \par} \vskip 3em {\large \lineskip .75em
X\begin{tabular}[t]{c}\@author
X\end{tabular}\par}
X\vskip 1.5em {\large \@date \par} \end{center} \par
X\@thanks
X\vfil
X\null
X\end{titlepage}
X\setcounter{footnote}{0} \let\thanks\relax
X\gdef\@thanks{}\gdef\@author{}\gdef\@title{}\let\maketitle\relax}
X\def\abstract{\titlepage
X\null\vfil
X\begin{center}
X{\bf Abstract}
X\end{center}}
X\def\endabstract{\par\vfil\null\endtitlepage}
SHAR_EOF
if test 601 -ne "`wc -c < 'titlepage.sty'`"
then
echo shar: "error transmitting 'titlepage.sty'" '(should have been 601 characters)'
fi
fi
exit 0
# End of shell archive