2010-12-08 8 views
18

Ich versuche, zwei Spalten in meinem Dataframe in das 'gute' Datum & Zeitklasse zu transformieren, und bis jetzt hatte nicht viel Erfolg damit. Ich habe verschiedene Klassen ausprobiert (timeDate, Date, timeSeries, POSIXct, POSIXlt), aber ohne Erfolg. Vielleicht übersehe ich nur das Offensichtliche und weil ich so viele Ansätze ausprobiert habe, weiß ich einfach nicht mehr, was es ist. Ich hoffe, dass einige von Ihnen etwas Licht in die Sache bringen können, wo ich falsch liege.So finden Sie das höchste (neueste) und das niedrigste (früheste) Datum [R]

Ziel: Ich möchte den Unterschied zwischen zwei Daten mit dem frühesten und spätesten Datum berechnen. Ich arbeite mit head() und tail(), aber da diese Werte nicht das früheste und späteste Datum in meinen Daten sind, brauche ich einen anderen Weg. (Ich sorge dafür, dass die Daten nicht sortiert werden, weil die Daten nur am Tag des Datums sortiert werden.)

Zweites Ziel: Ich möchte die Daten vom täglichen Format (dh 8-12 -2010) auf wöchentliche, monatliche und jährliche Ebenen (dh '49 -2010 ',' Dezember-10 'und nur' 2010 '). Dies kann mit den Formateinstellungen (wie "% d-% m-% y") geschehen. Kann dies getan werden, indem der data.frame in eine Zeitklasse konvertiert wird und die Zeitklasse in das richtige Format umgewandelt wird (8-12-2010 -> format ("% B-% y") -> 'Dezember-10') und dann diese Zeitklasse in einen Faktor mit Ebenen für jeden Monat umwandeln?

Für beide Ziele muss ich den Datumsrahmen irgendwie in eine Zeitklasse konvertieren, und hier stieß ich auf einige Schwierigkeiten.

sieht Ihr Datenrahmen wie folgt aus:

> tradesList[c(1,10,11,20),14:15] -> tmpTimes4 
> tmpTimes4 
    EntryTime ExitTime 
1 01-03-07 10-04-07 
10 29-10-07 02-11-07 
11 13-04-07 14-05-07 
20 18-12-07 20-02-08 

Hier ist eine Zusammenfassung dessen, was ich versucht habe:

> class(tmpTimes4) 
[1] "data.frame" 
> as.Date(head(tmpTimes4$EntryTimes, n=1), format="%d-%m-%y") 
Error in as.Date.default(head(tmpTimes4$EntryTimes, n = 1), format = "%d-%m-%y") : 
    do not know how to convert 'head(tmpTimes4$EntryTimes, n = 1)' to class "Date" 
> as.timeDate(tmpTimes4, format="%d-%m-%y") 
Error in as.timeDate(tmpTimes4, format = "%d-%m-%y") : 
    unused argument(s) (format = "%d-%m-%y") 
> timeSeries(tmpTimes4, format="%d-%m-%y") 
Error in midnightStandard2(charvec, format) : 
    'charvec' has non-NA entries of different number of characters 
> tmpEntryTimes4 <- timeSeries(tmpTimes4$EntryTime, format="%d-%m-%y") 
> tmpExitTimes4 <- timeSeries(tmpTimes4$ExitTime, format="%d-%m-%y") 
> tmpTimes5 <- cbind(tmpEntryTimes4,tmpExitTimes4) 
> colnames(tmpTimes5) <- c("Entry","Exit") 
> tmpTimes5 
    Entry Exit  
[1,] 01-03-07 10-04-07 
[2,] 29-10-07 02-11-07 
[3,] 13-04-07 14-05-07 
[4,] 18-12-07 20-02-08 
> class(tmpTimes5) 
[1] "timeSeries" 
attr(,"package") 
[1] "timeSeries" 
> as.timeDate(tmpTimes5, format="%d-%m-%y") 
Error in as.timeDate(tmpTimes5, format = "%d-%m-%y") : 
    unused argument(s) (format = "%d-%m-%y") 
> as.Date(tmpTimes5, format="%d-%m-%y") 
Error in as.Date.default(tmpTimes5, format = "%d-%m-%y") : 
    do not know how to convert 'tmpTimes5' to class "Date" 
> format.POSIXlt(tmpTimes5, format="%d-%m-%y", usetz=FALSE) 
Error in format.POSIXlt(tmpTimes5, format = "%d-%m-%y", usetz = FALSE) : 
    wrong class 
> as.POSIXlt(tmpTimes5, format="%d-%m-%y", usetz=FALSE) 
Error in as.POSIXlt.default(tmpTimes5, format = "%d-%m-%y", usetz = FALSE) : 
    do not know how to convert 'tmpTimes5' to class "POSIXlt" 
> as.POSIXct(tmpTimes5, format="%d-%m-%y", usetz=FALSE) 
Error in as.POSIXlt.default(x, tz, ...) : 
    do not know how to convert 'x' to class "POSIXlt" 

Die Timedate Pakete eine Funktion für ‚Reichweite‘ hat, jedoch die Umwandlung Die Date-Klasse funktioniert für eine einzelne Instanz, aber aus irgendeinem Grund nicht für einen Datenrahmen:

An diesem Punkt glaube ich fast, dass es unmöglich ist zu tun, also würden alle Gedanken sehr geschätzt werden!

Grüße,

+0

Sie verwenden könnten 'dput (tmpTimes4)' genaue Datenmenge die Verwendung in Ihrem Code zu liefern. – Marek

+0

@Marek: Danke für die Antwort! Ich wusste nichts von dput, also danke für den Tipp. :) – Jura25

Antwort

30

beginnen mit einigen Dummy-Daten:

start <- as.Date("2010/01/01") 
end <- as.Date("2010/12/31") 
set.seed(1) 
datewant <- seq(start, end, by = "days")[sample(15)] 
tmpTimes <- data.frame(EntryTime = datewant, 
         ExitTime = datewant + sample(100, 15)) 
## reorder on EntryTime so in random order 
tmpTimes <- tmpTimes[sample(NROW(tmpTimes)), ] 
head(tmpTimes) 

so haben wir etwas wie folgt aus:

> head(tmpTimes) 
    EntryTime ExitTime 
8 2010-01-14 2010-03-16 
9 2010-01-05 2010-01-17 
7 2010-01-10 2010-01-30 
3 2010-01-08 2010-04-16 
10 2010-01-01 2010-01-26 
13 2010-01-12 2010-02-15 

die oben verwenden, Blick auf Ziel 1, Rechen Differenz zwischen frühestem und spätestem Datum. Sie können Datumsangaben so behandeln, als ob sie Zahlen wären (so werden sie ohnehin intern gespeichert), so dass Funktionen wie min() und max() funktionieren. Sie können die difftime() Funktion:

> with(tmpTimes, difftime(max(EntryTime), main(EntryTime))) 
Time difference of 14 days 

oder Standard-Subtraktion verwenden

> with(tmpTimes, max(EntryTime) - min(EntryTime)) 
Time difference of 14 days 

, um den Unterschied in Tagen. head() und tail() funktionieren nur, wenn Sie die Daten sortieren, da diese den ersten und letzten Wert in einem Vektor enthalten, nicht den höchsten und niedrigsten tatsächlichen Wert.

Ziel 2: Sie scheinen zu versuchen, einen Datenrahmen in ein Datum zu konvertieren. Du kannst das nicht tun. Was Sie tun können, ist die Daten in den Komponenten des Datenrahmens neu zu formatieren. Hier füge ich Spalten zu tmpTimes hinzu, indem ich die Spalte EntryTime in mehrere verschiedene Zusammenfassungen des Datums umformatiere.

tmpTimes2 <- within(tmpTimes, weekOfYear <- format(EntryTime, format = "%W-%Y")) 
tmpTimes2 <- within(tmpTimes2, monthYear <- format(EntryTime, format = "%B-%Y")) 
tmpTimes2 <- within(tmpTimes2, Year <- format(EntryTime, format = "%Y")) 

Giving:

> head(tmpTimes2) 
    EntryTime ExitTime weekOfYear monthYear Year 
8 2010-01-14 2010-03-16 02-2010 January-2010 2010 
9 2010-01-05 2010-01-17 01-2010 January-2010 2010 
7 2010-01-10 2010-01-30 01-2010 January-2010 2010 
3 2010-01-08 2010-04-16 01-2010 January-2010 2010 
10 2010-01-01 2010-01-26 00-2010 January-2010 2010 
13 2010-01-12 2010-02-15 02-2010 January-2010 2010 

Wenn Sie Amerikaner sind oder wollen die US-Konvention für den Beginn der Woche verwenden (%W beginnt die Woche an einem Montag, ist im US-Kongress auf einem starten Sonntag), ändern Sie die zu %U. ?strftime hat mehr Details von was und %U darstellen.


Ein letzter Punkt auf Datenformat: In der oben Ich habe mit Daten in Standard-R-Format gearbeitet. Sie haben Ihre Daten in einem Datenrahmen in einem nicht standardmäßigen Markup gespeichert, vermutlich als Zeichen oder Faktoren. So haben Sie etwas wie:

tmpTimes3 <- within(tmpTimes, 
        EntryTime <- format(EntryTime, format = "%d-%m-%y")) 
tmpTimes3 <- within(tmpTimes3, 
        ExitTime <- format(ExitTime, format = "%d-%m-%y")) 

> head(tmpTimes3) 
    EntryTime ExitTime 
8 14-01-10 16-03-10 
9 05-01-10 17-01-10 
7 10-01-10 30-01-10 
3 08-01-10 16-04-10 
10 01-01-10 26-01-10 
13 12-01-10 15-02-10 

Sie müssen diese Zeichen oder Faktoren in etwas umwandeln, das R als ein Datum versteht. Meine Präferenz wäre die "Date" Klasse. Bevor Sie die oben genannten Antworten mit Ihren Daten versuchen, Ihre Daten in das richtige Format konvertieren:

tmpTimes3 <- 
    within(tmpTimes3, { 
      EntryTime <- as.Date(as.character(EntryTime), format = "%d-%m-%y") 
      ExitTime <- as.Date(as.character(ExitTime), format = "%d-%m-%y") 
      }) 

, so dass Ihre Daten wie folgt aussieht:

> head(tmpTimes3) 
    EntryTime ExitTime 
8 2010-01-14 2010-03-16 
9 2010-01-05 2010-01-17 
7 2010-01-10 2010-01-30 
3 2010-01-08 2010-04-16 
10 2010-01-01 2010-01-26 
13 2010-01-12 2010-02-15 
> str(tmpTimes3) 
'data.frame': 15 obs. of 2 variables: 
$ EntryTime:Class 'Date' num [1:15] 14623 14614 14619 14617 14610 ... 
$ ExitTime :Class 'Date' num [1:15] 14684 14626 14639 14715 14635 ... 
+0

Wow Gavin, vielen Dank! Sie haben mir wirklich geholfen, nicht nur mit dem Codebeispiel, sondern auch mit dem ausgezeichneten (und klaren) Text. Nochmals vielen Dank, ich verstehe es jetzt vollständig, und es ist mir einfach gelungen, die Anzahl der Tage zu berechnen, die Daten zu transformieren und die Ergebnisse pro Zeiteinheit anzuzeigen. Ja! :) – Jura25

+0

@ Jura25: froh, dass Sie es nützlich fanden. –

+1

In der Tat arbeiten min und max für das Datum, aber wenn Sie eine NA in Ihrer Datumsspalte haben, verwenden Sie bitte die na.rm = TRUE, z. Sternzeit <-min (DateofTest, na.rm = TRUE). Sparen Sie sich den verwirrten Kratzer auf dem Kopf. –

5

Kurze Antwort:

  • Convert bis heute, wenn nicht schon geschehen.
  • Dann verwenden Sie min und max auf der Liste von Daten.

    date_list = structure(c(15401, 15405, 15405), class = "Date") 
    date_list 
    #[1] "2012-03-02" "2012-03-06" "2012-03-06" 
    
    min(date_list) 
    #[1] "2012-03-02" 
    max(date_list) 
    #[1] "2012-03-06" 
    
Verwandte Themen