2012-07-17 7 views
5

Ich habe für eine Weile kämpfen mit diesem. Ich bin mit ts Daten und alle damit verbundenen R-Paketen zu arbeiten. I df eine mit mehreren Variablen, einschließlich dessen, was ‚Zeitpunkt der day'in GMT "% H% M" und das Datum "% Y /% m/e%" aufgetreten Abtastung haben. Ich möchte meine Datumsdaten in "Wochen" (d. H.% W /% g) zusammenfassen und berechnen und die durchschnittliche "Tageszeit" berechnen, wenn die Stichprobe während dieser Woche stattgefunden hat.Aggregieren mean "% H% M" in "Woche" Bins in R

konnte ich andere FUN auf numerischen Variablen (zB Gewicht) berechnen, indem man zuerst meine df in einem Zoo Objekt verwandeln und dann aggregate.zoo Befehl wie folgt verwendet:

#calculate the sum weight captured every week 
x2c <- aggregate(OA_zoo, as.Date(cut(time(OA_zoo), "week")), sum) 
jedoch

, ich bin nicht sicher, wie um die Tatsache zu bekommen, dass ich mit Datumsformat statt num und würden uns freuen irgendwelche Tipps arbeite! Auch habe ich offensichtlich viel zu viel codiert, indem ich jede meiner Variablen separat gemacht habe. Wäre es möglich, verschiedene FUN (sum/mean/max/min) auf mein df anzuwenden, indem man "plural" mit "wöchentlich" aggregiert? Oder einige andere Pakete?

EDITS/PRÄZISIERUNGEN Hier ist die dput Ausgabe einer Probe meiner vollständigen Datensatz. Ich habe Daten von 2004-2011. Was ich mit ggplot2 betrachten/darstellen möchte, ist der Mittelwert/Median von TIME (% H% M) aggregiert im Zeitraum von Wochen über die Zeit (2004-2011). Momentan werden meine Daten nicht in Woche aggregiert, sondern täglich (Stichprobe).

> dput(godin) 
structure(list(depth = c(878, 1200, 1170, 936, 942, 964, 951, 
953, 911, 969, 960, 987, 991, 997, 1024, 978, 1024, 951, 984, 
931, 1006, 929, 973, 986, 935, 989, 1042, 1015, 914, 984), duration = c(0.8, 
2.6, 6.5, 3.2, 4.1, 6.4, 7.2, 5.3, 7.4, 7, 7, 5.5, 7.5, 7.3, 
7.5, 7, 4.2, 3, 5, 5, 9.3, 7.9, 7.3, 7.2, 7, 5.2, 8, 6, 7.5, 
7), Greenland = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 40L, 28L, 0L, 
0L, 34L, 7L, 28L, 0L, 0L, 0L, 27L, 0L, 0L, 0L, 44L, 59L, 0L, 
0L, 0L, 0L, 0L, 0L), date2 = structure(c(12617, 12627, 12631, 
12996, 12669, 13036, 12669, 13036, 12670, 13036, 12670, 13037, 
12671, 13037, 12671, 13037, 12671, 13038, 12672, 13038, 12672, 
13038, 12672, 13039, 12631, 12997, 12673, 13039, 12673, 13039 
), class = "Date"), TIME = c("0940", "0145", "0945", "2045", 
"1615", "0310", "2130", "1045", "0625", "1830", "1520", "0630", 
"0035", "1330", "0930", "2215", "2010", "0645", "0155", "1205", 
"0815", "1845", "2115", "0350", "1745", "0410", "0550", "1345", 
"1515", "2115")), .Names = c("depth", "duration", "Greenland", 
"date2", "TIME"), class = "data.frame", row.names = c("6761", 
"9019", "9020", "9021", "9022", "9023", "9024", "9025", "9026", 
"9027", "9028", "9029", "9030", "9031", "9032", "9033", "9034", 
"9035", "9036", "9037", "9038", "9039", "9040", "9041", "9042", 
"9043", "9044", "9045", "9046", "9047")) 
+0

Das Problem für mich ist unklar. Ist das Problem mit der Berechnung eines Mittelwerts einer Zeit (im Gegensatz zu einer numerischen) oder mit der Aggregation nach Woche? – mac

+0

Sie müssen wirklich ein [reproduzierbares Beispiel] (http://stackoverflow.com/q/5963269/271616) zur Verfügung stellen, damit jeder helfen kann. –

+0

Wie nehmen Sie den Mittelwert einer Tageszeit? Würden Sie nicht stattdessen Median oder Mode machen? – A5C1D2H2I1M1N2O1R2T1

Antwort

3

Ich würde es so nähern: zunächst eine Spalte mit einer Schnur machen, die die Woche:

godin$week <- format(godin$date2, "%Y-W%U") 

dies werden Sie so etwas wie "2004-W26", die für aggregate gut genug sein wird.

dann müssen Sie Ihren Charakter Vektor drehen, die SSMM in eine tatsächliche Zeit darstellt, so dass Sie Zeit Mathe auf sie verwenden können.

godin$time2 <- as.POSIXct(strptime(godin$TIME, "%H%M")) 

HINWEIS: Die oben ist ein bisschen wie ein Hack ... strptime() das aktuelle Datum wird davon ausgegangen, wenn keine angegeben ist, aber das sollte in der Art und Weise dieser speziellen Anwendung nicht erhalten, da alle Zeiten haben umgewandelt werden am selben Tag wird der Zeitteil des Mittelwerts korrekt sein. Ich werde später das Datum abzustreifen ...

An diesem Punkt denke ich, kann man einfach Aggregat:

x2c <- aggregate(time2~week, data=godin, FUN=mean) 

und loszuwerden, die nicht relevant (und fehlerhafte) Datumsteil

x2c$time2 <- format(x2c$time2,"%H:%M:%S") 

und Voila.

> x2c 
     week time2 
1 2004-W29 09:40:00 
2 2004-W30 01:45:00 
3 2004-W31 13:45:00 
4 2004-W36 12:07:00 
5 2004-W37 10:32:30 
6 2005-W31 12:27:30 
7 2005-W36 10:48:20 
8 2005-W37 13:11:06 

Die Lektion hier ist, dass sein schwer zu schieben um mal ohne dazugehörige Termine in R. ich von anderen zu hören, würde lieben, dies zu tun, einen besseren Weg.

+1

'as.Date (godin $ TIME,"% H% M ")' ist ein Fehler. –

+0

@JoshuaUlrich: bah. Du hast recht. Wie konvertiert man eine Zeit ohne Datum? – mac

+0

Ich kenne keinen Weg zu ... –

1

Wenn Sie den Durchschnitt aller Beobachtungszeiten pro Woche wollen und Sie wollen Daten (das heißt Materie19.00 heute und morgen 19.00 Uhr würde bis 07:00 Uhr morgen früh im Durchschnitt), dann können Sie tun, um diese

godin$datetime <- as.POSIXct(paste(godin$date2, godin$TIME), format="%Y-%m-%d %H%M") 
aggregate(godin$datetime, list(format(godin$datetime, "%W/%g")), mean) 

# Group.1     x 
#1 28/04 2004-07-18 09:40:00 
#2 30/04 2004-07-31 01:45:00 
#3 31/05 2005-08-02 00:27:30 
#4 36/04 2004-09-10 13:51:15 
#5 36/05 2005-09-11 00:26:40 
#6 37/05 2005-09-13 00:44:10 

Aber ich denke, Sie die durchschnittliche Zeit wollen, und Sie kümmern sich nicht um das Datum (außer um zu bestimmen, welche Woche es ist). In diesem Fall können Sie ein beliebiges Datum als Anker verwenden und alle Zeiten so behandeln, als würden sie an diesem Datum auftreten.

godin$stime <- as.POSIXct(paste("1970-01-01", godin$TIME), format='%Y-%m-%d %H%M') 
aggregate(godin$stime, list(format(godin$datetime, "%W/%g")), mean) 

# Group.1     x 
#1 28/04 1970-01-01 09:40:00 
#2 30/04 1970-01-01 09:45:00 
#3 31/05 1970-01-01 12:27:30 
#4 36/04 1970-01-01 11:51:15 
#5 36/05 1970-01-01 12:26:40 
#6 37/05 1970-01-01 12:44:10 

bearbeiten

Der Unterschied zwischen dem obigen Ausgang und dem Ausgang, vorgesehen @JoshuaUlrich ist, dass seine von Woche sortiert. Wenn ich sie sortiere, ist es wie Joshua, aber mit Sekunden anstelle von 100 Minuten. (Obwohl, ist es ein wenig schwierig, sie auf die gleiche Weise zu sortieren, weil der format Spezifikation, die Sie gewählt haben.)

out <- aggregate(godin$stime, list(format(godin$datetime, "%W/%g")), mean) 
out[order(as.numeric(paste0(substr(out[, 1], 4, 5), substr(out[, 1], 1, 2)))), ] 
# Group.1     x 
#1 28/04 1970-01-01 09:40:00 
#2 30/04 1970-01-01 09:45:00 
#4 36/04 1970-01-01 11:51:15 
#3 31/05 1970-01-01 12:27:30 
#5 36/05 1970-01-01 12:26:40 
#6 37/05 1970-01-01 12:44:10 

Edit 2

können Sie format innerhalb aggregate wenn Sie nur wollen, erhalten zurück ein String formatiert wie %H%M

out <- aggregate(godin$stime, list(format(godin$datetime, "%W/%g")), function(TIME) format(mean(TIME), "%H%M")) 
out[order(as.numeric(paste0(substr(out[, 1], 4, 5), substr(out[, 1], 1, 2)))), ] 
# Group.1 x 
#1 28/04 0940 
#2 30/04 0945 
#4 36/04 1151 
#3 31/05 1227 
#5 36/05 1226 
#6 37/05 1244 
+0

@GodinA, lass dich nicht von meiner Basis-R-Antwort täuschen; Wenn ich das persönlich machen würde, würde ich meine Daten in 'xts' konvertieren, bevor ich irgendwas mache. – GSee

+0

Dank @Gsee für Sie beantworten – GodinA

+0

Neugierig zu wissen, warum Ihre Ergebnisse von @mac abweichen? – GodinA

2

Sie müssen die TIME Spalte in gemeinsamen Einheiten (dh Minuten) konvertieren. Hier sind ein paar Hilfsfunktionen, um das zu tun:

hour2min <- function(hhmm) { 
    hhmm <- as.numeric(hhmm) 
    trunc(hhmm/100)*60 + hhmm %% 100 
} 
min2hour <- function(min) { 
    min <- as.numeric(min) 
    trunc(min/60)*100 + min %% 60 
} 

Dann können Sie die Minuten aggregieren, wie Sie möchten. Ich würde sie persönlich in einem xts Objekt setzen und verwenden apply.weekly:

library(xts) 
x <- xts(hour2min(godin$TIME), as.Date(godin$date2), dimnames=list(NULL,"MINS")) 
w <- apply.weekly(x, mean) 
w$TIME <- min2hour(w$MINS) 
#    MINS  TIME 
# 2004-07-18 580.0000 940.000 
# 2004-08-01 585.0000 945.000 
# 2004-09-12 711.2500 1151.250 
# 2005-08-02 747.5000 1227.500 
# 2005-09-11 746.6667 1226.667 
# 2005-09-13 764.1667 1244.167 

Sekunden in 100stel einer Minute noch, aber könnte geändert werden ...

+0

Danke für deine Antwort @Joshua Ulrich, aber das war nicht genau das, was ich gesucht habe. Siehe Antworten unten. – GodinA

Verwandte Themen