2010-07-23 5 views
5

Tengo un marco de datos que me gustaría fusionar de formato largo a ancho, pero me gustaría tener el tiempo incrustado en el nombre de la variable en el ancho formato. He aquí un ejemplo de datos creados con el formato largo:Reformar los datos de largo a ancho, con el tiempo en el nuevo nombre de variable amplia

id <- as.numeric(rep(1,16)) 
time <- rep(c(5,10,15,20), 4) 
varname <- c(rep("var1",4), rep("var2", 4), rep("var3", 4), rep("var4", 4)) 
value <- rnorm(16) 
tmpdata <- as.data.frame(cbind(id, time, varname, value)) 

> tmpdata 
id time varname    value 
1 5 var1 0.713888426169224 
1 10 var1 1.71483653545922 
1 15 var1 -1.51992072577836 
1 20 var1 0.556992407683219 
.... 
4 20 var4 1.03752019932467 

me gustaría esto en un gran formato, con el siguiente resultado:

id var1.5 var1.10 var1.15 var1.20 .... 
1 0.71 1.71 -1.51 0.55 

(and so on) 

He intentado usar la función de formar de nuevo en la base de I sin éxito , y no estaba seguro de cómo lograr esto usando el paquete de remodelación, ya que todos los ejemplos ponen el tiempo como otra variable en el formato ancho. ¿Algunas ideas?

Respuesta

13

Esto es trivial con el paquete de cambio de forma:

library(reshape) 
cast(tmpdata, ... ~ varname + time) 
+0

Gracias, Hadley, tu código hace exactamente lo que estoy buscando. Para mi referencia, reemplacé el ... con id para que pueda recordar esto para futuros ejemplos. – sheed03

+0

En este contexto '...' significa todas las demás variables que aún no están incluidas en la especificación de conversión. No debería necesitar reemplazarlo con nombres de variables reales, a menos que esté haciendo una agregación. – hadley

1

¿Por qué no simplemente pegar varname y tiempo juntos antes de remodelar?

2

Tuve que hacerlo en dos pasos reshape. Es posible que los encabezados de las filas no sean exactamente lo que necesita, pero se puede renombrar fácilmente.

id <- as.numeric(rep(1, 16)) 
time <- rep(c(5,10,15,20), 4) 
varname <- c(rep("var1",4), rep("var2", 4), rep("var3", 4), rep("var4", 4)) 
value <- rnorm(16) 
tmpdata <- as.data.frame(cbind(id, time, varname, value)) 

first <- reshape(tmpdata, timevar="time", idvar=c("id", "varname"), direction="wide") 
second <- reshape(first, timevar="varname", idvar="id", direction="wide") 

Y la salida:

> tmpdata 
    id time varname    value 
1 1 5 var1 -0.231227494628982 
2 1 10 var1 -1.80887236653438 
3 1 15 var1 -0.443229294431553 
4 1 20 var1 1.33719337048763 
5 1 5 var2 0.673109282347586 
6 1 10 var2 -0.42142267953938 
7 1 15 var2 0.874367622725874 
8 1 20 var2 -1.19917678039462 
9 1 5 var3 1.13495606258399 
10 1 10 var3 -0.0779385346672042 
11 1 15 var3 -0.126775240288037 
12 1 20 var3 -0.760739300144526 
13 1 5 var4 -1.94626587907069 
14 1 10 var4 1.25643195699455 
15 1 15 var4 -0.50986941213717 
16 1 20 var4 -1.01324846239812 
> first 
    id varname   value.5   value.10   value.15 
1 1 var1 -0.231227494628982 -1.80887236653438 -0.443229294431553 
5 1 var2 0.673109282347586 -0.42142267953938 0.874367622725874 
9 1 var3 1.13495606258399 -0.0779385346672042 -0.126775240288037 
13 1 var4 -1.94626587907069 1.25643195699455 -0.50986941213717 
      value.20 
1 1.33719337048763 
5 -1.19917678039462 
9 -0.760739300144526 
13 -1.01324846239812 
> second 
    id  value.5.var1  value.10.var1  value.15.var1 value.20.var1 
1 1 -0.231227494628982 -1.80887236653438 -0.443229294431553 1.33719337048763 
     value.5.var2  value.10.var2  value.15.var2  value.20.var2 
1 0.673109282347586 -0.42142267953938 0.874367622725874 -1.19917678039462 
     value.5.var3  value.10.var3  value.15.var3  value.20.var3 
1 1.13495606258399 -0.0779385346672042 -0.126775240288037 -0.760739300144526 
     value.5.var4 value.10.var4  value.15.var4  value.20.var4 
1 -1.94626587907069 1.25643195699455 -0.50986941213717 -1.01324846239812 
+0

También es posible que desee comprobar hacia fuera 'paquete Reshape' de Hadley Wickham (Nunca lo he usado). –

+0

Gracias richardh, tu solución funcionó pero acepté el código de Hadley usando el paquete de reestructuración porque los nombres de las nuevas variables son exactamente como yo quería (var1_5, var1_10, etc.) sin tener líneas adicionales de código para cambiar el nombre de los nombres de las variables al formato deseado . – sheed03

+0

@ sheed03 - Sin preocupaciones. El camino de Hadley es el mejor camino para hacerlo. Pero me di cuenta de que cambia el orden de las columnas (es decir, pone el valor del tiempo 5 en el extremo derecho), así que asegúrese de echarle un vistazo a la salida. –

2

me di por vencido en el comando de edad reshape() hace 2 años (no Hadley). Parece que pensar que una maldita cosa cada vez fue más difícil que hacerlo de la manera "difícil", que es mucho más flexible.

Sus datos en su ejemplo están todos muy bien ordenados. Puede que tenga que ordenar sus datos reales por var nombre y hora primero.

(rebautizado su tmpdata a tmp, el valor hecho numérico)

y <- lapply(split(tmp, tmp$id), function(x) x$value) 
df <- data.frame(unique(tmp$id,), do.call(rbind,y)) 
names(df) <- c('id', as.character(tmp$time:tmp$var)) 
Cuestiones relacionadas