2010-07-23 9 views
5

Ich habe einen Datenrahmen, den ich gerne von Lang- zu Wide-Format zusammenführen würde, aber ich möchte die Zeit in den Variablennamen in der Breite eingebettet haben Format. Hier sind ein Beispiel von Daten mit dem langen Format eingestellt:Reshape Daten von Long nach Wide, mit Zeit in neuen Wide Variablennamen

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 

Ich würde dies gerne in ein Wide-Format mit der folgenden Ausgabe:

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

(and so on) 

Ich habe versucht, mit umformen Funktion in der Basis R ohne Erfolg und ich war mir nicht sicher, wie ich dies mit dem Umformpaket erreichen konnte, da alle Beispiele die Zeit als eine andere Variable im Breitformat angeben. Irgendwelche Ideen?

Antwort

13

(Ihr tmpdata zu tmp, gemacht Wert numerisch umbenannt) Dies ist trivial mit dem reshape Paket:

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

Vielen Dank Hadley, Ihr Code macht genau das, wonach ich suche. Als Referenz habe ich die ... mit ID ersetzt, damit ich mich an zukünftige Beispiele erinnern kann. – sheed03

+0

In diesem Kontext bedeutet '...' alle anderen Variablen, die nicht bereits in der Cast-Spezifikation enthalten sind. Sie sollten es nicht durch tatsächliche Variablennamen ersetzen müssen, es sei denn, Sie aggregieren. – hadley

1

Warum nicht einfach Varname und Zeit zusammenfügen, bevor Sie umformen?

2

Ich musste es in zwei Schritten reshape tun. Die Zeilenüberschriften sind möglicherweise nicht genau das, was Sie benötigen, können aber leicht umbenannt werden.

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

Und die Ausgabe:

> 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

Sie sollten auch überprüfen Hadley Wickhams 'Reshape' Paket (Ich habe es nie benutzt). –

+0

Vielen Dank richardh, Ihre Lösung hat funktioniert, aber ich akzeptierte Hadleys Code mit dem Umformpaket, weil die neuen Variablennamen genau so sind, wie ich wollte (var1_5, var1_10, etc.), ohne zusätzliche Codezeilen, um die Variablennamen in das gewünschte Format umzubenennen . – sheed03

+0

@ shed03 - Keine Sorge. Hadleys Weg ist der Weg, es zu tun. Aber ich habe bemerkt, dass er die Reihenfolge der Spalten ändert (d. H. Den Wert für Zeit 5 ganz nach rechts setzt), also sieh dir die Ausgabe an. –

2

habe ich vor 2 Jahren auf dem alten reshape() Befehl (nicht Hadleys). Es scheint, dass das verdammte Ding jedes Mal härter war, als nur den "harten" Weg zu machen, der viel flexibler ist.

Ihre Daten in Ihrem Beispiel sind alle gut sortiert. Möglicherweise müssen Sie Ihre realen Daten zuerst nach var name und time sortieren.

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)) 
Verwandte Themen