\HeaderA{Grouping-class}{Grouping objects}{Grouping.Rdash.class}
\aliasA{Binning}{Grouping-class}{Binning}
\aliasA{Binning-class}{Grouping-class}{Binning.Rdash.class}
\aliasA{class:Binning}{Grouping-class}{class:Binning}
\aliasA{class:Dups}{Grouping-class}{class:Dups}
\aliasA{class:Grouping}{Grouping-class}{class:Grouping}
\aliasA{class:H2LGrouping}{Grouping-class}{class:H2LGrouping}
\aliasA{class:Partitioning}{Grouping-class}{class:Partitioning}
\aliasA{class:PartitioningByEnd}{Grouping-class}{class:PartitioningByEnd}
\aliasA{class:PartitioningByWidth}{Grouping-class}{class:PartitioningByWidth}
\aliasA{coerce,Ranges,PartitioningByEnd-method}{Grouping-class}{coerce,Ranges,PartitioningByEnd.Rdash.method}
\aliasA{coerce,Ranges,PartitioningByWidth-method}{Grouping-class}{coerce,Ranges,PartitioningByWidth.Rdash.method}
\aliasA{duplicated,Dups-method}{Grouping-class}{duplicated,Dups.Rdash.method}
\aliasA{Dups}{Grouping-class}{Dups}
\aliasA{Dups-class}{Grouping-class}{Dups.Rdash.class}
\aliasA{end,PartitioningByEnd-method}{Grouping-class}{end,PartitioningByEnd.Rdash.method}
\aliasA{end,PartitioningByWidth-method}{Grouping-class}{end,PartitioningByWidth.Rdash.method}
\aliasA{Grouping}{Grouping-class}{Grouping}
\aliasA{grouplength}{Grouping-class}{grouplength}
\aliasA{grouplength,Binning-method}{Grouping-class}{grouplength,Binning.Rdash.method}
\aliasA{grouplength,Grouping-method}{Grouping-class}{grouplength,Grouping.Rdash.method}
\aliasA{grouplength,H2LGrouping-method}{Grouping-class}{grouplength,H2LGrouping.Rdash.method}
\aliasA{grouplength,Partitioning-method}{Grouping-class}{grouplength,Partitioning.Rdash.method}
\aliasA{grouprank}{Grouping-class}{grouprank}
\aliasA{grouprank,H2LGrouping-method}{Grouping-class}{grouprank,H2LGrouping.Rdash.method}
\aliasA{H2LGrouping}{Grouping-class}{H2LGrouping}
\aliasA{H2LGrouping-class}{Grouping-class}{H2LGrouping.Rdash.class}
\aliasA{high2low}{Grouping-class}{high2low}
\aliasA{high2low,H2LGrouping-method}{Grouping-class}{high2low,H2LGrouping.Rdash.method}
\aliasA{high2low,Sequence-method}{Grouping-class}{high2low,Sequence.Rdash.method}
\aliasA{high2low,vector-method}{Grouping-class}{high2low,vector.Rdash.method}
\aliasA{length,Binning-method}{Grouping-class}{length,Binning.Rdash.method}
\aliasA{length,H2LGrouping-method}{Grouping-class}{length,H2LGrouping.Rdash.method}
\aliasA{length,PartitioningByEnd-method}{Grouping-class}{length,PartitioningByEnd.Rdash.method}
\aliasA{length,PartitioningByWidth-method}{Grouping-class}{length,PartitioningByWidth.Rdash.method}
\aliasA{length<-,H2LGrouping-method}{Grouping-class}{length<.Rdash.,H2LGrouping.Rdash.method}
\aliasA{low2high}{Grouping-class}{low2high}
\aliasA{low2high,H2LGrouping-method}{Grouping-class}{low2high,H2LGrouping.Rdash.method}
\aliasA{members}{Grouping-class}{members}
\aliasA{members,Grouping-method}{Grouping-class}{members,Grouping.Rdash.method}
\aliasA{members,H2LGrouping-method}{Grouping-class}{members,H2LGrouping.Rdash.method}
\aliasA{names,Binning-method}{Grouping-class}{names,Binning.Rdash.method}
\aliasA{names,Partitioning-method}{Grouping-class}{names,Partitioning.Rdash.method}
\aliasA{names<-,Binning-method}{Grouping-class}{names<.Rdash.,Binning.Rdash.method}
\aliasA{names<-,Partitioning-method}{Grouping-class}{names<.Rdash.,Partitioning.Rdash.method}
\aliasA{nobj}{Grouping-class}{nobj}
\aliasA{nobj,Binning-method}{Grouping-class}{nobj,Binning.Rdash.method}
\aliasA{nobj,H2LGrouping-method}{Grouping-class}{nobj,H2LGrouping.Rdash.method}
\aliasA{nobj,PartitioningByEnd-method}{Grouping-class}{nobj,PartitioningByEnd.Rdash.method}
\aliasA{nobj,PartitioningByWidth-method}{Grouping-class}{nobj,PartitioningByWidth.Rdash.method}
\aliasA{Partitioning}{Grouping-class}{Partitioning}
\aliasA{Partitioning-class}{Grouping-class}{Partitioning.Rdash.class}
\aliasA{PartitioningByEnd}{Grouping-class}{PartitioningByEnd}
\aliasA{PartitioningByEnd-class}{Grouping-class}{PartitioningByEnd.Rdash.class}
\aliasA{PartitioningByWidth}{Grouping-class}{PartitioningByWidth}
\aliasA{PartitioningByWidth-class}{Grouping-class}{PartitioningByWidth.Rdash.class}
\aliasA{show,Dups-method}{Grouping-class}{show,Dups.Rdash.method}
\aliasA{show,Grouping-method}{Grouping-class}{show,Grouping.Rdash.method}
\aliasA{start,PartitioningByEnd-method}{Grouping-class}{start,PartitioningByEnd.Rdash.method}
\aliasA{start,PartitioningByWidth-method}{Grouping-class}{start,PartitioningByWidth.Rdash.method}
\aliasA{togroup}{Grouping-class}{togroup}
\aliasA{togroup,Binning-method}{Grouping-class}{togroup,Binning.Rdash.method}
\aliasA{togroup,H2LGrouping-method}{Grouping-class}{togroup,H2LGrouping.Rdash.method}
\aliasA{togroup,Partitioning-method}{Grouping-class}{togroup,Partitioning.Rdash.method}
\aliasA{togrouplength}{Grouping-class}{togrouplength}
\aliasA{togrouplength,Grouping-method}{Grouping-class}{togrouplength,Grouping.Rdash.method}
\aliasA{togrouprank}{Grouping-class}{togrouprank}
\aliasA{togrouprank,H2LGrouping-method}{Grouping-class}{togrouprank,H2LGrouping.Rdash.method}
\aliasA{vmembers}{Grouping-class}{vmembers}
\aliasA{vmembers,Grouping-method}{Grouping-class}{vmembers,Grouping.Rdash.method}
\aliasA{vmembers,H2LGrouping-method}{Grouping-class}{vmembers,H2LGrouping.Rdash.method}
\aliasA{width,PartitioningByEnd-method}{Grouping-class}{width,PartitioningByEnd.Rdash.method}
\aliasA{width,PartitioningByWidth-method}{Grouping-class}{width,PartitioningByWidth.Rdash.method}
\aliasA{[[,Binning-method}{Grouping-class}{[[,Binning.Rdash.method}
\aliasA{[[,H2LGrouping-method}{Grouping-class}{[[,H2LGrouping.Rdash.method}
\aliasA{[[,Partitioning-method}{Grouping-class}{[[,Partitioning.Rdash.method}
\keyword{methods}{Grouping-class}
\keyword{classes}{Grouping-class}
\begin{Description}\relax
In this man page, we call "grouping" the action of dividing a collection of
NO objects into NG groups (some of which may be empty). The Grouping class
and subclasses are containers for representing groupings.
\end{Description}
\begin{Section}{The Grouping core API}
Let's give a formal description of the Grouping core API:

Groups G_i are indexed from 1 to NG (1 <= i <= NG).

Objects O_j are indexed from 1 to NO (1 <= j <= NO).

Every object must belong to one group and only one.

Given that empty groups are allowed, NG can be greater than NO.

Grouping an empty collection of objects (NO = 0) is supported. In that
case, all the groups are empty. And only in that case, NG can be zero
too (meaning there are no groups).

If \code{x} is a Grouping object:
\describe{
\item[] \code{length(x)}:
Returns the number of groups (NG).

\item[] \code{names(x)}:
Returns the names of the groups.

\item[] \code{nobj(x)}:
Returns the number of objects (NO). Equivalent to \code{length(togroup(x))}.

}

Going from groups to objects:
\describe{
\item[] \code{x[[i]]}:
Returns the indices of the objects (the j's) that belong to G_i.
The j's are returned in ascending order.
This provides the mapping from groups to objects (one-to-many mapping).

\item[] \code{grouplength(x, i=NULL)}:
Returns the number of objects in G_i.
Works in a vectorized fashion (unlike \code{x[[i]]}).
\code{grouplength(x)} is equivalent to \code{grouplength(x, seq\_len(length(x)))}.
If \code{i} is not NULL, \code{grouplength(x, i)} is equivalent to
\code{sapply(i, function(ii) length(x[[ii]]))}.

\item[] \code{members(x, i)}:
Equivalent to \code{x[[i]]} if \code{i} is a single integer.
Otherwise, if \code{i} is an integer vector of arbitrary length, it's
equivalent to \code{sort(unlist(sapply(i, function(ii) x[[ii]])))}.

\item[] \code{vmembers(x, L)}:
A version of \code{members} that works in a vectorized fashion with
respect to the \code{L} argument (\code{L} must be a list of integer
vectors). Returns \code{lapply(L, function(i) members(x, i))}.

}

Going from objects to groups:
\describe{
\item[] \code{togroup(x, j=NULL)}:
Returns the index i of the group that O_j belongs to.
This provides the mapping from objects to groups (many-to-one mapping).
Works in a vectorized fashion. \code{togroup(x)} is equivalent to
\code{togroup(x, seq\_len(nobj(x)))}: both return the entire mapping in
an integer vector of length NO.
If \code{j} is not NULL, \code{togroup(x, j)} is equivalent to
\code{y <- togroup(x); y[j]}.

\item[] \code{togrouplength(x, j=NULL)}:
Returns the number of objects that belong to the same group as O_j
(including O_j itself).
Equivalent to \code{grouplength(x, togroup(x, j))}.

}

Given that \code{length}, \code{names} and \code{[[} are defined
for Grouping objects, those objects can be considered \LinkA{Sequence}{Sequence}
objects. In particular, \code{as.list} works out-of-the-box on them.

One important property of any Grouping object \code{x} is
that \code{unlist(as.list(x))} is always a permutation of 
\code{seq\_len(nobj(x))}. This is a direct consequence of the fact
that every object in the grouping belongs to one group and only
one.
\end{Section}
\begin{Section}{The H2LGrouping and Dups subclasses}
[DOCUMENT ME]
\end{Section}
\begin{Section}{The Partitioning subclass}
A Partitioning container represents a block-grouping, i.e. a grouping
where each group contains objects that are neighbors in the original
collection of objects. More formally, a grouping \code{x} is a
block-grouping iff \code{togroup(x)} is sorted in increasing order
(not necessarily strictly increasing).

A block-grouping object can also be seen (and manipulated) as a
\LinkA{Ranges}{Ranges} object where all the ranges are adjacent starting at 1
(i.e. it covers the 1:NO interval with no overlap between the ranges).

Note that a Partitioning object is both: a particular type of Grouping
object and a particular type of \LinkA{Ranges}{Ranges} object. Therefore all the
methods that are defined for Grouping and \LinkA{Ranges}{Ranges} objects can also
be used on a Partitioning object. See \code{?Ranges} for a description of
the \LinkA{Ranges}{Ranges} API.

The Partitioning class is virtual with 2 concrete subclasses:
PartitioningByEnd (only stores the end of the groups, allowing fast
mapping from groups to objects), and PartitioningByWidth (only stores
the width of the groups).
\end{Section}
\begin{Section}{Binning subclass}
A Binning container represents a grouping where each observation is
assigned to a group or bin. It is similar in nature to taking a the
integer codes of a factor object and splitting it up by its levels
(i.e. myFactor <- factor(...); split(as.integer(myFactor), myFactor)).
\end{Section}
\begin{Section}{Constructors}
\describe{
\item[] \code{H2LGrouping(high2low=integer())}:
[DOCUMENT ME]

\item[] \code{Dups(high2low=integer())}:
[DOCUMENT ME]

\item[] \code{PartitioningByEnd(end=integer(), names=NULL)}:
Return the PartitioningByEnd object made of the partitions ending
at the values specified by \code{end}. \code{end} must contain
sorted non-negative integer values. If the \code{names} argument
is non NULL, it is used to name the partitions.

\item[] \code{PartitioningByWidth(width=integer(), names=NULL)}:
Return the PartitioningByWidth object made of the partitions with
the widths specified by \code{width}. \code{width} must contain
non-negative integer values. If the \code{names} argument
is non NULL, it is used to name the partitions.

\item[] \code{Binning(group=integer(), names=NULL)}:
Return the Binning object made from the \code{group} argument, which
takes a factor or positive valued integer vector. If the \code{names}
argument is non NULL, it is used to name the bins. When \code{group}
is a factor, the \code{names} are set to \code{levels(group)} unless
specified otherwise.

}
Note that these constructors don't recycle their \code{names} argument
(to remain consistent with what \code{`names<-`} does on standard
vectors).
\end{Section}
\begin{Author}\relax
H. Pages and P. Aboyoun
\end{Author}
\begin{SeeAlso}\relax
\LinkA{Sequence-class}{Sequence.Rdash.class},
\LinkA{Ranges-class}{Ranges.Rdash.class},
\LinkA{IRanges-class}{IRanges.Rdash.class},
\LinkA{successiveIRanges}{successiveIRanges},
\LinkA{cumsum}{cumsum},
\LinkA{diff}{diff}
\end{SeeAlso}
\begin{Examples}
\begin{ExampleCode}
  showClass("Grouping")  # shows (some of) the known subclasses

  ## ---------------------------------------------------------------------
  ## A. H2LGrouping OBJECTS
  ## ---------------------------------------------------------------------
  high2low <- c(NA, NA, 2, 2, NA, NA, NA, 6, NA, 1, 2, NA, 6, NA, NA, 2)
  x <- H2LGrouping(high2low)
  x

  ## The Grouping core API:
  length(x)
  nobj(x)  # same as 'length(x)' for H2LGrouping objects
  x[[1]]
  x[[2]]
  x[[3]]
  x[[4]]
  x[[5]]
  grouplength(x)  # same as 'unname(sapply(x, length))'
  grouplength(x, 5:2)
  members(x, 5:2)  # all the members are put together and sorted
  togroup(x)
  togroup(x, 5:2)
  togrouplength(x)  # same as 'grouplength(x, togroup(x))'
  togrouplength(x, 5:2)

  ## The Sequence API:
  as.list(x)
  sapply(x, length)

  ## ---------------------------------------------------------------------
  ## B. Dups OBJECTS
  ## ---------------------------------------------------------------------
  x_dups <- as(x, "Dups")
  x_dups
  duplicated(x_dups)  # same as 'duplicated(togroup(x_dups))'

  ### The purpose of a Dups object is to describe the groups of duplicated
  ### elements in a vector-like object:
  x <- c(2, 77, 4, 4, 7, 2, 8, 8, 4, 99)
  x_high2low <- high2low(x)
  x_high2low  # same length as 'x'
  x_dups <- Dups(x_high2low)
  x_dups
  togroup(x_dups)
  duplicated(x_dups)
  togrouplength(x_dups)  # frequency for each element
  table(x)

  ## ---------------------------------------------------------------------
  ## C. Partitioning OBJECTS
  ## ---------------------------------------------------------------------
  x <- PartitioningByEnd(end=c(4, 7, 7, 8, 15), names=LETTERS[1:5])
  x  # the 3rd partition is empty

  ## The Grouping core API:
  length(x)
  nobj(x)
  x[[1]]
  x[[2]]
  x[[3]]
  grouplength(x)  # same as 'unname(sapply(x, length))' and 'width(x)'
  togroup(x)
  togrouplength(x)  # same as 'grouplength(x, togroup(x))'
  names(x)

  ## The Ranges core API:
  start(x)
  end(x)
  width(x)

  ## The Sequence API:
  as.list(x)
  sapply(x, length)

  ## Replacing the names:
  names(x)[3] <- "empty partition"
  x

  ## Coercion to an IRanges object:
  as(x, "IRanges")

  ## Other examples:
  PartitioningByEnd(end=c(0, 0, 19), names=LETTERS[1:3])
  PartitioningByEnd()  # no partition
  PartitioningByEnd(end=integer(9))  # all partitions are empty

  ## ---------------------------------------------------------------------
  ## D. RELATIONSHIP BETWEEN Partitioning OBJECTS AND successiveIRanges()
  ## ---------------------------------------------------------------------
  mywidths <- c(4, 3, 0, 1, 7)

  ## The 3 following calls produce the same ranges:
  x1 <- successiveIRanges(mywidths)  # IRanges instance.
  x2 <- PartitioningByEnd(end=cumsum(mywidths))  # PartitioningByEnd instance.
  x3 <- PartitioningByWidth(width=mywidths)  # PartitioningByWidth instance.
  stopifnot(identical(as(x1, "PartitioningByEnd"), x2))
  stopifnot(identical(as(x1, "PartitioningByWidth"), x3))

  ## ---------------------------------------------------------------------
  ## E. Binning OBJECTS
  ## ---------------------------------------------------------------------
  set.seed(0)
  x <- Binning(factor(sample(letters, 36, replace=TRUE), levels=letters))
  x

  grouplength(x)
  togroup(x)
  x[[2]]
  x[["u"]]
\end{ExampleCode}
\end{Examples}

