[R-gregmisc-users] SF.net SVN: r-gregmisc: [979] trunk/gdata
Brought to you by:
warnes
|
From: <wa...@us...> - 2006-09-13 14:55:47
|
Revision: 979
http://svn.sourceforge.net/r-gregmisc/?rev=979&view=rev
Author: warnes
Date: 2006-09-13 07:55:37 -0700 (Wed, 13 Sep 2006)
Log Message:
-----------
Add mapLevels functions from Gregor Gorjanc, along with associated unit tests.
Modified Paths:
--------------
trunk/gdata/DESCRIPTION
trunk/gdata/NAMESPACE
Added Paths:
-----------
trunk/gdata/R/mapLevels.R
trunk/gdata/man/mapLevels.Rd
Removed Paths:
-------------
trunk/gdata/R/combineLevels.R
trunk/gdata/R/mapFactor.R
trunk/gdata/man/combineLevels.Rd
trunk/gdata/man/mapFactor.Rd
Modified: trunk/gdata/DESCRIPTION
===================================================================
--- trunk/gdata/DESCRIPTION 2006-08-03 22:26:30 UTC (rev 978)
+++ trunk/gdata/DESCRIPTION 2006-09-13 14:55:37 UTC (rev 979)
@@ -3,7 +3,7 @@
Description: Various R programming tools for data manipulation
Depends: R (>= 1.9.0)
Imports: gtools
-Version: 2.2.0
+Version: 2.3.0
Author: Gregory R. Warnes. Includes R source code and/or documentation
contributed by Ben Bolker, Gregor Gorjanc, and Thomas Lumley
Maintainer: Gregory Warnes <gre...@ur...>
Modified: trunk/gdata/NAMESPACE
===================================================================
--- trunk/gdata/NAMESPACE 2006-08-03 22:26:30 UTC (rev 978)
+++ trunk/gdata/NAMESPACE 2006-09-13 14:55:37 UTC (rev 979)
@@ -3,7 +3,6 @@
Args,
aggregate.table,
combine,
- combineLevels,
ConvertMedUnits,
drop.levels,
elem,
@@ -15,7 +14,6 @@
ll,
lowerTriangle,
"lowerTriangle<-",
- mapFactor,
matchcols,
nobs,
read.xls,
@@ -26,7 +24,16 @@
trim,
unmatrix,
upperTriangle,
- "upperTriangle<-"
+ "upperTriangle<-",
+
+ ## mapLevels stuff
+ mapLevels,
+ as.levelsMap,
+ as.listLevelsMap,
+ is.levelsMap,
+ is.listLevelsMap,
+ sort.levelsMap, ## remove in R 2.4
+ "mapLevels<-"
)
importFrom(stats, reorder, na.omit)
@@ -46,3 +53,25 @@
S3method(drop.levels, factor)
S3method(drop.levels, list)
S3method(drop.levels, data.frame)
+
+S3method(mapLevels, default)
+S3method(mapLevels, character)
+S3method(mapLevels, factor)
+S3method(mapLevels, list)
+S3method(mapLevels, data.frame)
+
+S3method(print, levelsMap)
+S3method(print, listLevelsMap)
+
+S3method("[", levelsMap)
+S3method("[", listLevelsMap)
+
+S3method(c, levelsMap)
+S3method(c, listLevelsMap)
+
+S3method(unique, levelsMap)
+## S3method(sort, levelsMap) ## uncomment in R 2.4
+
+S3method("mapLevels<-", default)
+S3method("mapLevels<-", list)
+S3method("mapLevels<-", data.frame)
Deleted: trunk/gdata/R/combineLevels.R
===================================================================
--- trunk/gdata/R/combineLevels.R 2006-08-03 22:26:30 UTC (rev 978)
+++ trunk/gdata/R/combineLevels.R 2006-09-13 14:55:37 UTC (rev 979)
@@ -1,26 +0,0 @@
-## combineLevels.R
-###------------------------------------------------------------------------
-## What: Joint levels of given factors
-## $Id: combineLevels.R,v 1.1 2006/04/08 01:58:36 ggorjan Exp $
-## Time-stamp: <2006-04-08 03:57:53 ggorjan>
-###------------------------------------------------------------------------
-
-combineLevels <- function(x, apply=TRUE, drop=FALSE)
-{
- if (!is.factor(x)) {
- if (sum(!(c("data.frame", "list") %in% class(x))) == 2)
- stop(paste(sQuote("x"), "must be a", dQuote("data.frame"), "or a", dQuote("list")))
- if (any(!(unlist((lapply(x, is.factor))))))
- stop(paste("only", dQuote("factors"), "are supported"))
- if (drop) x <- lapply(x, factor)
- levs <- sort(unique(unlist(lapply(x, levels))))
- if (!apply) return(levs)
- return(lapply(x, "levels<-", mapFactor(levs, codes=FALSE)))
- }
- if (drop) x <- factor(x)
- if (!apply) return(levels(x))
- return(x)
-}
-
-###------------------------------------------------------------------------
-## combineLevels.R ends here
Deleted: trunk/gdata/R/mapFactor.R
===================================================================
--- trunk/gdata/R/mapFactor.R 2006-08-03 22:26:30 UTC (rev 978)
+++ trunk/gdata/R/mapFactor.R 2006-09-13 14:55:37 UTC (rev 979)
@@ -1,38 +0,0 @@
-## mapFactor.R
-###------------------------------------------------------------------------
-## What: Get a map of levels in a factor
-## $Id: mapFactor.R,v 1.1 2006/03/29 13:47:15 ggorjan Exp ggorjan $
-## Time-stamp: <2006-04-06 01:35:30 ggorjan>
-###------------------------------------------------------------------------
-
-mapFactor <- function(x, codes=TRUE, sort=TRUE, drop=FALSE, ...)
-{
- ## --- Check ---
- msg <- "x must be a factor or character"
- if (!is.factor(x)) {
- if (!is.character(x)) stop(msg)
- }
-
- ## --- Create a map ---
- if (is.factor(x)) { # factor
- if (drop) x <- factor(x)
- nlevs <- nlevels(x)
- levs <- levels(x)
- if (sort) levs <- sort(levs, ...)
- } else { # character
- levs <- unique(x)
- if (sort) levs <- sort(levs, ...)
- nlevs <- length(levs)
- }
- tmp <- vector("list", nlevs)
- names(tmp) <- levs
- if (codes) {
- tmp[1:nlevs] <- 1:nlevs
- } else {
- tmp[1:nlevs] <- levs
- }
- return(tmp)
-}
-
-###------------------------------------------------------------------------
-## mapFactor.R ends here
Added: trunk/gdata/R/mapLevels.R
===================================================================
--- trunk/gdata/R/mapLevels.R (rev 0)
+++ trunk/gdata/R/mapLevels.R 2006-09-13 14:55:37 UTC (rev 979)
@@ -0,0 +1,359 @@
+### mapLevels.R
+###------------------------------------------------------------------------
+### What: Mapping levels
+### $Id: mapLevels.R,v 1.1 2006/03/29 13:47:15 ggorjan Exp ggorjan $
+### Time-stamp: <2006-08-31 02:24:45 ggorjan>
+###------------------------------------------------------------------------
+
+### {{{ mapLevels
+
+###------------------------------------------------------------------------
+
+mapLevels <- function(x, codes=TRUE, sort=TRUE, drop=FALSE,
+ combine=FALSE, ...)
+{
+ UseMethod("mapLevels")
+}
+
+mapLevels.default <- function(x, codes=TRUE, sort=TRUE, drop=FALSE,
+ combine=FALSE, ...)
+{
+ stop(sprintf("mapLevels can only be used on %s and %s atomic 'x'",
+ dQuote("factor"), dQuote("character")))
+}
+
+mapLevels.character <- function(x, codes=TRUE, sort=TRUE, drop=FALSE,
+ combine=FALSE, ...)
+{
+ return(mapLevels.factor(x=x, codes=codes, sort=sort, drop=drop, ...))
+}
+
+## Could coerce character to factor and then use factor method, but that
+## is more expensive than simple unique and length used bellow in factor
+## method
+
+mapLevels.factor <- function(x, codes=TRUE, sort=TRUE, drop=FALSE,
+ combine=FALSE, ...)
+{
+ ## --- Argument actions ----
+
+ if(is.factor(x)) { # factor
+ if(drop) x <- factor(x)
+ nlevs <- nlevels(x)
+ levs <- levels(x)
+ } else { # character
+ levs <- unique(x)
+ nlevs <- length(levs)
+ if(sort) levs <- sort(levs, ...)
+ }
+
+ ## --- Create a map ---
+
+ map <- vector(mode="list", length=nlevs)
+ names(map) <- levs
+ if(codes) {
+ map[1:nlevs] <- 1:nlevs
+ } else {
+ map[1:nlevs] <- levs
+ }
+ class(map) <- "levelsMap"
+ return(map)
+}
+
+mapLevels.list <- function(x, codes=TRUE, sort=TRUE, drop=FALSE,
+ combine=FALSE, ...)
+{
+ map <- lapply(x, mapLevels, codes=codes, sort=sort, drop=drop, ...)
+ class(map) <- "listLevelsMap"
+ if(combine) {
+ if(!codes) {
+ return(c(map, sort=sort, recursive=TRUE))
+ } else {
+ stop(sprintf("can not combine integer %s", dQuote("levelsMaps")))
+ }
+ }
+ return(map)
+}
+
+mapLevels.data.frame <- function(x, codes=TRUE, sort=TRUE, drop=FALSE,
+ combine=FALSE, ...)
+{
+ return(mapLevels.list(x, codes=codes, sort=sort, drop=drop,
+ combine=combine, ...))
+}
+
+### }}}
+### {{{ print.*
+###------------------------------------------------------------------------
+
+.unlistLevelsMap <- function(x, ind=FALSE)
+{
+ y <- unlist(x, use.names=FALSE)
+ length <- sapply(x, FUN=length)
+ names(y) <- rep(names(x), times=length)
+ if(ind) {
+ return(list(y, rep(1:length(x), times=length), length))
+ } else {
+ return(y)
+ }
+}
+
+print.levelsMap <- function(x, ...)
+{
+ x <- gdata:::.unlistLevelsMap(x)
+ print(x, ...)
+}
+
+print.listLevelsMap <- function(x, ...)
+{
+ class(x) <- "list"
+ print(x, ...)
+}
+
+### }}}
+### {{{ [.*
+###------------------------------------------------------------------------
+
+## We need these two since [.list method drops class
+
+"[.levelsMap" <- function(x, i)
+{
+ classX <- class(x)
+ class(x) <- "list"
+ x <- x[i]
+ class(x) <- classX
+ return(x)
+}
+
+"[.listLevelsMap" <- function(x, i)
+{
+ classX <- class(x)
+ class(x) <- "list"
+ x <- x[i]
+ class(x) <- classX
+ return(x)
+}
+
+### }}}
+### {{{ is.*
+###------------------------------------------------------------------------
+
+is.levelsMap <- function(x)
+ inherits(x=x, what="levelsMap")
+
+is.listLevelsMap <- function(x)
+ inherits(x=x, what="listLevelsMap")
+
+.isCharacterMap <- function(x)
+{
+ if(is(x) == "levelsMap") {
+ return(inherits(x=unlist(x), what="character"))
+ } else {
+ stop(sprintf("can be used only on %s", dQuote("levelsMap")))
+ }
+}
+
+### }}}
+### {{{ as.*
+###------------------------------------------------------------------------
+
+as.levelsMap <- function(x, check=TRUE, ...)
+{
+ if(check)
+ gdata:::.checkLevelsMap(x, method="raw")
+ class(x) <- "levelsMap"
+ return(unique(x, ...))
+}
+
+as.listLevelsMap <- function(x, check=TRUE)
+{
+ if(check)
+ gdata:::.checkListLevelsMap(x, method="raw")
+ class(x) <- "listLevelsMap"
+ return(x)
+}
+
+### }}}
+### {{{ .check*
+###------------------------------------------------------------------------
+
+.checkLevelsMap <- function(x, method) {
+ xLab <- deparse(substitute(x))
+ also <- "\b"
+ if(method == "class") {
+ also <- "also"
+ if(!is.levelsMap(x))
+ stop(sprintf("'%s' must be a %s", xLab, dQuote("levelsMap")))
+ }
+ if(!is.list(x) || is.null(names(x)))
+ stop(sprintf("'%s' must be %s a named list", xLab, also))
+
+ ## Components can be of different length
+ ## if(!all(sapply(x, FUN=length) == 1))
+ ## stop(sprintf("all components of '%s' must have length 1", xLab))
+}
+
+.checkListLevelsMap <- function(x, method) {
+ xLab <- deparse(substitute(x))
+ also <- "\b"
+ if(method == "class") {
+ also <- "also"
+ if(!is.listLevelsMap(x))
+ stop(sprintf("'%s' must be a %s", xLab, dQuote("listLevelsMap")))
+ }
+ if(!is.list(x) || any(!sapply(x, FUN=is.levelsMap)))
+ stop(sprintf("'%s' must be %s a list of %s", xLab, also,
+ dQuote("levelsMap")))
+ lapply(x, FUN=gdata:::.checkLevelsMap, method=method)
+}
+
+### }}}
+### {{{ c.*
+###------------------------------------------------------------------------
+
+c.levelsMap <- function(..., sort=TRUE, recursive=FALSE)
+{
+ x <- list(...)
+ class(x) <- "listLevelsMap"
+ return(c(x, sort=sort, recursive=TRUE))
+}
+
+c.listLevelsMap <- function(..., sort=TRUE, recursive=FALSE)
+{
+ x <- list(...)
+ lapply(x, FUN=gdata:::.checkListLevelsMap, method="class")
+ x <- unlist(x, recursive=FALSE)
+ if(!recursive) {
+ class(x) <- "listLevelsMap"
+ } else {
+ if(any(!sapply(x, FUN=gdata:::.isCharacterMap)))
+ stop(sprintf("can not combine integer %s", dQuote("levelsMaps")))
+ if(!is.null(names(x))) names(x) <- NULL
+ x <- unlist(x, recursive=FALSE)
+ ## how to merge components with the same name?
+ class(x) <- "levelsMap"
+ if(sort) x <- sort.levelsMap(x)
+ x <- unique(x)
+ }
+ return(x)
+}
+
+### }}}
+### {{{ sort
+###------------------------------------------------------------------------
+
+sort.levelsMap <- function(x, decreasing=FALSE, na.last=TRUE, ...)
+ return(x[order(names(x), na.last=na.last, decreasing=decreasing)])
+
+### }}}
+### {{{ unique
+###------------------------------------------------------------------------
+
+unique.levelsMap <- function(x, incomparables=FALSE, ...)
+{
+ ## Find duplicates
+ y <- gdata:::.unlistLevelsMap(x, ind=TRUE)
+ ## Duplicates for values and names combinations
+ test <- duplicated(cbind(y[[1]], names(y[[1]])),
+ incomparables=incomparables, ...)
+ if(any(test)) {
+ if(any(y[[3]] > 1)) { # work with the same structure as in x
+ j <- 1
+ k <- y[[3]][1]
+ empty <- NULL
+ for(i in seq(along=x)) { # how slow is this loop?
+ tmp <- !test[j:k]
+ if(all(!tmp)) { # these components will be empty
+ empty <- c(empty, i)
+ } else {
+ x[[i]] <- x[[i]][tmp]
+ }
+ j <- j + y[[3]][i]
+ k <- k + y[[3]][i + 1]
+ }
+ if(!is.null(empty))
+ x[empty] <- NULL
+ } else { # simple one-length components
+ x <- x[!test]
+ }
+ }
+ return(x)
+}
+
+### }}}
+### {{{ mapLevels<-
+###------------------------------------------------------------------------
+
+"mapLevels<-" <- function(x, value)
+ UseMethod("mapLevels<-")
+
+"mapLevels<-.default" <- function(x, value)
+{
+ ## --- Checks ---
+
+ classX <- c("integer", "character", "factor")
+ if(any(!(class(x) %in% classX)))
+ stop(sprintf("'x' must be either: %s", paste(dQuote(classX), collapse=", ")))
+
+ gdata:::.checkLevelsMap(x=value, method="class")
+
+ ## --- Mapping levels in x ---
+
+ char <- all(lapply(value, is.character))
+ int <- all(lapply(value, is.integer))
+
+ if(int) { # codes=TRUE
+ if(is.integer(x)) x <- factor(x)
+ if(is.factor(x)) levels(x) <- value
+ if(is.character(x))
+ stop(sprintf("can not apply integer %s to %s",
+ dQuote("levelsMap"), dQuote("character")))
+ } else { # codes=FALSE
+ if(!char)
+ stop("all components of 'value' must be of the same class")
+ if(is.character(x)) x <- factor(x)
+ if(is.factor(x)) levels(x) <- value
+ if(is.integer(x))
+ stop(sprintf("can not apply character %s to %s",
+ dQuote("levelsMap"), dQuote("integer")))
+ }
+
+ return(x)
+}
+
+"mapLevels<-.list" <- function(x, value)
+{
+ if(!is.listLevelsMap(value)) {
+ if(is.levelsMap(value)) {
+ value <- as.listLevelsMap(list(value), check=FALSE)
+ ## no need for check as default method does checking anyway
+ } else {
+ stop(sprintf("'x' must be either %s or %s",
+ dQuote("listLevelsMap"), dQuote("levelsMap")))
+ }
+ }
+ ## FIXME: mapply drops names
+ if(!is.null(names(x))) {
+ isNamed <- TRUE
+ namesX <- names(x)
+ }
+ x <- mapply(FUN="mapLevels<-", x=x, value=value, SIMPLIFY=FALSE)
+ if(isNamed) names(x) <- namesX
+ return(x)
+}
+
+"mapLevels<-.data.frame" <- function(x, value)
+{
+ x[] <- "mapLevels<-.list"(x, value)
+ return(x)
+}
+
+### }}}
+### {{{ Dear Emacs
+## Local variables:
+## folded-file: t
+## End:
+### }}}
+
+###------------------------------------------------------------------------
+### mapLevels.R ends here
Deleted: trunk/gdata/man/combineLevels.Rd
===================================================================
--- trunk/gdata/man/combineLevels.Rd 2006-08-03 22:26:30 UTC (rev 978)
+++ trunk/gdata/man/combineLevels.Rd 2006-09-13 14:55:37 UTC (rev 979)
@@ -1,61 +0,0 @@
-% combineLevels.Rd
-%--------------------------------------------------------------------------
-% What: Combine levels of given factors
-% $Id: combineLevels.Rd,v 1.1 2006/03/29 13:47:10 ggorjan Exp ggorjan $
-% Time-stamp: <2006-06-27 09:30:42 ggorjan>
-%--------------------------------------------------------------------------
-
-\name{combineLevels}
-
-\alias{combineLevels}
-
-\title{Combine levels of given factors}
-
-\description{
-\code{combineLevels} combines levels of given factors and applies this
-levels to given factors. This eases the work with factors since all
-factors have the same levels.
-}
-
-\usage{
-combineLevels(x, apply=TRUE, drop=FALSE)
-}
-
-\arguments{
- \item{x}{data.frame or list, object with factors}
- \item{apply}{boolean, apply combined levels to \code{x} or just return
- combined levels}
- \item{drop}{boolean, drop unused levels}
-}
-
-\value{\code{apply} handles the output. If \code{apply=TRUE} the output
- is a modified \code{x}, where all factors have the same set of
- levels. If \code{apply=FALSE} only combined levels are returned.
-}
-
-\author{Gregor Gorjanc}
-
-\seealso{
- \code{\link{factor}}, \code{\link{levels}}, \code{\link[ggmisc]{mapFactor}}
-}
-
-\examples{
-
-(f1 <- factor(letters[1:5]))
-(f2 <- factor(letters[3:10]))
-tmp <- list(f1, f2)
-combineLevels(tmp)
-combineLevels(tmp, apply=FALSE)
-
-f1[2] <- NA
-f1 <- factor(f1)
-tmp <- list(f1, f2)
-combineLevels(tmp, apply=FALSE, drop=TRUE)
-
-}
-
-\keyword{misc}
-\keyword{manip}
-
-%--------------------------------------------------------------------------
-% combineLevels.Rd ends here
Deleted: trunk/gdata/man/mapFactor.Rd
===================================================================
--- trunk/gdata/man/mapFactor.Rd 2006-08-03 22:26:30 UTC (rev 978)
+++ trunk/gdata/man/mapFactor.Rd 2006-09-13 14:55:37 UTC (rev 979)
@@ -1,81 +0,0 @@
-% mapFactor.Rd
-%--------------------------------------------------------------------------
-% What: Get a map of levels in a factor man page
-% $Id: mapFactor.Rd,v 1.1 2006/03/29 13:47:10 ggorjan Exp ggorjan $
-% Time-stamp: <2006-06-27 09:31:03 ggorjan>
-%--------------------------------------------------------------------------
-
-\name{mapFactor}
-
-\alias{mapFactor}
-
-\title{Get a map of levels in a factor}
-
-\description{
-\code{mapFactor} produces a list with information on levels and internal
-integer codes. As such can be conveniently used to store factor map when
-one needs to work with internal codes of a factor and later transfrorm
-back to factor.
-}
-
-\usage{
-mapFactor(x, codes=TRUE, sort=TRUE, drop=FALSE, ...)
-}
-
-\arguments{
- \item{x}{factor, the object to be mapped}
- \item{codes}{boolean, create map with internal codes or with
- levels, look into value and examples}
- \item{sort}{boolean, sort levels for a character, look into details}
- \item{drop}{boolean, drop unused levels of a factor}
- \item{...}{additional arguments for \code{sort}}
-}
-
-\details{
- \code{sort} and \code{...} arguments provides possibility to "order"
- levels and can only be used for characters and not for factors.
-}
-
-\value{A list with names equal to levels and entries equal to internal
-codes, when \code{codes=TRUE}, or entries equal to levels
-otherwise. The later case is usefull, when one would like to combine
-two factors with different levels.
-}
-
-\author{Gregor Gorjanc}
-
-\seealso{
- \code{\link{factor}}, \code{\link{levels}}, \code{\link{unclass}},
- \code{\link{attributes}}
-}
-
-\examples{
-
-## Example with codes=TRUE
-(f <- factor(letters[c(1, 1, 2, 3, 4, 5, 7, 8, 9, 8, 8, 10)]))
-map <- mapFactor(f)
-int <- as.integer(f)
-fNew <- factor(int)
-levels(fNew) <- map
-fNew
-
-## Example with codes=FALSE
-f1 <- factor(f[1:5])
-f2 <- factor(f[5:length(f)])
-map1 <- mapFactor(f1, codes=FALSE)
-map2 <- mapFactor(f2, codes=FALSE)
-map <- c(map1, map2)
-levels(f1) <- map
-levels(f2) <- map
-as.integer(f1)
-as.integer(f2)
-
-## x <- unique(map)
-## names(x) <- unlist(x)
-}
-
-\keyword{misc}
-\keyword{manip}
-
-%--------------------------------------------------------------------------
-% mapFactor.Rd ends here
Added: trunk/gdata/man/mapLevels.Rd
===================================================================
--- trunk/gdata/man/mapLevels.Rd (rev 0)
+++ trunk/gdata/man/mapLevels.Rd 2006-09-13 14:55:37 UTC (rev 979)
@@ -0,0 +1,221 @@
+% mapLevels.Rd
+%--------------------------------------------------------------------------
+% What: Mapping levels
+% $Id: mapLevels.Rd,v 1.1 2006/03/29 13:47:10 ggorjan Exp ggorjan $
+% Time-stamp: <2006-08-31 02:43:29 ggorjan>
+%--------------------------------------------------------------------------
+
+\name{mapLevels}
+
+\alias{mapLevels}
+\alias{mapLevels.default}
+\alias{mapLevels.factor}
+\alias{mapLevels.character}
+\alias{mapLevels.list}
+\alias{mapLevels.data.frame}
+
+\alias{print.levelsMap}
+\alias{print.listLevelsMap}
+
+\alias{is.levelsMap}
+\alias{is.listLevelsMap}
+
+\alias{as.levelsMap}
+\alias{as.listLevelsMap}
+
+\alias{.checkLevelsMap}
+\alias{.checkListLevelsMap}
+
+\alias{"[.levelsMap"}
+\alias{"[.listLevelsMap"}
+
+\alias{c.levelsMap}
+\alias{c.listLevelsMap}
+
+\alias{unique.levelsMap}
+\alias{sort.levelsMap}
+
+\alias{mapLevels<-}
+\alias{mapLevels<-.default}
+\alias{mapLevels<-.factor}
+\alias{mapLevels<-.character}
+\alias{mapLevels<-.list}
+\alias{mapLevels<-.data.frame}
+
+\title{Mapping levels}
+
+\description{
+
+\code{mapLevels} produces a map with information on levels and/or
+internal integer codes. As such can be conveniently used to store level
+mapping when one needs to work with internal codes of a factor and later
+transfrorm back to factor or when working with several factors that
+should have the same levels and therefore the same internal coding.
+
+}
+
+\usage{
+
+mapLevels(x, codes=TRUE, sort=TRUE, drop=FALSE, combine=FALSE, \ldots)
+mapLevels(x) <- value
+
+}
+
+\arguments{
+ \item{x}{object whose levels will be mapped, look into details}
+ \item{codes}{boolean, create integer levelsMap (with internal
+ codes) or character levelsMap (with level names)}
+ \item{sort}{boolean, sort levels of character \code{x}, look into
+ details}
+ \item{drop}{boolean, drop unused levels}
+ \item{combine}{boolean, combine levels, look into details}
+ \item{\ldots}{additional arguments for \code{sort}}
+ \item{value}{levelsMap or listLevelsMap, output of \code{mapLevels}
+ methods or constructed by user, look into details}
+}
+
+\section{mapLevels}{
+
+\code{mapLevels} function was written primarly for work with
+\dQuote{factors}, but is generic and can also be used with
+\dQuote{character}, \dQuote{list} and \dQuote{data.frame}, while
+\dQuote{default} method produces error. Here the term levels is also
+used for unique character values.
+
+When \code{codes=TRUE} \bold{integer \dQuote{levelsMap}} with
+information on mapping internal codes with levels is produced. Output
+can be used to transform integer to factor or remap factor levels as
+described bellow. With \code{codes=FALSE} \bold{character
+\dQuote{levelsMap}} is produced. The later is usefull, when one would
+like to remap factors or combine factors with some overlap in levels as
+described in \code{mapLevels<-} section and shown in examples.
+
+\code{sort} argument provides possibility to sort levels of
+\dQuote{character} \code{x} and has no effect when \code{x} is a
+\dQuote{factor}.
+
+Argument \code{combine} has effect only in \dQuote{list} and
+\dQuote{data.frame} methods and when \code{codes=FALSE} i.e. with
+\bold{character \dQuote{levelsMaps}}. The later condition is necesarry
+as it is not possible to combine maps with different mapping of level
+names and integer codes. It is assumed that passed \dQuote{list} and
+\dQuote{data.frame} have all components for which methods
+exist. Otherwise error is produced.
+
+}
+
+\section{levelsMap and listLevelsMap}{
+
+Function \code{mapLevels} returns a map of levels. This map is of class
+\dQuote{levelsMap}, which is actually a list of length equal to number
+of levels and with each component of length 1. Components need not be of
+length 1. There can be either integer or character
+\dQuote{levelsMap}. \bold{Integer \dQuote{levelsMap}} (when
+\code{codes=TRUE}) has names equal to levels and components equal to
+internal codes. \bold{Character \dQuote{levelsMap}} (when
+\code{codes=FALSE}) has names and components equal to levels. When
+\code{mapLevels} is applied to \dQuote{list} or \dQuote{data.frame},
+result is of class \dQuote{listLevelsMap}, which is a list of
+\dQuote{levelsMap} components described previously. If
+\code{combine=TRUE}, result is a \dQuote{levelsMap} with all levels in
+\code{x} components.
+
+For ease of inspection, print methods unlists \dQuote{levelsMap} with
+proper names. \code{mapLevels<-} methods are fairly general and
+therefore additional convenience methods are implemented to ease the
+work with maps: \code{is.levelsMap} and \code{is.listLevelsMap};
+\code{as.levelsMap} and \code{as.listLevelsMap} for coercion of user
+defined maps; generic \code{"["} and \code{c} for both classes (argument
+\code{recursive} can be used in \code{c} to coerce
+\dQuote{listLevelsMap} to \dQuote{levelsMap}) and generic \code{unique}
+and \code{sort} (generic from \R 2.4) for \dQuote{levelsMap}.
+
+}
+
+\section{mapLevels<-}{
+
+Workhorse under \code{mapLevels<-} methods is
+\code{\link{levels<-}}. \code{mapLevels<-} just control the assignment
+of \dQuote{levelsMap} (integer or character) or \dQuote{listLevelsMap}
+to \code{x}. The idea is that map values are changed to map names as
+indicated in \code{\link{levels}} examples. \bold{Integer
+\dQuote{levelsMap}} can be applied to \dQuote{integer} or
+\dQuote{factor}, while \bold{character \dQuote{levelsMap}} can be
+applied to \dQuote{character} or \dQuote{factor}. Methods for
+\dQuote{list} and \dQuote{data.frame} can work only on mentioned atomic
+components/columns and can accept either \dQuote{levelsMap} or
+\dQuote{levelsMap}. Recycling occours, if length of \code{value} is not
+the same as number of components/columns of a \dQuote{list/data.frame}.
+}
+
+\value{
+
+\code{mapLevels()} returns \dQuote{levelsMap} or \dQuote{listLevelsMap}
+objects as described in levelsMap and listLevelsMap section.
+
+Result of \code{mapLevels<-} is always a factor with remapped levels or
+a \dQuote{list/data.frame} with remapped factors.
+
+}
+
+\author{Gregor Gorjanc}
+
+\seealso{
+ \code{\link{factor}}, \code{\link{levels}} and \code{\link{unclass}}
+}
+
+\examples{
+
+## --- Integer levelsMap ---
+
+(f <- factor(sample(letters, size=20, replace=TRUE)))
+(mapInt <- mapLevels(f))
+
+## Integer to factor
+(int <- as.integer(f))
+(mapLevels(int) <- mapInt)
+all.equal(int, f)
+
+## Remap levels of a factor
+(fac <- factor(as.integer(f)))
+(mapLevels(fac) <- mapInt) # the same as levels(fac) <- mapInt
+all.equal(fac, f)
+
+## --- Character levelesMap ---
+
+f1 <- factor(letters[1:10])
+f2 <- factor(letters[5:14])
+
+## Internal codes are the same, but levels are not
+as.integer(f1)
+as.integer(f2)
+
+## Get character levelsMaps and combine them
+mapCha1 <- mapLevels(f1, codes=FALSE)
+mapCha2 <- mapLevels(f2, codes=FALSE)
+(mapCha <- c(mapCha1, mapCha2))
+
+## Remap factors
+mapLevels(f1) <- mapCha # the same as levels(f1) <- mapCha
+mapLevels(f2) <- mapCha # the same as levels(f2) <- mapCha
+
+## Internal codes are now "consistent" among factors
+as.integer(f1)
+as.integer(f2)
+
+## Remap characters to get factors
+f1 <- as.character(f1); f2 <- as.character(f2)
+mapLevels(f1) <- mapCha
+mapLevels(f2) <- mapCha
+
+## Internal codes are now "consistent" among factors
+as.integer(f1)
+as.integer(f2)
+
+}
+
+\keyword{misc}
+\keyword{manip}
+
+%--------------------------------------------------------------------------
+% mapLevels.Rd ends here
This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.
|