Rev 42961 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
% File src/library/stats/man/reshape.Rd% Part of the R package, http://www.R-project.org% Copyright 1995-2007 R Core Development Team% Distributed under GPL 2 or later\name{reshape}\alias{reshape}\title{Reshape Grouped Data}\description{This function reshapes a data frame between \sQuote{wide} format withrepeated measurements in separate columns of the same record and\sQuote{long} format with the repeated measurements in separaterecords.}\usage{reshape(data, varying = NULL, v.names = NULL, timevar = "time",idvar = "id", ids = 1:NROW(data),times = seq_along(varying[[1]]),drop = NULL, direction, new.row.names = NULL,sep = ".",split = if (sep==""){list(regexp="[A-Za-z][0-9]",include=TRUE)} else {list(regexp=sep, include= FALSE, fixed=TRUE)})}\arguments{\item{data}{a data frame}\item{varying}{names of sets of variables in the wide format thatcorrespond to single variables in long format(\sQuote{time-varying}). This is canonically a list of vectors ofvariable names, but it can optionally be a matrix of names, or asingle vector of names. In each case, the names can be replaced byindexes which are interpreted as referring to \code{names(data)}.See below for more details andoptions.}\item{v.names}{names of variables in the long format that correspondto multiple variables in the wide format. See below for details.}\item{timevar}{the variable in long format that differentiates multiplerecords from the same group or individual.}\item{idvar}{Names of one or more variables in long format that identify multiplerecords from the same group/individual. These variables may also bepresent in wide format}\item{ids}{the values to use for a newly created \code{idvar}variable in long format.}\item{times}{the values to use for a newly created \code{timevar}variable in long format. See below for details.}\item{drop}{a vector of names of variables to drop before reshaping}\item{direction}{character string, either \code{"wide"} to reshape towide format, or \code{"long"} to reshape to long format.}\item{new.row.names}{logical; if \code{TRUE} and \code{direction="wide"},create new row names in long format from the values of the id andtime variables.}\item{sep} {A character vector of length 1, indicating a separatingcharacter in the variable names in the wide format. This is used forguessing \code{v.names} and \code{times} arguments based on thenames in \code{varying}. If \code{sep==""}, the split is just beforethe first numeral that follows an alphabetic character.}\item{split}{A list with three components, \code{regexp},\code{include}, and (optionally) \code{fixed}. This allows anextended interface to variable name splitting. See below for details.}}\details{The arguments to this function are described in terms of longitudinaldata, as that is the application motivating the functions. A \sQuote{wide}longitudinal dataset will have one record for each individual withsome time-constant variables that occupy single columns and sometime-varying variables that occupy a column for each time point. In\sQuote{long} format there will be multiple records for each individual, withsome variables being constant across these records and others varyingacross the records. A \sQuote{long} format dataset also needs a \sQuote{time}variable identifying which time point each record comes from and an\sQuote{id} variable showing which records refer to the same person.If the data frame resulted from a previous \code{reshape} then theoperation can be reversed simply by \code{reshape(a)}. The\code{direction} argument is optional and the other arguments arestored as attributes on the data frame.If \code{direction="wide"} and no \code{varying} or \code{v.names}arguments are supplied it is assumed that all variables except\code{idvar} and \code{timevar} are time-varying. They are allexpanded into multiple variables in wide format.If \code{direction="long"} the \code{varying} argument can be a vectorof column names (or a corresponding index). The function will attemptto guess the \code{v.names} and \code{times} from these names. Thedefault is variable names like \code{x.1}, \code{x.2}, where\code{sep="."} specifies to split at the dot and drop it from thename. To have alphabetic followed by numeric times use \code{sep=""}.Variable name splitting as described above is only attempted in thecase where \code{varying} is an atomic vector, if it is a list or amatrix, \code{v.names} and \code{times} will generally need to bespecified, although they will default to, respectively, the firstvariable name in each set, and sequential times.Also, guessing is not attempted if \code{v.names} is givenexplicitly. Notice that the order of variables in \code{varying} islike \code{x.1},\code{y.1},\code{x.2},\code{y.2}.The \code{split} argument should not usually be necessary. The\code{split$regexp} component is passed to either \code{strsplit()} or\code{regexp()}, where the latter is used if \code{split$include} is\code{TRUE}, in which case the splitting occurs after the firstcharacter of the matched string. In the \code{strsplit()} case, theseparator is not included in the result, and it is possible to specifyfixed-string matching using \code{split$fixed}.}\value{The reshaped data frame with added attributes to simplify reshapingback to the original form.}\seealso{\code{\link{stack}}, \code{\link{aperm}};\code{\link[utils]{relist}} for reshaping the result of \code{\link{unlist}}.}\examples{summary(Indometh)wide <- reshape(Indometh, v.names="conc", idvar="Subject",timevar="time", direction="wide")widereshape(wide, direction="long")reshape(wide, idvar="Subject", varying=list(2:12),v.names="conc", direction="long")## times need not be numericdf <- data.frame(id=rep(1:4,rep(2,4)),visit=I(rep(c("Before","After"),4)),x=rnorm(4), y=runif(4))dfreshape(df, timevar="visit", idvar="id", direction="wide")## warns that y is really varyingreshape(df, timevar="visit", idvar="id", direction="wide", v.names="x")## unbalanced 'long' data leads to NA fill in 'wide' formdf2 <- df[1:7,]df2reshape(df2, timevar="visit", idvar="id", direction="wide")## Alternative regular expressions for guessing namesdf3 <- data.frame(id=1:4, age=c(40,50,60,50), dose1=c(1,2,1,2),dose2=c(2,1,2,1), dose4=c(3,3,3,3))reshape(df3, direction="long", varying=3:5, sep="")## an example that isn't longitudinal datastate.x77 <- as.data.frame(state.x77)long <- reshape(state.x77, idvar="state", ids=row.names(state.x77),times=names(state.x77), timevar="Characteristic",varying=list(names(state.x77)), direction="long")reshape(long, direction="wide")reshape(long, direction="wide", new.row.names=unique(long$state))## multiple id variablesdf3 <- data.frame(school=rep(1:3,each=4), class=rep(9:10,6),time=rep(c(1,1,2,2),3),score=rnorm(12))wide <- reshape(df3, idvar=c("school","class"), direction="wide")wide## transform backreshape(wide)}\keyword{manip}