ddply + summarize dla powtarzania tej samej funkcji statystycznej w dużej liczbie kolumn
Ok, drugie pytanie R w szybkiej kolejności.
Moje dane:
Timestamp St_01 St_02 ...
1 2008-02-08 00:00:00 26.020 25.840 ...
2 2008-02-08 00:10:00 25.985 25.790 ...
3 2008-02-08 00:20:00 25.930 25.765 ...
4 2008-02-08 00:30:00 25.925 25.730 ...
5 2008-02-08 00:40:00 25.975 25.695 ...
...
W zasadzie normalnie użyłbym kombinacji ddply
i summarize
do obliczenia kompletów (np. średniej dla każdej godziny w całym roku).
W powyższym przypadku utworzyłbym kategorię, np. hour (np. strptime(data$Timestamp,"%H") -> data$hour
, a następnie użył tej kategorii w ddply
, np. ddply(data,"hour", summarize, St_01=mean(St_01), St_02=mean(St_02)...)
, aby uśrednić według kategorii w każdej z kolumn.
Ale tutaj robi się lepki. Mam do czynienia z ponad 40 kolumnami i Nie jestem przygotowany, aby wpisywać je wszystkie jeden po drugim jako parametry do funkcji summarize
. Kiedyś pisałem pętlę w powłoce, aby wygenerować ten kod, ale nie tak Programiści rozwiązują problemy, prawda?
Więc proszę powiedzieć, czy ktoś ma lepszy sposób na osiągnięcie tego samego wyniku, ale z mniejszą liczbą naciśnięć klawiszy?
2 answers
Możesz użyć numcolwise()
do uruchomienia podsumowania wszystkich kolumn numerycznych.
Oto przykład użycia iris
:
ddply(iris, .(Species), numcolwise(mean))
Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1 setosa 5.006 3.428 1.462 0.246
2 versicolor 5.936 2.770 4.260 1.326
3 virginica 6.588 2.974 5.552 2.026
Podobnie jest catcolwise()
, aby podsumować wszystkie kolumny kategoryczne.
Zobacz ?numcolwise
aby uzyskać więcej pomocy i przykładów.
EDIT
Alternatywnym podejściem jest użycie reshape2
(zaproponowane przez @gsk3). Ma to więcej naciśnięć klawiszy w tym przykładzie, ale daje ogromną elastyczność: {]}
Biblioteka (reshape2)
miris <- melt(iris, id.vars="Species")
x <- ddply(miris, .(Species, variable), summarize, mean=mean(value))
dcast(x, Species~variable, value.var="mean")
Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1 setosa 5.006 3.428 1.462 0.246
2 versicolor 5.936 2.770 4.260 1.326
3 virginica 6.588 2.974 5.552 2.026
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-05-28 16:35:44
Możesz nawet uprościć drugie podejście zaproponowane przez Andrie ' ego, całkowicie pomijając wywołanie ddply. Po prostu określ mean
jako funkcję agregacji w wywołaniu dcast:
library(reshape2)
miris <- melt(iris, id.vars="Species")
dcast(miris, Species ~ variable, mean)
Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1 setosa 5.006 3.428 1.462 0.246
2 versicolor 5.936 2.770 4.260 1.326
3 virginica 6.588 2.974 5.552 2.026
Ten sam wynik można również bardzo szybko obliczyć za pomocą pakietu data.table
. Zmienna .SD
w wyrażeniu j jest danymi specjalnymi.zmienna tabel zawierająca podzbiór danych dla każdej grupy, z wyłączeniem wszystkich kolumn używanych w by
.
library(data.table)
dt_iris <- as.data.table(iris)
dt_iris[, lapply(.SD, mean), by = Species]
Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1: setosa 5.006 3.428 1.462 0.246
2: versicolor 5.936 2.770 4.260 1.326
3: virginica 6.588 2.974 5.552 2.026
Kolejną opcją byłaby nowa wersja 0.2 Hadley ' a dplyr
PAKIET
library(dplyr)
group_by(iris, Species) %>% summarise_each(funs(mean))
Source: local data frame [3 x 5]
Species Sepal.Length Sepal.Width Petal.Length Petal.Width
1 setosa 5.006 3.428 1.462 0.246
2 versicolor 5.936 2.770 4.260 1.326
3 virginica 6.588 2.974 5.552 2.026
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-05-26 21:40:58