wide long funcion r aggregate reshape reshape2

long - funcion melt en r



Calcule la media y la desviación estándar por grupo para múltiples variables en un data.frame (5)

Editar : esta pregunta se tituló originalmente << Remodelación de datos de largo a ancho en R >>

Solo estoy aprendiendo R e intentando encontrar maneras de aplicarlo para ayudar a otros en mi vida. Como un caso de prueba, estoy trabajando en la remodelación de algunos datos y tengo problemas para seguir los ejemplos que he encontrado en línea. Lo que estoy empezando se ve así:

ID Obs 1 Obs 2 Obs 3 1 43 48 37 1 27 29 22 1 36 32 40 2 33 38 36 2 29 32 27 2 32 31 35 2 25 28 24 3 45 47 42 3 38 40 36

Y lo que quiero terminar se verá así:

ID Obs 1 mean Obs 1 std dev Obs 2 mean Obs 2 std dev 1 x x x x 2 x x x x 3 x x x x

Etcétera. Lo que no estoy seguro es si necesito información adicional en mis datos de formato largo, o qué. Me imagino que la parte de matemáticas (encontrar la media y las desviaciones estándar) será la parte fácil, pero no he podido encontrar una manera que parezca trabajar para remodelar los datos correctamente para comenzar ese proceso.

Muchas gracias por la ayuda.


Añado la solución dplyr .

set.seed(1) df <- data.frame(ID=rep(1:3, 3), Obs_1=rnorm(9), Obs_2=rnorm(9), Obs_3=rnorm(9)) library(dplyr) df %>% group_by(ID) %>% summarise_each(funs(mean, sd)) # ID Obs_1_mean Obs_2_mean Obs_3_mean Obs_1_sd Obs_2_sd Obs_3_sd # (int) (dbl) (dbl) (dbl) (dbl) (dbl) (dbl) # 1 1 0.4854187 -0.3238542 0.7410611 1.1108687 0.2885969 0.1067961 # 2 2 0.4171586 -0.2397030 0.2041125 0.2875411 1.8732682 0.3438338 # 3 3 -0.3601052 0.8195368 -0.4087233 0.8105370 0.3829833 1.4705692


Aquí hay otra data.table respuestas de la data.table de datos, utilizando los datos de @ Carson, que es un poco más legible (y también un poco más rápido, debido al uso de lapply lugar de sapply ):

library(data.table) set.seed(1) dt = data.table(ID=c(1:3), Obs_1=rnorm(9), Obs_2=rnorm(9), Obs_3=rnorm(9)) dt[, c(mean = lapply(.SD, mean), sd = lapply(.SD, sd)), by = ID] # ID mean.Obs_1 mean.Obs_2 mean.Obs_3 sd.Obs_1 sd.Obs_2 sd.Obs_3 #1: 1 0.4854187 -0.3238542 0.7410611 1.1108687 0.2885969 0.1067961 #2: 2 0.4171586 -0.2397030 0.2041125 0.2875411 1.8732682 0.3438338 #3: 3 -0.3601052 0.8195368 -0.4087233 0.8105370 0.3829833 1.4705692


Esta es probablemente la forma más sencilla de hacerlo (con un ejemplo reproducible ):

library(plyr) df <- data.frame(ID=rep(1:3, 3), Obs_1=rnorm(9), Obs_2=rnorm(9), Obs_3=rnorm(9)) ddply(df, .(ID), summarize, Obs_1_mean=mean(Obs_1), Obs_1_std_dev=sd(Obs_1), Obs_2_mean=mean(Obs_2), Obs_2_std_dev=sd(Obs_2)) ID Obs_1_mean Obs_1_std_dev Obs_2_mean Obs_2_std_dev 1 1 -0.13994642 0.8258445 -0.15186380 0.4251405 2 2 1.49982393 0.2282299 0.50816036 0.5812907 3 3 -0.09269806 0.6115075 -0.01943867 1.3348792

EDITAR: El siguiente enfoque le ahorra muchos tipos de escritura al tratar con muchas columnas.

ddply(df, .(ID), colwise(mean)) ID Obs_1 Obs_2 Obs_3 1 1 -0.3748831 0.1787371 1.0749142 2 2 -1.0363973 0.0157575 -0.8826969 3 3 1.0721708 -1.1339571 -0.5983944 ddply(df, .(ID), colwise(sd)) ID Obs_1 Obs_2 Obs_3 1 1 0.8732498 0.4853133 0.5945867 2 2 0.2978193 1.0451626 0.5235572 3 3 0.4796820 0.7563216 1.4404602


Este es un problema de agregación, no un problema de remodelación como lo sugirió originalmente la pregunta. Deseamos agregar cada columna en una media y desviación estándar por ID. Hay muchos paquetes que manejan tales problemas. En la base de R se puede hacer usando un aggregate como este (asumiendo que DF es el marco de datos de entrada):

ag <- aggregate(. ~ ID, DF, function(x) c(mean = mean(x), sd = sd(x)))

Nota 1: Un comentarista señaló que ag es un marco de datos para el cual algunas columnas son matrices. Aunque inicialmente pueda parecer extraño, de hecho simplifica el acceso. ag tiene el mismo número de columnas que la entrada DF . Su primera columna ag[[1]] es ID y la columna i del resto ag[[i+1]] (o equivalanetly ag[-1][[i]] ) es la matriz de estadísticas para la observación i entrada columna. Si uno desea acceder a la estadística jth de la observación i, entonces es ag[[i+1]][, j] que también puede escribirse como ag[-1][[i]][, j] .

Por otro lado, supongamos que hay k columnas estadísticas para cada observación en la entrada (donde k = 2 en la pregunta). Luego, si aplanamos la salida, para acceder a la estadística jth de la columna de observación i debemos usar ag[[k*(i-1)+j+1]] más complejo o equivalentemente ag[-1][[k*(i-1)+j]] .

Por ejemplo, compare la simplicidad de la primera expresión con la segunda:

ag[-1][[2]] ## mean sd ## [1,] 36.333 10.2144 ## [2,] 32.250 4.1932 ## [3,] 43.500 4.9497 ag_flat <- do.call("data.frame", ag) # flatten ag_flat[-1][, 2 * (2-1) + 1:2] ## Obs_2.mean Obs_2.sd ## 1 36.333 10.2144 ## 2 32.250 4.1932 ## 3 43.500 4.9497

Nota 2: La entrada en forma reproducible es:

Lines <- "ID Obs_1 Obs_2 Obs_3 1 43 48 37 1 27 29 22 1 36 32 40 2 33 38 36 2 29 32 27 2 32 31 35 2 25 28 24 3 45 47 42 3 38 40 36" DF <- read.table(text = Lines, header = TRUE)


Hay algunas maneras diferentes de hacerlo. reshape2 es un paquete útil. Personalmente, me gusta usar data.table

A continuación se muestra un paso a paso

Si myDF es tu data.frame :

library(data.table) DT <- data.table(myDF) DT # this will get you your mean and SD''s for each column DT[, sapply(.SD, function(x) list(mean=mean(x), sd=sd(x)))] # adding a `by` argument will give you the groupings DT[, sapply(.SD, function(x) list(mean=mean(x), sd=sd(x))), by=ID] # If you would like to round the values: DT[, sapply(.SD, function(x) list(mean=round(mean(x), 3), sd=round(sd(x), 3))), by=ID] # If we want to add names to the columns wide <- setnames(DT[, sapply(.SD, function(x) list(mean=round(mean(x), 3), sd=round(sd(x), 3))), by=ID], c("ID", sapply(names(DT)[-1], paste0, c(".men", ".SD")))) wide ID Obs.1.men Obs.1.SD Obs.2.men Obs.2.SD Obs.3.men Obs.3.SD 1: 1 35.333 8.021 36.333 10.214 33.0 9.644 2: 2 29.750 3.594 32.250 4.193 30.5 5.916 3: 3 41.500 4.950 43.500 4.950 39.0 4.243

Además, esto puede o no ser útil

> DT[, sapply(.SD, summary), .SDcols=names(DT)[-1]] Obs.1 Obs.2 Obs.3 Min. 25.00 28.00 22.00 1st Qu. 29.00 31.00 27.00 Median 33.00 32.00 36.00 Mean 34.22 36.11 33.22 3rd Qu. 38.00 40.00 37.00 Max. 45.00 48.00 42.00