%\VignetteDepends{Biobase,IRanges,Biostrings}
%\VignetteIndexEntry{S4 System Development in Bioconductor}
%\VignettePackage{AdvancedR}

\documentclass{beamer}

\usepackage{Bioconductor}
\SweaveOpts{keep.source=TRUE}

\title{S4 System Development in Bioconductor}
\author{Patrick Aboyoun}
\institute[FHCRC]{Fred Hutchinson Cancer Research Center}
\date{20-21 May, 2010}

\begin{document}

<<setup, echo=FALSE>>=
options(width = 62)
@ 

\frame{\titlepage}

\section[Outline]{}
\frame{\tableofcontents}


\begin{frame}
  \frametitle{BioC Motivation for OOP}
  \begin{figure}
    \includegraphics[width=2.5in]{S4/garbage_in_garbage_out.png}
    \renewcommand{\figurename}{OOP}
    \caption{Minimizing inaccurate inputs \& modularizing inputs and
      outputs.}
  \end{figure}
\end{frame}


\section{Introduction}

\subsection{Object-Oriented Programming in R}

\begin{frame}[t]
  \frametitle{Two Programming Systems in \R{}}
  \begin{itemize}
    \item \R{} is an implementation of the S3 language by Chambers
      and Hastie (1992).
    \item S3 uses a \textit{``class" attribute} to mimic aspects of
      OOP.
    \item S4 is a formal OOP system.
    \item The \Rpackage{methods} package implements the S4 system
      as described in Chambers (1998) and Chambers (2008).
  \end{itemize}
  \begin{figure}
    \includegraphics[height=1.3in,width=1in]{S4/Chambers1998.jpg}
    \hspace{0.77in}%
    \includegraphics[height=1.3in,width=1in]{S4/Chambers2008.jpg}
  \end{figure}
\end{frame}


\subsection{Role of S4 in Bioconductor}

\begin{frame}[t]
  \frametitle{Main Features of Bioconductor}
\begin{block}{S4 superiority to S3 in realizing BioC features}
  \begin{itemize}
    \item The \R{} project for statistical computing
    \item Documentation and \textbf{reproducible research}
    \item Statistical and graphical \textbf{methods for genomic data}
    \item \textbf{Genomic annotations}
    \item Open source
    \item \textbf{Open development}
  \end{itemize}
\end{block}
\begin{block}{Reasons}
  \begin{itemize}
    \item Explicit representation of classes
    \item Validity checking of instances
    \item Methods registered with generics
  \end{itemize}
\end{block}
\end{frame}

\begin{frame}[t]
  \frametitle{Use of S4 in Bioconductor}
\begin{block}{Statistics on packages in BioC 2.6}
  \begin{itemize}
    \item 197 of 389 (51\%) BioC packages define S4 classes
    \item 97 use inheritance
    \begin{itemize}
      \item traditional parents: \Rclass{ExpressionSet}
        and \Rclass{eSet} from \Rpackage{Biobase}
      \item newer prolific parent: \Rclass{Sequence} from
        \Rpackage{IRanges}
      \item common off-beat parent: \Rclass{list}, an S3 type
    \end{itemize}
    \item 30 define virtual classes
    \item 14 use multiple inheritance
  \end{itemize}
\end{block}
\end{frame}


\section{S4 Basics}

\begin{frame}[t]
  \frametitle{S4 Framework}
\begin{block}{S4 Components}
  \begin{columns}[t]
    \column{0.3\textwidth}
    \textit{Class}
    \begin{itemize}
      \item is virtual?
      \item slots (properties)
      \item contains (inherits)
      \item prototype
      \item validity function
    \end{itemize}

    \column{0.3\textwidth}
    \textit{Generic Function}
    \begin{itemize}
      \item dispatch signature
      \item dispatch method
    \end{itemize}

    \column{0.3\textwidth}
    \textit{Methods{\footnotesize *}}
    \begin{itemize}
      \item signature mapping
      \item function definition
    \end{itemize}
      {\scriptsize * Grouped in methods list}
  \end{columns}
\end{block}
\begin{block}{Important differences with Java and C++}
  \begin{enumerate}
    \item Classes don't own methods.
    \item Design goal: Be ``vectorized".
      \begin{enumerate}[(a)]
        \item Class slots ideally vectors and matrices.
        \item Methods avoid unnecessary looping.
      \end{enumerate}
  \end{enumerate}
\end{block}
\end{frame}

\subsection{S4 Classes}

\begin{frame}[t]
  \frametitle{S4 Class Creation}
\begin{block}{\Rfunction{setClass} function arguments}
  \begin{itemize}
    \item \Rfunarg{Class} -- the class name.
    \item \Rfunarg{representation} -- the slot definitions.
    \item \Rfunarg{contains} -- the parent classes.
    \item \Rfunarg{prototype} -- the slot values for a default
      instance.
    \item \Rfunarg{validity} -- a function that checks instance
      validity.
  \end{itemize}
\end{block}
\begin{block}{\Rfunction{new} constructor arguments}
  \begin{itemize}
    \item \Rfunarg{Class} -- the class name.
    \item \Rfunarg{...} -- typically, slot values.
  \end{itemize}
\end{block}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Canonical Example in S4 (1/2)}
{\footnotesize
\begin{block}{Class definition}
<<Greeting-class, results=hide>>=
setClass("Greeting",
         representation =
         representation(phrase = "character"),
         prototype = prototype(phrase = "Hello world!"))
@
\end{block}
\begin{block}{Default instantiation}
<<Greeting-new-default>>=
new("Greeting")
@
\end{block}
\begin{block}{Customized instantiation}
<<Greeting-new-custom>>=
new("Greeting", phrase = "ciao")
@
\end{block}
}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Canonical Example in S4 (2/2)}
\begin{block}{Validity method}
{\small
<<setValidity, results=hide>>=
setValidity("Greeting",
    function(object) {
        if (length(object@phrase) != 1)
            "'phrase' not a single string"
        else if (!nzchar(object@phrase))
            "'phrase' is empty"
        else
            TRUE
    })
@
}
\end{block}
\begin{block}{Invalid object instantiation}
{\small
\begin{verbatim}
> new("Greeting", phrase = "")
Error in validObject(.Object) : 
  invalid class "Greeting" object: 'phrase' is empty
\end{verbatim}
}
\end{block}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Creating New S4 Objects from Old}
\begin{block}{\Rfunction{initialize} function arguments}
  \begin{itemize}
    \item \Rfunarg{.Object} -- an S4 object.
    \item \Rfunarg{...} -- typically, new slot values.
  \end{itemize}
\end{block}
\begin{block}{Creation via \Rfunction{initialize}}
{\small
<<Greeting-update>>=
nametag <- new("Greeting")
nametag <- initialize(nametag, phrase = "Welcome")
nametag
@
}
\end{block}
\end{frame}


\subsection{S4 Generic Functions \& Methods}

\begin{frame}[t,fragile]
  \frametitle{S4 Generic Function \& Method Creation}
\begin{block}{\Rfunction{setGeneric} function arguments}
  \begin{itemize}
    \item \Rfunarg{name} -- the generic function name.
    \item \Rfunarg{def} -- the generic definition, typically of
      the form
      \vskip4pt
      {\footnotesize
      \verb+function(<<ARG_LIST>>) standardGeneric("<<GEN_NAME>>"))+
      }
      \vskip4pt
    \item \Rfunarg{signature} -- the method dispatch signature.
  \end{itemize}
\end{block}
\begin{block}{\Rfunction{setMethod} function arguments}
   \begin{itemize}
     \item \Rfunarg{f} -- the generic function name.
     \item \Rfunarg{signature} -- the mapping of arguments in
       dispatch signature to classes.
     \item \Rfunarg{definition} -- the method definition.
   \end{itemize}
\end{block}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Generic Function \& Method for Canonical Example (1/2)}
\begin{block}{Generic function definition}
{\small
<<words-generic, results=hide>>=
setGeneric("words", signature = "x",
    function(x) standardGeneric("words"))
@
}
\end{block}
\begin{block}{Method definition}
{\small
<<words-method, results=hide>>=
setMethod("words", c("x" = "Greeting"),
    function(x)
    {
        ans <- strsplit(x@phrase, "\\W")[[1L]]
        sort(unique(ans[nzchar(ans)]))
    })
@
}
\end{block}
\begin{block}{Method invocation}
{\small
<<words-use>>=
words(new("Greeting"))
@
}
\end{block}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Generic Function \& Method for Canonical Example (2/2)}
\begin{block}{Method definition}
{\small
<<words-method, results=hide>>=
setMethod("words", c("x" = "character"),
    function(x)
    {
        ans <- unlist(strsplit(x, "\\W"),
                      use.names = FALSE)
        sort(unique(ans[nzchar(ans)]))
    })
setMethod("words", c("x" = "Greeting"),
    function(x) callGeneric(x@phrase))
@
}
\end{block}
\begin{block}{Method invocation}
{\small
<<words-use>>=
words(new("Greeting"))
@
}
\end{block}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Implicit Generic Method for Canonical Example}
\begin{block}{Non-S4 generic function}
{\small
<<nchar>>=
showMethods("nchar")
@
}
\end{block}
\begin{block}{Method definition}
{\small
<<nchar-method, results=hide>>=
setMethod("nchar", c("x" = "Greeting"),
          function(x) nchar(x@phrase))
@
}
\end{block}
\begin{block}{Method invocation}
{\small
<<nchar-use>>=
nchar(new("Greeting"))
@
}
\end{block}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Implicit Generic Not Always Available}
\begin{block}{}
{\small
<<nzchar, eval=FALSE>>=
showMethods("nzchar")
@
\begin{verbatim}
Error in genericForPrimitive(f) : 
  methods may not be defined for primitive function
"nzchar" in this version of R
\end{verbatim}
}
\end{block}
\begin{block}{}
{\small
<<nzchar-method, eval=FALSE>>=
setMethod("nzchar", c("x" = "Greeting"),
          function(x) nzchar(x@phrase))
@
\begin{verbatim}
Error in genericForPrimitive(f) : 
  methods may not be defined for primitive function
"nzchar" in this version of R
\end{verbatim}
}
\end{block}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{S4 Coerce and Replace Method Creation}
\begin{block}{\Rfunction{setAs} function arguments;
  produces \Rfunction{coerce} methods}
  \begin{itemize}
    \item \Rfunarg{from} -- the old object's class.
    \item \Rfunarg{to} -- the new object's class.
    \item \Rfunarg{def} -- the method definition.
  \end{itemize}
\end{block}
\begin{block}{\Rfunction{setReplaceMethod} function;
  produces \Rfunction{"<-"} methods}
  \begin{itemize}
    \item A wrapper for \Rfunction{setMethod} that adds suffix
      \Rfunction{"<-"} to argument \Rfunarg{f}.
    \item e.g. \Rfunction{"names<-"}, usage:
      \verb|names(x) <- letters|.
  \end{itemize}
\end{block}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Coercion Method for Canonical Example}
\begin{block}{Method definition}
{\small
<<coercion-def>>=
setAs("Greeting", "character",
      function(from) from@phrase)
@
}
\end{block}
\begin{block}{Display coerce methods}
{\small
<<coerce-methods>>=
showMethods("coerce", classes = "Greeting")
@
}
\end{block}
\begin{block}{Perform coercion}
{\small
<<coerce-use>>=
as(new("Greeting"), "character")
@
}
\end{block}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Slot Accessor and Replacer in Canonical Example (1/2)}
\begin{block}{Accessor generic and method}
{\small
<<phrase-getter, results=hide>>=
setGeneric("phrase", signature = "x",
    function(x) standardGeneric("phrase"))
setMethod("phrase", "Greeting",
    function(x) x@phrase)
@
}
\end{block}
\begin{block}{Replacer generic and method}
{\small
<<phrase-setter, results=hide>>=
setGeneric("phrase<-", signature = "x",
    function(x, value) standardGeneric("phrase<-"))
setReplaceMethod("phrase", "Greeting",
    function(x, value) initialize(x, phrase = value))
@
}
\end{block}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Slot Accessor and Replacer in Canonical Example (2/2)}
\begin{block}{Accessor invocation}
{\small
<<Greeting-use-getter>>=
silentBob <- new("Greeting")
phrase(silentBob)
@
}
\end{block}
\begin{block}{Replacer invocation}
{\small
<<Greeting-use-replacer, eval=FALSE>>=
phrase(silentBob) <- ""
@
\begin{verbatim}
Error in validObject(.Object) : 
  invalid class "Greeting" object: 'phrase' is empty
\end{verbatim}
}
\end{block}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Motivation for Replacement Methods}
\begin{block}{Slot replacement methods don't validity check}
{\small
<<Greeting-bug>>=
silentBob <- new("Greeting")
silentBob@phrase <- ""
@
\begin{verbatim}
> validObject(silentBob)
Error in validObject(silentBob) : 
  invalid class "Greeting" object: 'phrase' is empty
\end{verbatim}
}
\end{block}
\begin{block}{\Rfunction{initialize} function does}
{\small
\begin{verbatim}
> initialize(silentBob, phrase = "")
Error in validObject(.Object) : 
  invalid class "Greeting" object: 'phrase' is empty
\end{verbatim}
}
\end{block}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Object Display in Canonical Example}
\begin{block}{\Rfunction{show} method definition}
{\small
<<show-method, results=hide>>=
setMethod("show", "Greeting",
    function(object)
    {
        cat("A ", class(object), ": \"", phrase(object),
            "\"\n", sep = "")
    })
@
}
\end{block}
\begin{block}{\Rfunction{show} method invocation}
{\small
<<show-method>>=
new("Greeting")
@
}
\end{block}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Finding Methods for an S4 Class}
\begin{block}{\Rfunction{showMethods} function wrapper}
{\small
<<s4Methods>>=
s4Methods <- function(class)
{
    methods <-
      showMethods(classes = class, printTo = FALSE)
    methods <- methods[grep("^Function:", methods)]
    sapply(strsplit(methods, " "), "[", 2)
}
@
}
\end{block}
\begin{block}{Using custom function}
{\small
<<s4Methods-use>>=
s4Methods("Greeting")
@
}
\end{block}
\end{frame}


\section{S4 Exercises}

\begin{frame}[t,fragile]
  \frametitle{S4 Classes for Exercises}
\begin{block}{Virtual Class}
{\small
<<Sample-class, results=hide>>=
setClass("Sample",
         representation("VIRTUAL",
                        description = "character"))
@
}
\end{block}
\begin{block}{Subclasses}
{\small
<<OneSample-class, results=hide>>=
setClass("OneSample", contains = "Sample",
         representation(one = "numeric"))
@
<<TwoSample-class, results=hide>>=
setClass("TwoSample", contains = "Sample",
         representation(one = "numeric",
                        two = "numeric"))
@
}
\end{block}
\end{frame}

\begin{frame}[t]
  \frametitle{S4 Exercises}
{\small
  \begin{enumerate}
    \item Create a \Rclass{PairedSample} class that inherits
      from \Rclass{TwoSample}.
      \begin{enumerate}[(a)]
        \item Same slots as \Rclass{TwoSample}.
        \item Validity method checks slots \Rfunarg{one} and
          \Rfunarg{two} to be of equal length.
      \end{enumerate}
    \item Create a \Rfunction{tTest} generic and methods using
      \Rfunction{t.test} function from the \Rpackage{stats} package.
      \begin{enumerate}[(a)]
        \item Generic signature \\
          \Rfunction{(x, alternative = c("two.sided", "less", "greater"),
                      mu = 0, conf.level = 0.95, ...)}
        \item \Rclass{OneSample} and \Rclass{PairedSample} method signature \\
          \Rfunction{(x, alternative = c("two.sided", "less", "greater"),
                      mu = 0, conf.level = 0.95)}
        \item \Rclass{TwoSample} method signature \\
          \Rfunction{(x, alternative = c("two.sided", "less", "greater"),
                      mu = 0, conf.level = 0.95, var.equal = FALSE)}
      \end{enumerate}
    \item Create \Rfunction{show} methods and any other features
      you find interesting.
  \end{enumerate}
}
\end{frame}


\section{S4 Constraints}

\subsection{Copy on Slot Modification}

\begin{frame}[t,fragile]
  \frametitle{S4 Objects Always Copied on Modification}
\begin{block}{S4 object copy-on-change}
{\small
\begin{verbatim}
> setClass("DotDash", representation =
+          representation(dot = "raw", dash = "integer"))
> aDotDash <- new("DotDash", dot = as.raw(1), dash = 1:1e8)
> system.time(aDotDash@dot <- as.raw(2))
   user  system elapsed 
  0.254   0.333   0.603 
\end{verbatim}
}
\end{block}
\begin{block}{Best practices}
  \begin{itemize}
    \item Use one \Rfunction{initialize} call instead of multiple
      \Rfunction{"@<-"}/\Rfunction{"slot<-"} calls.
    \item Vectorize (e.g. inherit from \Rpackage{IRanges}'s
      \Rclass{CompressedList} class).
  \end{itemize}
\end{block}
\end{frame}


\subsection{Object Overhead}

\begin{frame}[t,fragile]
  \frametitle{S4 Object Overhead}
\begin{block}{S4 object instantiation timing \& size}
{\small
\begin{verbatim}
> setClass("DotDash", representation =
+          representation(dot = "raw", dash = "integer"))

> system.time(dd <- lapply(1:1e4, function(i) new("DotDash")))
  user  system elapsed 
 0.740   0.003   0.745 

> print(object.size(dd), units = "Mb")
4.2 Mb
\end{verbatim}
}
\end{block}
\begin{block}{Best practice}
  \begin{itemize}
    \item Vectorize (e.g. inherit from \Rpackage{IRanges}'s
      \Rclass{CompressedList} class).
  \end{itemize}
\end{block}
\end{frame}


\subsection{Method Dispatch}

\begin{frame}[t,fragile]
  \frametitle{S4 Method Dispatch}
\begin{block}{S4 method dispatch}
{\small
\begin{verbatim}
> setClass("DotDash", representation =
+          representation(dot = "raw", dash = "integer"))
> aDotDash <- new("DotDash")
> setMethod("show", "DotDash", function(object) cat())
> system.time(lapply(1:1e4, function(i) show(aDotDash)))
   user  system elapsed 
  0.424   0.004   0.441
\end{verbatim}
}
\end{block}
\begin{block}{Best practice}
{\small
\begin{verbatim} 
> chosenFun <- selectMethod("show", "DotDash")
> system.time(lapply(1:1e4, function(i) chosenFun(aDotDash)))
   user  system elapsed 
  0.084   0.001   0.094 
\end{verbatim}
}
\end{block}
\end{frame}


\section{S4 Case Studies}

\subsection{Slot-Oriented Virtual Class (eSet)}

\begin{frame}[t,fragile]
  \frametitle{Slot-Oriented Virtual Class (eSet)}
  \begin{columns}[t]
    \column{0.5\textwidth}
    \Rpackage{Biobase}'s \Rclass{eSet}
{\scriptsize
<<Biobase, results=hide>>=
library(Biobase)
@
<<options-set, echo=FALSE>>=
options(width=35)
@
<<eSet>>=
isVirtualClass("eSet")
getSlots("eSet")
@
<<options-reset, echo=FALSE>>=
options(width=62)
@
}

    \column{0.5\textwidth}
\Rpackage{limma}'s \Rclass{MAList}
{\scriptsize
<<limma, results=hide>>=
library(limma)
@
<<MAList>>=
isVirtualClass("MAList")
getSlots("MAList")
@
}
  \end{columns}
\end{frame}

\subsection{Method-Oriented Virtual Class (Sequence)}

\begin{frame}[t,fragile]
  \frametitle{Method-Oriented Virtual Class (Sequence)}
    \Rpackage{IRanges}'s \Rclass{Sequence}
{\footnotesize
<<IRanges, results=hide>>=
library(IRanges)
@
<<Sequence>>=
isVirtualClass("Sequence")
getSlots("Sequence")
getSlots("Rle")
length(s4Methods("Sequence"))
head(s4Methods("Sequence"), 8)
@
}
\end{frame}

\begin{frame}[t,fragile]
  \frametitle{Method-Oriented Virtual Class (Sequence)}
\begin{block}{\Rclass{Sequence} subclass defines}
  \Rfunction{"["}, \Rfunction{c}, \Rfunction{length},
  \Rfunction{window}, \Rfunction{seqselect}, \Rfunction{"seqselect<-"}
\end{block}
\begin{block}{\Rclass{Sequence} subclass inherits}
    \Rfunction{head}, \Rfunction{tail}, \Rfunction{append},
    \Rfunction{subset}, \Rfunction{rep}, \Rfunction{rev} \footnotesize{(optimize?)},
    \Rfunction{"window<-"}, \Rfunction{"[<-"}
{\footnotesize
\begin{verbatim}
setMethod("head", "Sequence",
    function(x, n = 6L, ...)
    {
        stopifnot(length(n) == 1L)
        if (n < 0L)
            n <- max(length(x) + n, 0L)
        else
            n <- min(n, length(x))
        if (n == 0L)
            x[integer(0)]
        else
            window(x, 1L, n)
    })
\end{verbatim}
}
\end{block}
\end{frame}

\subsection{Multiple Inheritance \& Vectorization (CompressedIRangesList)}

\begin{frame}[t,fragile]
  \frametitle{Multiple Inheritance \& Vectorization (CompressedIRangesList)}
\begin{block}{\Rclass{CompressedIRangesList}}
{\small
\begin{verbatim}
setClass("CompressedIRangesList",
         prototype = prototype(elementType = "IRanges",
                               unlistData = new("IRanges")),
         contains = c("IRangesList", "CompressedList"))
\end{verbatim}
}
\end{block}
\begin{block}{\Rpackage{IRanges}'s \Rclass{List} paradigm}
  \begin{itemize}
    \item \Rclass{IRangesList} -- a method-oriented virtual class
    \item \Rclass{CompressedList} -- a slot-oriented virtual class
    \item \Rclass{SimpleIRangesList} -- a sibling class to 
      \Rclass{CompressedIRangesList}
  \end{itemize}
\end{block}
\end{frame}

\subsection{Build or Reuse? (CompresssedIRangesList)}

\begin{frame}[t,fragile]
  \frametitle{Build or Reuse? (CompresssedIRangesList)}
  \begin{columns}[t]
    \column{0.5\textwidth}
    \Rpackage{IRanges}'s \Rclass{CompressedIRangesList}
{\scriptsize
<<options-set, echo=FALSE>>=
options(width=35)
@
<<IRanges, results=hide>>=
library(IRanges)
@
<<CompressedIRangesList>>=
is(new("CompressedIRangesList"))
length(s4Methods("RangesList"))
head(s4Methods("RangesList"), 8)
@
}

    \column{0.5\textwidth}
\Rpackage{Biostrings}'s \Rclass{MIndex}
{\scriptsize
<<Biostrings, results=hide>>=
library(Biostrings)
@
<<MIndex>>=
isVirtualClass("MIndex")
s4Methods("MIndex")
s4Methods("ByPos_MIndex")
@
<<options-reset, echo=FALSE>>=
options(width=62)
@
}
  \end{columns}
\end{frame}

\subsection{Class Union \& Group Generic (Rle)}

\begin{frame}[t,fragile]
  \frametitle{Class Union \& Group Generic (Rle)}
  \Rpackage{IRanges}'s \Rclass{Rle}
{\footnotesize
\begin{verbatim}
setClassUnion("vectorORfactor", c("vector", "factor"))

setClass("Rle", contains = "Sequence")
         representation(values = "vectorORfactor",
                        lengths = "integer"),
         <<REMAINING DEFINITION>>)

setMethod("Summary", "Rle",
    function(x, ..., na.rm = FALSE)
        switch(.Generic,
               all =, any =, min =, max =, range =
               callGeneric(runValue(x), ..., na.rm = na.rm),
               sum = sum(runValue(x) * runLength(x), ...,
                         na.rm = na.rm),
               prod = prod(runValue(x) ^ runLength(x), ...,
                           na.rm = na.rm)))
\end{verbatim}
}
\end{frame}


\section{Resources}

\begin{frame}{Resources}
  \begin{block}{Books}
{\small
    \begin{itemize}
      \item John M. Chambers.
        \textit{Software for Data Analysis: Programming with R}.
        Springer, New York, 2008. ISBN-13 978-0387759357.
      \item Robert Gentleman. \textit{R Programming for Bioinformatics}.
        Chapman \& Hall/CRC, New York, 2008. ISBN-13 978-1420063677.
    \end{itemize}
}
  \end{block}
  \begin{block}{Documents on the Web}
{\small
    \begin{itemize}
      \item John M. Chambers. ``How S4 Methods Work", \\
        \url{http://developer.r-project.org/howMethodsWork.pdf}
      \item Friedrich Leisch, ``S4 Classes and Methods", \\
        \url{http://www.ci.tuwien.ac.at/Conferences/useR-2004/Keynotes/Leisch.pdf}
      \item ``S4 Classes in 15 pages, more or less", \\
        \url{http://www.stat.auckland.ac.nz/S-Workshop/Gentleman/S4Objects.pdf}
    \end{itemize}
}
  \end{block}
\end{frame}

\end{document}
