2010-07-23 5 views
5

Mam ramkę danych, którą chciałbym scalić z długiego do szerokiego formatu, ale chciałbym, aby czas był osadzony w nazwie zmiennej w szerokim format. Oto przykład zbiór danych z długim formacie:Zmiana kształtu danych z długich na szerokie, z czasem w nowej nazwie zmiennej szerokiej

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 

chciałbym to w szerokim formacie z następującym wyjścia:

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

(and so on) 

Próbowałem przy użyciu funkcji zmienią się zasady R bez powodzenia , i nie byłem pewien, jak to osiągnąć, korzystając z pakietu przekształcania, ponieważ wszystkie przykłady umieszczają czas jako kolejną zmienną w szerokim formacie. Jakieś pomysły?

Odpowiedz

13

To trywialne z pakietem przekształcenia:

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

Dziękuję Hadley, twój kod robi dokładnie to, czego szukam. Dla mojej informacji zastąpiłem ... id, więc mogę to zapamiętać na przyszłe przykłady. – sheed03

+0

W tym kontekście "..." oznacza wszystkie inne zmienne, które nie zostały jeszcze uwzględnione w specyfikacji rzutowania. Nie musisz zastępować go rzeczywistymi nazwami zmiennych, chyba że robisz agregację. – hadley

1

Dlaczego po prostu nie wklejają nazwy zmiennych i czasu do siebie przed zmianą kształtu?

2

Musiałem to zrobić w dwóch krokach reshape. Nagłówki wierszy mogą nie być dokładnie tym, czego potrzebujesz, ale można je łatwo zmienić.

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

a wyjście:

> 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

Można też sprawdzić 'pakiet Hadley Wickhama Reshape' (Nigdy tego nie używałem). –

+0

Dziękuję, Richardzie, twoje rozwiązanie działało, ale zaakceptowałem kod Hadleya używając pakietu zmiany kształtu, ponieważ nowe nazwy zmiennych są dokładnie takie jakie chciałem (var1_5, var1_10, etc) bez dodatkowych linii kodu, aby zmienić nazwę zmiennej na żądany format . – sheed03

+0

@ sheed03 - Bez obaw. Droga Hadleya polega na tym, żeby to zrobić. Zauważyłem jednak, że zmienia on kolejność kolumn (tj. Umieszcza wartość czasu 5 w skrajnej prawej), więc upewnij się, że rzucasz okiem na wynik. –

2

dałem się na komendzie stary Reshape() 2 lata temu (nie Hadley). Wydaje się, że wymyślanie tego cholerstwa za każdym razem było naprawdę trudniejsze niż po prostu "twardą" drogą, która jest znacznie bardziej elastyczna.

Twoje dane w twoim przykładzie są ładnie posortowane. Może zajść potrzeba najpierw uporządkowania rzeczywistych danych według nazwy i czasu var.

(przemianowany Twój tmpdata do PZT, wykonane numeryczna wartość)

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)) 
Powiązane problemy