Geschachtelte Funktionen in rollapply

Wie erweitere ich R um eigene Funktionen oder Pakete? Welches Paket ist passend für meine Fragestellung?

Moderatoren: EDi, jogo

Antworten
Marge

Geschachtelte Funktionen in rollapply

Beitrag von Marge »

Guten Tag zusammen,

für die Analyse von Datensätzen möchte ich ein R-Skript schreiben, mit dem ich verschiedene statistische Größen berechnen kann.
Dafür teile ich die Datensätze mit der Funktion rollapply in Gruppen ein und wende Funktionen wie mean (Mittelwert) oder sd (Standardabweichung) an - das ist soweit auch kein Problem. Allerdings möchte ich auch Größen wie Root Mean Square (rms), Median Absolute Deviation (mad) oder die Korrelation ermittlen.
Nehmen wir beispielsweise die Berechnung von mad: Dabei stehe ich vor der Herausforderung, dass ich einerseits die Daten mit rollapply gruppieren und gleichzeitig die einzelnen Werte der Gruppen mit den entsprechenden Gruppenmittelwerten der vorher berechneten Mittelwerte verrechnen möchte.
Ich habe die folgende Lösung gebastelt, die ist für eine große Datenmenge wie ich sie habe allerdings umständlich und ungeeignet:

Code: Alles auswählen

t <- c(1:10)
x <- c(5:14)
res <- sqrt(t^2 + x^2)
test <- data.frame(t, x, res)
# Berechnen der Mittelwerte von jeweils 5 Werten
mean <- rollapply(test$res, width = 5, FUN=mean, by = 5, partial =TRUE, align = 'left')
mean
# Berechnen von mad von den ersten 5 Werten aus res und dem Mittelwert der ersten Gruppe
mad1 <- mad(test$res[1:5], center = mean[1])
mad1
# Berechnen von mad von den nächsten 5 Werten aus res und dem Mittelwert der nächsten Gruppe
mad2 <- mad(test$res[5:10], center = mean[2])
mad2
# Und so weiter für alle Gruppen
In der Dokumentation zu rollapply habe ich gesehen, dass man mit dem Funktions-Argument

Code: Alles auswählen

FUN=funktion(z)
und einem nachfolgenden Argument auch nicht vorprogramierte Funktionen angewenden kann. Das habe ich auch ausprobiert, allerdings nicht hinbekommen:

Code: Alles auswählen

mad <- rollapply(test$res, width = 5, FUN=funktion(test$res) mad(test$res[1:5], center = mean[1]), by = 5, partial =TRUE, align = 'left')
Gibt es eine Möglichkeit, eine solch geschachtelte Funktion zu erstellen, damit ich nicht alles für jede Gruppe einzeln erstellen muss?
Vielen Dank vorab und viele Grüße
Marge
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Geschachtelte Funktionen in rollapply

Beitrag von jogo »

Hallo Marge,

willkommen im Forum!
es könnte so aussehen:

Code: Alles auswählen

mad <- rollapply(test$res, width = 5, FUN=function(x) mad(x, center = mean(x)), by = 5, partial =TRUE, align = 'left')
Gruß, Jörg
Marge

Re: Geschachtelte Funktionen in rollapply

Beitrag von Marge »

Hallo Jörg,

vielen Dank für deine Antwort! Ich habe deinen Code ausprobiert und so funktioniert es einwandfrei :)
Mir hat sich allerdings eine Verständnisfrage gestellt: Setzt R für das x in der Funktion nur einen Wert ein oder ist das x die Nummer der Gruppe mit den fünf Werten und dadurch wird auch der Mittelwert der x-ten Gruppe gewählt? Da die ausgegebenen Ergebnisse mit meinen manuell berechneten Werten übereinstimmen, gehe ich davon aus, dass es die zweite Variante ist.

Ich konnte mit deinem Hinweis auch die Funktionen für die anderen Größen erstellen die ich berechnen möchte, außer der Korrelation. Da stehe ich vor dem Problem, dass ich nicht nur eine, sondern zwei Variablen habe. Meine Idee ist folgende:

Code: Alles auswählen

korr <- rollapply(test$x, width = 250, FUN=function(x) (cov(x, test$t)/(sd(x)*sd(test$t))), by = 250, partial =TRUE, align = 'left')
funktionieren tut es leider noch nicht.. Gibt es dafür auch eine Lösung?

Viele Grüße und ein sonniges Wochenende
Marge
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Geschachtelte Funktionen in rollapply

Beitrag von jogo »

Marge hat geschrieben: Sa Jun 09, 2018 4:54 pm vielen Dank für deine Antwort! Ich habe deinen Code ausprobiert und so funktioniert es einwandfrei :)
sehr schön, es freut mich, das zu hören.
Mir hat sich allerdings eine Verständnisfrage gestellt: Setzt R für das x in der Funktion nur einen Wert ein oder ist das x die Nummer der Gruppe mit den fünf Werten und dadurch wird auch der Mittelwert der x-ten Gruppe gewählt? Da die ausgegebenen Ergebnisse mit meinen manuell berechneten Werten übereinstimmen, gehe ich davon aus, dass es die zweite Variante ist.
Das x steht für den Vektor der fünf Werte (bei width=5) entsprechend dem definierten Fenster.
Ich konnte mit deinem Hinweis auch die Funktionen für die anderen Größen erstellen die ich berechnen möchte, außer der Korrelation. Da stehe ich vor dem Problem, dass ich nicht nur eine, sondern zwei Variablen habe.
Das Fenster soll parallel über beide Vektoren laufen, ist das richtig?
Meine Idee ist folgende:

Code: Alles auswählen

korr <- rollapply(test$x, width = 250, FUN=function(x) (cov(x, test$t)/(sd(x)*sd(test$t))), by = 250, partial =TRUE, align = 'left')
funktionieren tut es leider noch nicht.. Gibt es dafür auch eine Lösung?
alles, was man als endlichen Algorithmus formulieren kann, kann man auch entsprechend programmieren.
kurz: ja, es gibt dafür eine Lösung.
Dich dürfte nun eher die Antwort auf die zwangsläufig logisch folgende Frage interessieren: Wie sieht eine solche Lösung aus? ;)
Trotzdem noch eine Frage von mir, warum verwendest Du nicht cor() ?

Viele Grüße
Jörg
p.s.:
Darüber, wie eine solche Lösung aussieht, muss auch ich erstmal nachdenken.
Vielleicht wird es etwas wie:

Code: Alles auswählen

rollapply(1:length(test$x), width=..., FUN=function(I) cor(test$x[I], test$t[I]))
Du kannst ja schon mal probieren, ob das so klappt.
Marge

Re: Geschachtelte Funktionen in rollapply

Beitrag von Marge »

Hallo Jörg,
Das Fenster soll parallel über beide Vektoren laufen, ist das richtig?
Genau, also es sollen beide Vektoren in gleiche, regelmäßige Fenster geteilt werden.

Zu der Frage, warum ich nicht cor() benutze: Ich habe eine Quelle, an die ich mich bei der Berechnung der Größen halten möchte und da wird diese Berechnung verwendet - obwohl ich inzwischen gemerkt habe, dass beide die selben Ergebnisse liefern ;)

Und zu deinem Vorschlag, wie die Lösung aussehen könnte: Die funktioniert soweit! Nur verstehe ich nicht ganz, was das

Code: Alles auswählen

1:length(text$x)
bewirkt und bedeutet? Bzw. warum es da nicht reicht, wieder

Code: Alles auswählen

text$x
zu schreiben?

Viele Grüße
Marge
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Geschachtelte Funktionen in rollapply

Beitrag von jogo »

Hallo Marge,
Marge hat geschrieben: So Jun 10, 2018 7:08 pm Zu der Frage, warum ich nicht cor() benutze: Ich habe eine Quelle, an die ich mich bei der Berechnung der Größen halten möchte und da wird diese Berechnung verwendet - obwohl ich inzwischen gemerkt habe, dass beide die selben Ergebnisse liefern ;)
jepp
Und zu deinem Vorschlag, wie die Lösung aussehen könnte: Die funktioniert soweit! Nur verstehe ich nicht ganz, was das

Code: Alles auswählen

1:length(text$x)
bewirkt und bedeutet? Bzw. warum es da nicht reicht, wieder

Code: Alles auswählen

text$x
zu schreiben?
Wir benötigen diesmal nicht die Werte von x, sondern die Indizes der Werte von x, über die das Fenster läuft.
Statt 1:length(test$x) kann man auch seq_along(test$x) schreiben oder auch 1:nrow(test) oder seq_len(nrow(test)).

Viele Grüße
Jörg
Marge

Re: Geschachtelte Funktionen in rollapply

Beitrag von Marge »

Hallo Jörg,

danke, dass du dir die Zeit nimmst, meine Fragen zu beantworten! Es ist mir wichtig, dass ich verstehe, wie der Code funktioniert.
Aber leider muss ich zugeben, dass sich mir das mit den Indizes noch nicht vollständig erschlossen hat.
Wir benötigen diesmal nicht die Werte von x, sondern die Indizes der Werte von x, über die das Fenster läuft.
Warum brauchen wir denn nicht die Werte? Werden die nicht für die Berechnung gebraucht?
Ansonsten verstehe ich es so, dass die Fenster dieses Mal über die Indizes gelegt werden und dann die Korrelation der zwei Vektoren für diese Fenster berechnet wird - genau das, was gemacht werden soll.

Viele Grüße
Marge
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Geschachtelte Funktionen in rollapply

Beitrag von jogo »

Hallo Marge,
ich hatte mich vorher ungeschickt ausgedrückt:
natürlich werden für die Berechnung letztendlich die Werte der beiden Vektoren benötigt.
Am besten wäre eine Funktion, die wie rollapply() über die Vektoren läuft - und zwar parallel über mindestens zwei Vektoren (so wie mapply()).
Leider ist mir so eine Funktion nicht bekannt - gerne lerne ich hinzu. Andererseits kann man das Fenster über den Vektor mit den Indizes laufen lassen - das Indexfenster kann dann für beide Vektoren verwendet werden, um die für die Berechnung benötigten Werte zu extrahieren.

Nachtrag:
rollapply() kann auch Dataframes verarbeiten (also multivariate (=mehrere) Zeitreihen).
Dabei hat die Verarbeitung einer Variablen jedoch nichts mit der Verarbeitung einer anderen Variable zu tun
- somit ist diese Funktion ungeeignet, um die rollende Korrelation zwischen zwei Variablen direkt (in dem Sinne, dass man einfach diese beiden Variablen an rollapply() übergeben könnte und nur die Funktion FUN= geeignet definieren muss) zu berechnen

Gruß, Jörg
Antworten