2011-08-10 13 views
7

Próbuję użyć funkcji daply w pakiecie plyr, ale nie mogę jej poprawnie wyświetlić. Mimo że zmienna składająca się na macierz jest numeryczna, elementy macierzy są listami, a nie samą zmienną. Oto mały podzbiór danych, na przykład imię:Konwertowanie ramki danych na macierz za pomocą plyr dully

Month Vehicle Samples 
1 Oct-10 31057  256 
2 Oct-10 31059  316 
3 Oct-10 31060  348 
4 Nov-10 31057  267 
5 Nov-10 31059  293 
6 Nov-10 31060  250 
7 Dec-10 31057  159 
8 Dec-10 31059  268 
9 Dec-10 31060  206 

I chciałbym, aby móc wizualizować dane w formacie matrycy, która będzie wyglądać mniej więcej tak:

Month 
Vehicle Oct-10 Nov-10 Dec-10 
    31057 256 267 159 
    31059 316 293 268 
    31060 348 250 206 

tutaj kilka składni alternatywnej że używam (ten ostatni, ponieważ mój oryginalny dataframe ma więcej kolumn niż pokażę tutaj):

daply(DF, .(Vehicle, Month), identity) 
daply(DF,.(Vehicle,Month), colwise(identity,.(Samples))) 

jednak to, co dostaję w zamian jest dość zawiły:

 Month 
Vehicle Oct-10 Nov-10 Dec-10 
    31057 List,3 List,3 List,3 
    31059 List,3 List,3 List,3 
    31060 List,3 List,3 List,3 

użyłem funkcji str na wyjściu, jak niektórzy komentatorzy sugerowali, a oto fragment:

List of 9 
$ :'data.frame':  1 obs. of 3 variables: 
    ..$ Month : Ord.factor w/ 3 levels "Oct-10"<"Nov-10"<..: 1 
    ..$ Vehicle: Factor w/ 3 levels "31057","31059",..: 1 
    ..$ Samples: int 256 
$ :'data.frame':  1 obs. of 3 variables: 
    ..$ Month : Ord.factor w/ 3 levels "Oct-10"<"Nov-10"<..: 1 
    ..$ Vehicle: Factor w/ 3 levels "31057","31059",..: 2 
    ..$ Samples: int 316 

Czego mi brakuje? Czy istnieje sposób na zrobienie tego po prostu z pakietami podstawowymi? Dzięki!

Poniżej Dput ramki danych, jeśli chcesz, aby odtworzyć to:

structure(list(Month = structure(c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 
3L, 3L), .Label = c("Oct-10", "Nov-10", "Dec-10"), class = c("ordered", 
"factor")), Vehicle = structure(c(1L, 2L, 3L, 1L, 2L, 3L, 1L, 
2L, 3L), .Label = c("31057", "31059", "31060"), class = "factor"), 
    Samples = c(256L, 316L, 348L, 267L, 293L, 250L, 159L, 268L, 
    206L)), .Names = c("Month", "Vehicle", "Samples"), class = "data.frame", row.names = c(NA, 
9L)) 
+2

Przydałoby się trochę więcej informacji. Spróbuj str (DF) i wklej dane wyjściowe do pytania. Lub użyj dput (DF), aby zapewnić ludziom swoje dane do pracy, jeśli nie jest duża (podzbiór go, jeśli jest). – nzcoops

+1

Nie jest oczywiste, co próbujesz tutaj zrobić. Wygląda na to, że próbujesz przekształcić dane, ponieważ 'identity' nie wykonuje żadnych operacji na swoich argumentach. Powiedz nam, jakie są twoje oczekiwane rezultaty. – Andrie

+1

Zobacz http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example, w jaki sposób uczynić swój kod w pytaniu powtarzalnym. –

Odpowiedz

7

Funkcja identity nie jest to, co chcesz tutaj; ze strony pomocy: "Wszystkie funkcje plyr wykorzystują tę samą strategię split-apply-merging: dzielą dane wejściowe na prostsze kawałki, nakładają .fun na każdy element, a następnie łączą elementy w jedną strukturę danych." Prostszymi elementami w tym przypadku są podzbiory oryginalnej ramki danych z unikalnymi kombinacjami Pojazdy/Miesiące; funkcja tożsamości właśnie zwraca ten podzbiór, a te podzbiory są następnie wykorzystywane do wypełnienia wynikowej macierzy.

Oznacza to, że każdy element macierzy, którą masz, to ramka danych (która jest rodzajem listy) z wierszami z kombinacją Miesiąc/Pojazd.

> try1 <- daply(DF, .(Vehicle, Month), identity) 
> try1[1,1] 
[[1]] 
    Month Vehicle Samples 
1 Oct-10 31057  256 

Zamiast tego chcemy korzystać z funkcji, która właśnie trafia część Samples tej ramki danych, na przykład:

daply(DF, .(Vehicle, Month), function(x) x$Samples) 

co powoduje

 Month 
Vehicle Oct-10 Nov-10 Dec-10 
    31057 256 267 159 
    31059 316 293 268 
    31060 348 250 206 

kilka alternatywnych sposobów robi się to z cast z pakietu (który zwraca ramkę danych)

cast(DF, Vehicle~Month, value="Samples") 

zmieniona wersja w reshape2; pierwszy zwraca ramki danych, drugą matrycę

dcast(DF, Vehicle~Month, value_var="Samples") 
acast(DF, Vehicle~Month, value_var="Samples") 

z xtabs pakiecie

xtabs(Samples ~ Vehicle + Month, DF) 

stats lub ręcznie, co nie jest trudne w ogóle za pomocą indeksowania matrycy; prawie cały kod to właśnie konfiguracja macierzy.

with(DF, { 
    out <- matrix(nrow=nlevels(Vehicle), ncol=nlevels(Month), 
       dimnames=list(Vehicle=levels(Vehicle), Month=levels(Month))) 
    out[cbind(Vehicle, Month)] <- Samples 
    out 
}) 

reshape funkcja w pakiecie statystyki mogą być również wykorzystywane w tym celu, ale składnia jest trudne i nie użyłem go raz od nauki cast i melt z pakietu reshape.

+0

Dzięki, jeszcze bardziej pomocna niż mógłbym życzyć! Pomogło mi to również przezwyciężyć nieporozumienie związane z funkcją d * -play, tzn. Najpierw tworzy podzbiory, które są ramkami danych. –

2

Jeśli weźmiemy OP w ich słowa (i) w tytule, to mogą być one szuka data.matrix() która jest standardową funkcją w pakiecie base, która jest zawsze dostępna w wersji R.

data.matrix() polega na przekonwertowaniu dowolnych czynników na ich kodowanie numeryczne przed przekształceniem ramki danych w macierz. Rozważmy następujący ramkę danych:

dat <- data.frame(A = 1:10, B = factor(sample(c("X","Y"), 10, replace = TRUE))) 

Jeśli konwertować poprzez as.matrix() otrzymujemy matrycę znaków:

> head(as.matrix(dat)) 
    A B 
[1,] " 1" "X" 
[2,] " 2" "X" 
[3,] " 3" "Y" 
[4,] " 4" "Y" 
[5,] " 5" "Y" 
[6,] " 6" "Y" 

czy poprzez matrix() dostaje listę z wymiarami (tablicy listy - jak wspomniano w Wartość odcinek ?daply przy okazji)

> head(matrix(dat)) 
    [,1]  
[1,] Integer,10 
[2,] factor,10 
> str(matrix(dat)) 
List of 2 
$ : int [1:10] 1 2 3 4 5 6 7 8 9 10 
$ : Factor w/ 2 levels "X","Y": 1 1 2 2 2 2 1 2 2 1 
- attr(*, "dim")= int [1:2] 2 1 

data.matrix() Jednak nie zamierzony rzecz:

> mat <- data.matrix(dat) 
> head(mat) 
    A B 
[1,] 1 1 
[2,] 2 1 
[3,] 3 2 
[4,] 4 2 
[5,] 5 2 
[6,] 6 2 
> str(mat) 
int [1:10, 1:2] 1 2 3 4 5 6 7 8 9 10 ... 
- attr(*, "dimnames")=List of 2 
    ..$ : NULL 
    ..$ : chr [1:2] "A" "B" 
Powiązane problemy