# R: Reshape Grouped Data

reshape {stats} | R Documentation

## Reshape Grouped Data

### Description

This function reshapes a data frame between ‘wide’ format with repeated measurements in separate columns of the same record and ‘long’ format with the repeated measurements in separate records.

### 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

`data` | a data frame
`varying` | names of sets of variables in the wide format that correspond to single variables in long format (‘time-varying’). This is canonically a list of vectors of variable names, but it can optionally be a matrix of names, or a single vector of names. In each case, the names can be replaced by indexes which are interpreted as referring to `names(data)`. See below for more details and options.
`v.names` | names of variables in the long format that correspond to multiple variables in the wide format. See below for details.
`timevar` | the variable in long format that differentiates multiple records from the same group or individual.
`idvar` | Names of one or more variables in long format that identify multiple records from the same group/individual. These variables may also be present in wide format
`ids` | the values to use for a newly created `idvar` variable in long format.
`times` | the values to use for a newly created `timevar` variable in long format. See below for details.
`drop` | a vector of names of variables to drop before reshaping
`direction` | character string, either `"wide"` to reshape to wide format, or `"long"` to reshape to long format.
`new.row.names` | logical; if `TRUE` and `direction="wide"`, create new row names in long format from the values of the id and time variables.
`sep` |
`split` | A list with three components, `regexp`, `include`, and (optionally) `fixed`. This allows an extended interface to variable name splitting. See below for details.

### Details

The arguments to this function are described in terms of longitudinal data, as that is the application motivating the functions. A ‘wide’ longitudinal dataset will have one record for each individual with some time-constant variables that occupy single columns and some time-varying variables that occupy a column for each time point. In ‘long’ format there will be multiple records for each individual, with some variables being constant across these records and others varying across the records. A ‘long’ format dataset also needs a ‘time’ variable identifying which time point each record comes from and an ‘id’ variable showing which records refer to the same person.

If the data frame resulted from a previous `reshape` then the operation can be reversed simply by `reshape(a)`. The `direction` argument is optional and the other arguments are stored as attributes on the data frame.

If `direction="wide"` and no `varying` or `v.names` arguments are supplied it is assumed that all variables except `idvar` and `timevar` are time-varying. They are all expanded into multiple variables in wide format.

If `direction="long"` the `varying` argument can be a vector of column names (or a corresponding index). The function will attempt to guess the `v.names` and `times` from these names. The default is variable names like `x.1`, `x.2`, where `sep="."` specifies to split at the dot and drop it from the name. To have alphabetic followed by numeric times use `sep=""`.

Variable name splitting as described above is only attempted in the case where `varying` is an atomic vector, if it is a list or a matrix, `v.names` and `times` will generally need to be specified, although they will default to, respectively, the first variable name in each set, and sequential times.

Also, guessing is not attempted if `v.names` is given explicitly. Notice that the order of variables in `varying` is like `x.1`,`y.1`,`x.2`,`y.2`.

The `split` argument should not usually be necessary. The `split$regexp` component is passed to either `strsplit()` or `regexp()`, where the latter is used if `split$include` is `TRUE`, in which case the splitting occurs after the first character of the matched string. In the `strsplit()` case, the separator is not included in the result, and it is possible to specify fixed-string matching using `split$fixed`.

### Value

The reshaped data frame with added attributes to simplify reshaping back to the original form.

### See Also

`stack`, `aperm`; `relist` for reshaping the result of `unlist`.

### Examples

    summary(Indometh)
    wide <- reshape(Indometh, v.names="conc", idvar="Subject",
                    timevar="time", direction="wide")
    wide

    reshape(wide, direction="long")
    reshape(wide, idvar="Subject", varying=list(2:12),
            v.names="conc", direction="long")

    ## times need not be numeric
    df <- data.frame(id=rep(1:4,rep(2,4)),
                     visit=I(rep(c("Before","After"),4)),
                     x=rnorm(4), y=runif(4))
    df
    reshape(df, timevar="visit", idvar="id", direction="wide")
    ## warns that y is really varying
    reshape(df, timevar="visit", idvar="id", direction="wide", v.names="x")

    ##  unbalanced 'long' data leads to NA fill in 'wide' form
    df2 <- df[1:7,]
    df2
    reshape(df2, timevar="visit", idvar="id", direction="wide")

    ## Alternative regular expressions for guessing names
    df3 <- 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 data
    state.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 variables
    df3 <- 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 back
    reshape(wide)

[Package stats version 2.6.0 Index]