\HeaderA{groupGeneric}{Group Generic Functions}{groupGeneric}
\aliasA{.Class}{groupGeneric}{.Class}
\aliasA{.Generic}{groupGeneric}{.Generic}
\aliasA{.Group}{groupGeneric}{.Group}
\aliasA{.Method}{groupGeneric}{.Method}
\aliasA{Arith}{groupGeneric}{Arith}
\aliasA{Compare}{groupGeneric}{Compare}
\aliasA{Complex}{groupGeneric}{Complex}
\aliasA{group generic}{groupGeneric}{group generic}
\aliasA{Math}{groupGeneric}{Math}
\methaliasA{Math.data.frame}{groupGeneric}{Math.data.frame}
\aliasA{Math2}{groupGeneric}{Math2}
\aliasA{Ops}{groupGeneric}{Ops}
\methaliasA{Ops.data.frame}{groupGeneric}{Ops.data.frame}
\aliasA{Summary}{groupGeneric}{Summary}
\methaliasA{Summary.data.frame}{groupGeneric}{Summary.data.frame}
\keyword{methods}{groupGeneric}
\begin{Description}\relax
Group generic functions can be defined with either S3 and S4 methods
(with different groups).  Methods are defined for the group of functions
as a whole.

A method defined for an individual member of the group takes
precedence over a method defined for the group as a whole.

When package \pkg{methods} is attached there are objects visible with
the names of the group generics: these functions should never be
called directly (a suitable error message will result if they are).
\end{Description}
\begin{Usage}
\begin{verbatim}
## S3 methods have prototypes:
Math(x, ...)
Ops(e1, e2)
Complex(z)
Summary(x, ...)
## S3 method for class 'data.frame':
Summary(..., na.rm)

## S4 methods have prototypes:
Arith(e1, e2)
Compare(e1, e2)
Ops(e1, e2)
Math(x)
Math2(x, digits)
Summary(x, ..., na.rm = FALSE)
Complex(z)
\end{verbatim}
\end{Usage}
\begin{Arguments}
\begin{ldescription}
\item[\code{x, z, e1, e2}] objects.
\item[\code{digits}] number of digits to be used in \code{round} or \code{signif}.
\item[\code{...}] further arguments passed to or from methods.
\item[\code{na.rm}] logical: should missing values be removed?
\end{ldescription}
\end{Arguments}
\begin{Section}{S3 Group Dispatching}
There are four \emph{groups} for which S3 methods can be written,
namely the \code{"Math"}, \code{"Ops"}, \code{"Summary"} and
\code{"Complex"} groups.  These are not \R{} objects, but methods can be
supplied for them and base \R{} contains \code{\LinkA{factor}{factor}},
\code{\LinkA{data.frame}{data.frame}} and \code{\LinkA{difftime}{difftime}} methods for
the first three groups.
(There are also a \code{\LinkA{ordered}{ordered}} method for \code{Ops},
\code{\LinkA{POSIXt}{POSIXt}} methods for \code{Math} and \code{Ops}, as well as a
\code{\LinkA{ts}{ts}} method for \code{Ops} in package \pkg{stats}.)


\Enumerate{
\item Group \code{"Math"}:
\Itemize{
\item
\code{abs}, \code{sign}, \code{sqrt}, \\
\code{floor}, \code{ceiling}, \code{trunc},\\
\code{round}, \code{signif}

\item \code{exp}, \code{log}, \\
\code{cos}, \code{sin}, \code{tan},\\
\code{acos}, \code{asin}, \code{atan}

\code{cosh}, \code{sinh}, \code{tanh},\\
\code{acosh}, \code{asinh}, \code{atanh}

\item
\code{lgamma}, \code{gamma}, \code{gammaCody},\\
\code{digamma}, \code{trigamma}

\item \code{cumsum}, \code{cumprod}, \code{cummax}, \code{cummin}
}

\item Group \code{"Ops"}:
\Itemize{
\item
\code{"+"}, \code{"-"}, \code{"*"}, \code{"/"},
\code{"\textasciicircum{}"}, \code{"\%\%"}, \code{"\%/\%"}

\item \code{"\&"}, \code{"|"}, \code{"!"}

\item \code{"=="}, \code{"!="},
\code{"<"}, \code{"<="}, \code{">="}, \code{">"}
}

\item Group \code{"Summary"}:
\Itemize{
\item \code{all}, \code{any}
\item \code{sum}, \code{prod}
\item \code{min}, \code{max}
\item \code{range}
}

\item Group \code{Complex}:
\Itemize{
\item \code{Arg}, \code{Conj}, \code{Im}, \code{Mod}, \code{Re}
}
}

Note that a method will used for either one of these groups or one of
its members \emph{only} if it corresponds to a \code{"class"}
attribute, as the internal code dispatches on \code{\LinkA{oldClass}{oldClass}}
and not on \code{\LinkA{class}{class}}.  This is for efficiency: having to
dispatch on, say, \code{Ops.integer} would be too slow.

The number of arguments supplied for \code{"Math"} group generic
methods is not checked prior to dispatch. (Most have default methods
expecting one argument, but three expect two.)

All of the members of the \code{Summary} group have a last argument
\code{na.rm}, so a \code{Summary} group method can be written with
argument list \code{function(..., na.rm)}, and methods should be
prepared to handle a \code{na.rm} argument.
\end{Section}
\begin{Section}{S4 Group Dispatching}
When package \pkg{methods} is attached (which it is by default),
formal (S4) methods can be defined for groups.

The functions belonging to the various groups are as follows:
\describe{
\item[\code{Arith}] \code{"+"}, \code{"-"}, \code{"*"}, \code{"\textasciicircum{}"},
\code{"\%\%"}, \code{"\%/\%"}, \code{"/"}
\item[\code{Compare}] \code{"=="}, \code{">"}, \code{"<"},
\code{"!="}, \code{"<="}, \code{">="}
\item[\code{Ops}] \code{"Arith"}, \code{"Compare"}
\item[\code{Math}] \code{"log"}, \code{"sqrt"}, \code{"log10"},
\code{"cumprod"}, \code{"abs"}, \code{"acos"}, \code{"acosh"},
\code{"asin"}, \code{"asinh"}, \code{"atan"}, \code{"atanh"},
\code{"ceiling"}, \code{"cos"}, \code{"cosh"}, \code{"cumsum"},
\code{"exp"}, \code{"floor"}, \code{"gamma"}, \code{"lgamma"},
\code{"sin"}, \code{"sinh"}, \code{"tan"}, \code{"tanh"},
\code{"trunc"}
\item[\code{Math2}] \code{"round"}, \code{"signif"}
\item[\code{Summary}] \code{"max"}, \code{"min"}, \code{"range"},
\code{"prod"}, \code{"sum"}, \code{"any"}, \code{"all"}
\item[\code{Complex}] \code{"Arg"}, \code{"Conj"}, \code{"Im"},
\code{"Mod"}, \code{"Re"}
}
Functions with the group names exist in the \pkg{methods} package but
should not be called directly.

All the functions in these groups (other than the group generics
themselves) are basic functions in \R.  They are not by default S4 generic
functions, and many of them are defined as primitives, meaning that
they do not have formal arguments.  However, you can still define
formal methods for them.  The effect of doing so is to create an S4 generic
function with the appropriate arguments, in the environment where the
method definition is to be stored.  It all works more or less as you
might expect, admittedly via a bit of trickery in the background.

Note: currently those members which are not primitive functions must
have been converted to S4 generic functions (preferably
\emph{before} setting an S4 group generic method) as it only sets
methods for known S4 generics.  This can be done by a call to
\code{setGeneric}, for example \code{setGeneric("round", group="Math2")}.
\end{Section}
\begin{References}\relax
Appendix A, \emph{Classes and Methods} of\\
Chambers, J. M.  and Hastie, T. J. eds (1992)
\emph{Statistical Models in S.}
Wadsworth \& Brooks/Cole.

Chambers, J. M. (1998) \emph{Programming with Data.} Springer, pp. 352--4.
\end{References}
\begin{SeeAlso}\relax
\code{\LinkA{methods}{methods}} for methods of non-Internal generic functions.
\end{SeeAlso}
\begin{Examples}
\begin{ExampleCode}
d.fr <- data.frame(x=1:9, y=rnorm(9))
data.class(1 + d.fr) == "data.frame" ##-- add to d.f. ...

if(.isMethodsDispatchOn()) {# package "methods" is attached or loaded
  methods("Math")
  methods("Ops")
  methods("Summary")

  setClass("testComplex", representation(zz = "complex"))
  ## method for whole group "Complex"
  setMethod("Complex", "testComplex",
            function(z) c("groupMethod", callGeneric(z@zz)))
  ## exception for Arg() :
  setMethod("Arg", "testComplex",
            function(z) c("ArgMethod", Arg(z@zz)))
  z1 <- 1+2i
  z2 <- new("testComplex", zz = z1)
  stopifnot(identical(Mod(z2), c("groupMethod", Mod(z1))))
  stopifnot(identical(Arg(z2), c("ArgMethod", Arg(z1))))
}\end{ExampleCode}
\end{Examples}

