2010-07-23 6 views
5

J'ai un cadre de données que je voudrais fusionner du format long au format large, mais j'aimerais que le temps soit incorporé dans le nom de la variable dans la largeur format. Voici un ensemble de données par exemple serties le format long:Remodeler les données de long à large, avec le temps dans le nouveau nom de variable large

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 

Je voudrais que cela dans un format large avec la sortie suivante:

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

(and so on) 

J'ai essayé d'utiliser remodeler la fonction dans la base R sans succès , et je n'étais pas sûr de la façon d'accomplir cela en utilisant le paquet reshape, car tous les exemples mettent l'heure comme une autre variable dans le format large. Des idées?

Répondre

13

Ceci est trivial avec le paquet Reshape:

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

Merci Hadley, ton code fait exactement ce que je cherche. Pour ma référence, j'ai remplacé le ... par ID pour que je m'en souvienne pour de futurs exemples. – sheed03

+0

Dans ce contexte '...' signifie toutes les autres variables qui ne sont pas déjà incluses dans la spécification de cast. Vous ne devriez pas avoir besoin de le remplacer par des noms de variables réels, sauf si vous faites une agrégation. – hadley

1

Pourquoi ne pas simplement coller le nom de variable et le temps ensemble avant de refaçonner?

2

Je devais le faire en deux étapes reshape. Les en-têtes de lignes peuvent ne pas être exactement ce dont vous avez besoin, mais peuvent être renommés facilement.

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") 

Et la sortie:

> 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

Vous pouvez également consulter le package 'Reshape' Hadley Wickham (Je ne l'ai jamais utilisé). –

+0

Merci richardh, votre solution a fonctionné mais j'ai accepté le code de Hadley en utilisant le paquet reshape car les nouveaux noms de variables sont exactement comme je le voulais (var1_5, var1_10, etc) sans avoir besoin de lignes de code supplémentaires . – sheed03

+0

@ sheed03 - Pas de soucis. Le chemin de Hadley est la façon de le faire. Mais j'ai remarqué qu'il change l'ordre des colonnes (c'est-à-dire, met la valeur de temps 5 à l'extrême droite), alors assurez-vous de jeter un coup d'œil à la sortie. –

2

Je donnai sur la commande ancienne Reshape() il y a 2 ans (non Hadley de). Il semble que cette foutue chose à chaque fois était plus difficile que de le faire de manière «dure», ce qui est beaucoup plus flexible.

Vos données dans votre exemple sont toutes bien triées. Vous devrez peut-être trier vos données réelles par nom de variable et heure d'abord.

(rebaptisé votre tmpdata à tmp, numérique de valeur faite)

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)) 
Questions connexes