Tageswerte über Uhrzeit aggregieren

Alles zum Thema der beschreibenden Statistik

Moderator: jogo

Antworten
bafor26048
Beiträge: 3
Registriert: Do Apr 22, 2021 12:38 pm

Tageswerte über Uhrzeit aggregieren

Beitrag von bafor26048 »

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 :)
Athomas
Beiträge: 768
Registriert: Mo Feb 26, 2018 8:19 pm

Re: Tageswerte über Uhrzeit aggregieren

Beitrag von Athomas »

In "data.table" kann man "rolling joins" veranstalten.
Dabei kann man den Parameter "roll" auf "nearest" setzen - das sollte was für Dich sein!
Benutzeravatar
EDi
Beiträge: 1599
Registriert: Sa Okt 08, 2016 3:39 pm

Re: Tageswerte über Uhrzeit aggregieren

Beitrag von EDi »

So hier?

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)
Muss man überlegen was man bei äquidistanz macht und wie man über gruppen das anwendet (die Beiepisldaten haben das nicht hergegeben).
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
Bild.
bafor26048
Beiträge: 3
Registriert: Do Apr 22, 2021 12:38 pm

Re: Tageswerte über Uhrzeit aggregieren

Beitrag von bafor26048 »

EDi hat geschrieben: Do Jun 10, 2021 6:50 pm So hier?

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)
Muss man überlegen was man bei äquidistanz macht und wie man über gruppen das anwendet (die Beiepisldaten haben das nicht hergegeben).
Hat funktioniert, genau so habe ich es mir vorgestellt, vielen Dank!!
Beeindruckend wie schnell einem hier mit einer schlauen Lösung geholfen wird :shock: echt toll, Danke.
Für die Gruppen habe ich es dann einfach mit group_by über die jeweilige ID der Tankstellen gelöst.
Athomas
Beiträge: 768
Registriert: Mo Feb 26, 2018 8:19 pm

Re: Tageswerte über Uhrzeit aggregieren

Beitrag von Athomas »

Bevor die "data.table"-Lösung (wieder mal :( ) ignoriert wird, hier ein Beispiel mit simulierten Daten:

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)]
Man beachte die Ausführungszeit :shock: !
Antworten