Hallo liebes R - Forum,
ich habe folgende Frage und hoffe, dass mir jemand weiterhelfen kann.
Ich verwende Daten zu Kraftstoffpreisen an verschiedenen Tankstellen in ganz Deutschland.
Dazu ist in den Daten jede Änderung der Kraftstoffpreise pro Tag angegeben.
Da ich die Werte aber in einem Paneldatensatz mit täglichen Werten betrachten möchte, muss ich auch die Werte der Kraftstoffpreise zu täglichen Werten aggregieren.
In einem Ersten Ansatz habe ich die dazu einfach die gemittelten Werte über den Tag gebildet (dafür habe ich die Packages lubridate und dlyr verwendet). Das hat auch wunderbar funktioniert.
In einem weiteren Ansatz möchte ich nun versuchen, jeder Tankstelle immer einen Preis pro Tag zuordnen, der zeitlich am nächsten an 13 Uhr liegt.
Mein Datensatz ist folgendermaßen aufgebaut, ich denke damit wird mein Vorhaben deutlicher.
date | Tankstelle | Preis Diesel
2018-01-01 10:43:06 | A | 1.199
2018-01-01 11:19:06 | A | 1.229
2018-01-01 12:43:05 | A | 1.209
2018-01-01 15:29:06 | A | 1.199
So werden die Daten dann für jede Tankstelle, für jede Änderung der Preise für jeden Tag dargestellt. Mein Ziel ist es, jeder Tankstelle aber eben nur einen Wert pro Tag zuzuordnen und zwar immer den Wert, der am nächsten an 13 Uhr liegt. Für die Tankstelle A im Beispiel also den Preis um 12:43 Uhr von 1.209€
Hat jemand eine Idee oder einen Ansatz, wie man sowas lösen könnte?
Ich hoffe ich konnte meine Frage verständlich formulieren und bedanke mich jetzt schonmal für eure Unterstützung
Tageswerte über Uhrzeit aggregieren
Moderator: jogo
-
- Beiträge: 3
- Registriert: Do Apr 22, 2021 12:38 pm
Re: Tageswerte über Uhrzeit aggregieren
In "data.table" kann man "rolling joins" veranstalten.
Dabei kann man den Parameter "roll" auf "nearest" setzen - das sollte was für Dich sein!
Dabei kann man den Parameter "roll" auf "nearest" setzen - das sollte was für Dich sein!
Re: Tageswerte über Uhrzeit aggregieren
So hier?
Muss man überlegen was man bei äquidistanz macht und wie man über gruppen das anwendet (die Beiepisldaten haben das nicht hergegeben).
Code: Alles auswählen
# data --------------------------------------------------------------------
df <- read.table(text = "date | Tankstelle | Preis Diesel
2018-01-01 10:43:06 | A | 1.199
2018-01-01 11:19:06 | A | 1.229
2018-01-01 12:43:05 | A | 1.209
2018-01-01 15:29:06 | A | 1.199",
sep = "|", header = TRUE)
# Pkgs --------------------------------------------------------------------
library(dplyr)
library(lubridate)
# code --------------------------------------------------------------------
df %>%
mutate(date = lubridate::ymd_hms(date),
reference = update(date, hour = 13, minute = 0, second = 0),
distance = abs(date - reference)) %>%
filter(distance == min(distance))
# or in case of ties using only the first
filter(rank(distance, ties.method = "first") == 1)
Bitte immer ein reproduzierbares Minimalbeispiel angeben. Meinungen gehören mir und geben nicht die meines Brötchengebers wieder.
Dieser Beitrag ist lizensiert unter einer CC BY 4.0 Lizenz
.
Dieser Beitrag ist lizensiert unter einer CC BY 4.0 Lizenz
.
-
- Beiträge: 3
- Registriert: Do Apr 22, 2021 12:38 pm
Re: Tageswerte über Uhrzeit aggregieren
Hat funktioniert, genau so habe ich es mir vorgestellt, vielen Dank!!EDi hat geschrieben: ↑Do Jun 10, 2021 6:50 pm So hier?Muss man überlegen was man bei äquidistanz macht und wie man über gruppen das anwendet (die Beiepisldaten haben das nicht hergegeben).Code: Alles auswählen
# data -------------------------------------------------------------------- df <- read.table(text = "date | Tankstelle | Preis Diesel 2018-01-01 10:43:06 | A | 1.199 2018-01-01 11:19:06 | A | 1.229 2018-01-01 12:43:05 | A | 1.209 2018-01-01 15:29:06 | A | 1.199", sep = "|", header = TRUE) # Pkgs -------------------------------------------------------------------- library(dplyr) library(lubridate) # code -------------------------------------------------------------------- df %>% mutate(date = lubridate::ymd_hms(date), reference = update(date, hour = 13, minute = 0, second = 0), distance = abs(date - reference)) %>% filter(distance == min(distance)) # or in case of ties using only the first filter(rank(distance, ties.method = "first") == 1)
Beeindruckend wie schnell einem hier mit einer schlauen Lösung geholfen wird echt toll, Danke.
Für die Gruppen habe ich es dann einfach mit group_by über die jeweilige ID der Tankstellen gelöst.
Re: Tageswerte über Uhrzeit aggregieren
Bevor die "data.table"-Lösung (wieder mal ) ignoriert wird, hier ein Beispiel mit simulierten Daten:
Man beachte die Ausführungszeit !
Code: Alles auswählen
library(data.table)
#------------------- Erzeugung Beispielsdaten: ---------------------------------
# für 100 Tanken werden über ein halbes Jahr
# (durchschnittlich) 8 "zufällige Zeitpunkte" pro Tag
# mit zufälligen Preisen erzeugt
ID <- paste0("ID", 1:100)
startZeit <- as.POSIXct("2020-01-01 00:00:00")
endZeit <- as.POSIXct("2020-07-01 00:00:00")
diff <- endZeit - startZeit
DT <- data.table(Tanke = sample(ID, 100*183*8, replace=TRUE),
Zeit = startZeit + diff*runif(100*183*8),
Preis = rnorm(100*183*8, 1.2,0.1))
DT[ , verwendeteZeit:=Zeit]
#---------- Für jede Tanke und jeden Tag wird ein "Stichzeitpunkt" -------------
#---------------- (High Noon, Summer time :) ) vereinbart ----------------------
Stichzeit <- seq(as.POSIXct("2020-01-01 13:00:00"), endZeit, by="1 day")
Zeitpunkte <- data.table(expand.grid(Tanke = ID, Zeit = Stichzeit, stringsAsFactors=FALSE))
#------------------- Jetzt der "rolling join": ---------------------------------
# Man sollte sich Gedanken darüber machen, wie für den Fall, dass der
# "Stichzeitpunkt" an einem anderen Tag liegt, verfahren werden soll
Extrakt <- DT[Zeitpunkte, roll="nearest", on = .(Tanke, Zeit)]