Datumsmanipulationen mit as.POSIXlt
Frage
Ich versuche den Sonntag zu finden, der dem heutigen Tag am nächsten liegt.
Ich definiere heute als:
dt <- as.Date("2014-06-04")
Den letzten Sonntag finde ich wie folgt:
dt - as.POSIXlt(dt)$wday
[1] "2014-06-01"
Den nächsten Sonntag finde ich wie folgt:
dt + as.POSIXlt(dt)$wday
[1] "2014-06-07"
Ich bin mir nicht sicher, warum Folgendes nicht funktioniert:
ifelse(as.POSIXlt(dt)$wday <= 3,
dt - as.POSIXlt(dt)$wday,
dt + as.POSIXlt(dt)$wday)
[1] 16222
Ich bekomme eine Nummer: 16222
statt eines Datums.
Jede der folgenden Anweisungen funktioniert wie erwartet:
as.POSIXlt(dt)$wday
class(as.POSIXlt(dt)$wday)
as.POSIXlt(dt)$wday <= 3
Irgendwelche Ideen??
Lösung
Anscheinend ifelse
gibt einen Vektor zurück und entfernt die Klasse „POSIX“ aus Ihren Daten.Warum nicht?
dt + ifelse(as.POSIXlt(dt)$wday <= 3, -1, 1) * as.POSIXlt(dt)$wday
stattdessen.
Andere Tipps
Eine andere Lösung:Stellen Sie das Klassenattribut wieder her, indem Sie z. B. Folgendes aufrufen:
structure(ifelse(as.POSIXlt(dt)$wday <= 3,
dt - as.POSIXlt(dt)$wday,
dt + as.POSIXlt(dt)$wday), class="Date")
Es ist nicht erforderlich, ein zu verwenden ifelse
hier, Ein Klassiker if/else
wird den Job machen:
if(as.POSIXlt(dt)$wday <= 3) dt - as.POSIXlt(dt)$wday else dt + as.POSIXlt(dt)$wday
[1] "2014-06-01"
Oder noch einfacher:
wday <- as.POSIXlt(dt)$wday
dt + if(wday<= 3) -wday else wday
1) Versuche dies:
wday <- as.POSIXlt(dt)$wday
dt + ifelse(wday <= 3, -wday, 7-wday)
Dabei handelt es sich um die ifelse
auf die Anzahl der addierten oder subtrahierten Tage. ifelse
funktioniert gut mit einfachen Zahlen, aber nicht mit komplexen Typen wie "Date"
Klasse, sodass die Anwendung von vermieden wird ifelse
Zu "Date"
Klassenobjekte.
Beachten Sie, dass wenn wday > 3
dann wollen wir hinzufügen 7-wday
und nicht wday
(wie in der Frage).
Die Lösung hier funktioniert auch dann weiterhin, wenn dt
ist ein Vektor von Daten.
2) Beachten Sie, dass die zweite Zeile der Antwort in (1) alternativ folgendermaßen geschrieben werden könnte, wobei zunächst der letzte Sonntag berechnet wird (dt-wday
) und addiert 7, um den nächsten Sonntag zu erhalten, wenn dieser in der Woche nach einem Mittwoch liegt.
dt - wday + ifelse(wday > 3, 7, 0)
3) Noch eine andere Möglichkeit, dies auszudrücken, ist:
dt - wday + 7 * (wday > 3)