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?

Author: smci, 2012-05-28

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
 36
Author: Andrie,
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
 7
Author: alex23lemm,
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