2011-01-13 16 views
7

Say mam następujące macierzy:Obliczanie dziennego oznacza w R

x1 = 1:288 
x2 = matrix(x1,nrow=96,ncol=3) 

Czy istnieje prosty sposób, aby uzyskać średnią z wierszy 1: 24,25: 48,49: 72,73: 96 dla kolumna 2?

Zasadniczo mam roczną serię czasową i muszę uśredniać niektóre dane co 24 godziny.

Odpowiedz

8

Jest.

Załóżmy, że mamy dni:

Days <- rep(1:4,each=24) 

można zrobić łatwo

tapply(x2[,2],Days,mean) 

Jeśli masz dataframe ze zmiennej data, można użyć tego. Możesz to zrobić dla wszystkich zmiennych naraz, używając agregatu:

x2 <- as.data.frame(cbind(x2,Days)) 
aggregate(x2[,1:3],by=list(Days),mean) 

Zapoznaj się z plikami pomocy dla tych funkcji. Również nie szukaj tutaj, jest tam kilka innych ciekawych odpowiedzi dotyczące tego problemu:

PS: Jeśli masz zamiar zrobić wiele timeseries, należy spójrz na pakiet zoo (na CRAN: http://cran.r-project.org/web/packages/zoo/index.html)

+0

@SnowFrog Mylisz się. tapply nie tworzy ramki danych. Tworzy wektor (w tym przypadku). Duża różnica. –

+0

Jednym z problemów związanych z metodą "tapply" jest to, że tworzy on wektor (liczba kolumn = liczba dni).Metoda "agregatowa" tworzy ramkę danych (1 kolumna z liczbą wierszy = liczba dni), co może być bardziej praktyczne, jeśli potrzebna jest późniejsza manipulacja danymi. – SnowFrog

2

Dość kompaktowy i szybki obliczeniowo sposób to zmienić kształt wektora na odpowiednią macierz i obliczyć kolumnę ans.

colMeans(matrix(x2[,2],nrow=24)) 
+0

czyste rozwiązanie, pod warunkiem, że nigdzie nie brakuje danych. W przeciwnym razie macierz nie reprezentowałaby dni. –

+0

Należy zachować ostrożność przy użyciu tej metody, aby wymiary były prawidłowe. Ale możesz sobie poradzić z brakującymi danymi, używając NA dla tych i używając na.rm = TRUE –

+0

Jestem tego świadomy :-) Mam na myśli brak w tym sensie, że "nie każdy dzień ma 24 wiersze danych" –

4

1) ts. Ponieważ jest to seria regularnych odstępach czasu, przekonwertować go do serii ts a następnie zsumować je z częstotliwością 24 do częstotliwości 1:

> aggregate(ts(x2[, 2], freq = 24), 1, mean) 

podając:

Time Series: 
Start = 1 
End = 4 
Frequency = 1 
[1] 108.5 132.5 156.5 180.5 

2) zoo. Tutaj używa się zoo. Pakiet zoo może również obsługiwać nieregularne odstępy między seriami (jeśli potrzebujemy przedłużyć to). Poniżej day.hour jest liczba dni (1, 2, 3, 4) oraz godzinę jako ułamek dnia, tak że floor(day.hour) tylko liczba dni:

> library(zoo) 
> day.hour <- seq(1, length = length(x2[, 2]), by = 1/24) 
> z <- zoo(x2[, 2], day.hour) 
> aggregate(z, floor, mean) 
    1  2  3  4 
108.5 132.5 156.5 180.5 

Jeśli zz jest wyjście następnie coredata(zz) i time(zz) są odpowiednio wartościami i czasami, jak zwykłe wektory.

+0

+1 za pokazywanie jak korzystać z zoo i ts. Nie wspominałem o tym, ponieważ nie chciałem przyjmować zbyt wiele na temat danych w rzeczywistym problemie, ale jest to z pewnością istotne i pomocne. –