R Language
Remodelando datos entre formas largas y anchas
Buscar..
Introducción
En R, los datos tabulares se almacenan en marcos de datos . Este tema cubre las diversas formas de transformar una sola tabla.
Observaciones
Paquetes útiles
- Remodelación, apilamiento y división con data.table.
- Remodelar utilizando tidyr
- splitstackshape
La función de remodelación
La función de base R más flexible para remodelar datos es reshape
. Ver ?reshape
para su sintaxis.
# create unbalanced longitudinal (panel) data set
set.seed(1234)
df <- data.frame(identifier=rep(1:5, each=3),
location=rep(c("up", "down", "left", "up", "center"), each=3),
period=rep(1:3, 5), counts=sample(35, 15, replace=TRUE),
values=runif(15, 5, 10))[-c(4,8,11),]
df
identifier location period counts values
1 1 up 1 4 9.186478
2 1 up 2 22 6.431116
3 1 up 3 22 6.334104
5 2 down 2 31 6.161130
6 2 down 3 23 6.583062
7 3 left 1 1 6.513467
9 3 left 3 24 5.199980
10 4 up 1 18 6.093998
12 4 up 3 20 7.628488
13 5 center 1 10 9.573291
14 5 center 2 33 9.156725
15 5 center 3 11 5.228851
Tenga en cuenta que el cuadro de datos está desequilibrado, es decir, a la unidad 2 le falta una observación en el primer período, mientras que a las unidades 3 y 4 les faltan observaciones en el segundo período. Además, tenga en cuenta que hay dos variables que varían a lo largo de los períodos: recuentos y valores, y dos que no varían: identificador y ubicación.
Largo a ancho
Para remodelar el data.frame a formato ancho,
# reshape wide on time variable
df.wide <- reshape(df, idvar="identifier", timevar="period",
v.names=c("values", "counts"), direction="wide")
df.wide
identifier location values.1 counts.1 values.2 counts.2 values.3 counts.3
1 1 up 9.186478 4 6.431116 22 6.334104 22
5 2 down NA NA 6.161130 31 6.583062 23
7 3 left 6.513467 1 NA NA 5.199980 24
10 4 up 6.093998 18 NA NA 7.628488 20
13 5 center 9.573291 10 9.156725 33 5.228851 11
Observe que los períodos de tiempo faltantes se completan con NA.
En la remodelación de ancho, el argumento "v.names" especifica las columnas que varían con el tiempo. Si la variable de ubicación no es necesaria, se puede eliminar antes de cambiar de forma con el argumento "soltar". Al eliminar la única columna que no varía / no-id desde el data.frame, el argumento v.names se vuelve innecesario.
reshape(df, idvar="identifier", timevar="period", direction="wide",
drop="location")
Ancho a largo
Para remodelar largo con el actual df.wide, una sintaxis mínima es
reshape(df.wide, direction="long")
Sin embargo, esto suele ser más complicado:
# remove "." separator in df.wide names for counts and values
names(df.wide)[grep("\\.", names(df.wide))] <-
gsub("\\.", "", names(df.wide)[grep("\\.", names(df.wide))])
Ahora la sintaxis simple producirá un error sobre columnas no definidas.
Con los nombres de columna que son más difíciles de analizar automáticamente para la función de reshape
, a veces es necesario agregar el argumento "variable" que le dice a la reshape
que reshape
variables particulares en formato ancho para la transformación en formato largo. Este argumento toma una lista de vectores de nombres de variables o índices.
reshape(df.wide, idvar="identifier",
varying=list(c(3,5,7), c(4,6,8)), direction="long")
En la remodelación larga, se puede proporcionar el argumento "v.names" para cambiar el nombre de las variables variables resultantes.
A veces, la especificación de "variable" se puede evitar mediante el uso del argumento "sep" que le dice a la reshape
qué parte del nombre de la variable especifica el argumento de valor y la que especifica el argumento de tiempo.
Remodelación de datos
A menudo los datos vienen en tablas. Generalmente se puede dividir estos datos tabulares en formatos anchos y largos. En un formato ancho, cada variable tiene su propia columna.
Persona | Altura (cm] | Edad [año] |
---|---|---|
Alison | 178 | 20 |
Mover | 174 | 45 |
Carl | 182 | 31 |
Sin embargo, a veces es más conveniente tener un formato largo, en el que todas las variables están en una columna y los valores en una segunda columna.
Persona | Variable | Valor |
---|---|---|
Alison | Altura (cm] | 178 |
Mover | Altura (cm] | 174 |
Carl | Altura (cm] | 182 |
Alison | Edad [año] | 20 |
Mover | Edad [año] | 45 |
Carl | Edad [año] | 31 |
La base R, así como los paquetes de terceros, pueden utilizarse para simplificar este proceso. Para cada una de las opciones, se mtcars
conjunto de datos mtcars
. Por defecto, este conjunto de datos está en un formato largo. Para que los paquetes funcionen, insertaremos los nombres de las filas como la primera columna.
mtcars # shows the dataset
data <- data.frame(observation=row.names(mtcars),mtcars)
Base R
Hay dos funciones en la base R que pueden usarse para convertir entre formato ancho y largo: stack()
y unstack()
.
long <- stack(data)
long # this shows the long format
wide <- unstack(long)
wide # this shows the wide format
Sin embargo, estas funciones pueden llegar a ser muy complejas para casos de uso más avanzados. Afortunadamente, hay otras opciones utilizando paquetes de terceros.
El paquete tidyr
Este paquete utiliza gather()
para convertir de ancho a largo y spread()
para convertir de largo a ancho.
library(tidyr)
long <- gather(data, variable, value, 2:12) # where variable is the name of the
# variable column, value indicates the name of the value column and 2:12 refers to
# the columns to be converted.
long # shows the long result
wide <- spread(long,variable,value)
wide # shows the wide result (~data)
El paquete data.table
El paquete data.table extiende las funciones reshape2
y usa la función melt()
para ir de ancho a largo y dcast()
para ir de largo a ancho.
library(data.table)
long <- melt(data,'observation',2:12,'variable', 'value')
long # shows the long result
wide <- dcast(long, observation ~ variable)
wide # shows the wide result (~data)