2011-10-19 17 views
45

Mam ogromny dataframe takiego:Przegrupuj dataframe do stołu, przeciwieństwo „topić”

SN = c(1:100, 1:100, 1:100, 1:100) 
class = c(rep("A1", 100), rep("B2", 100), rep("C3", 100), rep("D4", 100)) # total 6000 levels 
myvar = rnorm(400) 
mydf = data.frame(SN, class, myvar) 

chcę „unmelt” do tabeli z każdym poziomie pojedynczej kolumny i myVar w nasyceni

SN   A1   B2   C3   D4  .............and so on for all 6000 

Jak mogę to osiągnąć, wiem, że to proste pytanie, ale nie mogłem zrozumieć.

+2

W pakiecie 'reshape2' przeciwieństwem' melt' jest 'cast' – Andrie

+0

dzięki za sugestie, wymagają (reshape2); acast (mydf, myvar ~ class) dało dobry wynik – jon

+0

Zobacz odpowiedź poniżej, aby uzyskać poprawną składnię. To całkiem naturalne, gdy używasz go kilka razy. Znacznie lepiej niż wbudowany 'reshape()'. –

Odpowiedz

47
> dcast(mydf, SN ~ class) 

    SN   A1   B2   C3   D4 
1 1 0.1461258 0.8325014 0.33562088 -0.07294576 
2 2 0.5964182 0.4593710 -0.23652803 -1.52539568 
3 3 2.0247742 -1.1235963 1.79875447 -1.87462227 
4 4 0.8184004 1.3486721 0.76076486 -1.18311991 
5 5 -0.6577212 0.3666741 -0.06057506 1.38825487 
6 6 0.1590443 0.2043661 0.08161778 0.10421797 
... 
+10

Uwaga: pochodzi z biblioteki 'reshape2'. –

+2

Należy również zauważyć, że "najlepsza praktyka" to: dcast (mydf, SN ~ class, value.var = "myvar") – pallevillesen

+0

Hm, czy to powinno działać? 'iris_melt <- stop (tęczówki); dcast (iris_melt, zmienna gatunkowa ~) '? Ponieważ tak nie jest. Daje liczby (gatunek według tabeli pomiarowej). – naught101

5
molten = melt(mydf , id.vars = c("SN" , "class") , measure.vars = "myvar") 
casted = dcast(molten , SN~class) 
1

w bazie R można zrobić to w ten sposób ...

# get it sorted so that all you need to do is make a matrix out of it 
mydf <- mydf[order(mydf$class, mydf$SN),] 
# save the unique values of SN 
SNu <- unique(mydf$SN) 
# combine a matrix with SN 
mydfw <- data.frame(SNu, matrix(mydf$myvar, nrow = length(SNu))) 
# name your columns  
colnames(mydfw) <- c('SN', levels(mydf$class)) 

Albo, bardziej zwięzłe wypowiedzi z użyciem kruszywa

aggregate(myvar~SN, mydf, 'c') 
# column names don't come out great 
colnames(mydfw) <- c('SN', levels(mydf$class)) 
+1

Zakłada się, że wszystkie kombinacje poziomów są obecne, co generalnie stanowi niebezpieczne założenie. – hadley

+0

Działa na przykład. Po prostu nie lubisz pierwszego, ponieważ jest bardzo szybki. :) Ale żartuję na bok, pytający, Hadley ma rację, jeśli nie masz kompletnej matrycy, to nie będzie działać poprawnie. Można po prostu połączyć się z kompletnym projektem czynnikowym za pomocą metody expand.grid, aby uzyskać interesujące czynniki. – John

1

inne podejście ze split:

mydfSplit <- split(mydf[,-2], mydf$class, drop=TRUE) 

Wynikiem jest lista, które można łatwo przekształcić w data.frame gdy elementy mają te same wymiary (co ma miejsce w tym przykładzie):

mydf2 <- do.call(cbind, mydfSplit) 

Problemem tego rozwiązania jest to, że te nazwy wynik końcowy wymaga czyszczenia. Jednak w przypadku bardziej ogólnych danych może to być przydatne, jeśli SN jest inna dla każdej klasy.