Data.table mit unterschiedlichen Ergebnissen

Wie rufe ich R-Funktionen auf, wie selektiere ich Daten, ich weiß nicht genau ....

Moderatoren: EDi, jogo

Regression
Beiträge: 76
Registriert: Mo Jan 15, 2018 9:57 am

Re: Data.table mit unterschiedlichen Ergebnissen

Beitrag von Regression »

jogo hat geschrieben: Mo Mär 05, 2018 2:08 pm sollte der letzte Zyklus auch eine Mindestanzahl von Zeitpunkten haben, damit er für die Regression verwendet wird?
Ja genau mind. 10 Abmessungen sonst soll "insufficient Data" ausgegeben werden.
:!: :!: :!: DANKE :!: :!: :!:
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Data.table mit unterschiedlichen Ergebnissen

Beitrag von jogo »

o.k., dann:

Code: Alles auswählen

library("data.table")
library("readxl")
Example_Set <- read_excel("Example_Set.xlsx")
setDT(Example_Set)

#Gruppen <- Example_Set[, unique(V1)]
Example_Set[, Level_diff := Level - shift(Level), V1]
Example_Set[, Zykl:=rleidv(Level_diff>0), V1]
Example_Set[, .(.N, m=max(Level)), by=.(V1, Zykl)]

whichZykl <- function(Gruppe) {
  Z <- Gruppe[, .(m=max(Level)), by=Zykl]
  if (Z[, .N] %% 2) Z <- tail(Z, -1)
  Z[m>=60, last(Zykl)]
}

date_forecast<-function(Gruppe, Level_alert=10) {
  regZyk <- whichZykl(Gruppe)
  regData <- Gruppe[Zykl %in% c(regZyk-1, regZyk)]
  if (regData[, .N] < 10) return("insufficient Data")
  
  lm1.model <- lm(Date ~ Level, data=regData)
  D <- predict.lm(lm1.model, newdata = data.frame(Level=10))
  as.character(as.POSIXct(D, origin="1970-01-01"))
}

Example_Set[, date_forecast(.SD), by=V1]
Regression
Beiträge: 76
Registriert: Mo Jan 15, 2018 9:57 am

Re: Data.table mit unterschiedlichen Ergebnissen

Beitrag von Regression »

1A !
Sehr schön! DANKE!
Regression
Beiträge: 76
Registriert: Mo Jan 15, 2018 9:57 am

Re: Data.table mit unterschiedlichen Ergebnissen

Beitrag von Regression »

Nun, möchte ich die mittlere Lebenszeit über alle Zyklen berechnen:
Dazu mein Ansatz:

Code: Alles auswählen

whichZykl <- function(Gruppe) {
  Z <- Gruppe[, .(.N, m=max(Level)), by=Zykl]
  #nZ <- Z[, .N]
  #if (nZ %% 2) { Z <- tail(Z, -1); nZ <- nZ -1 }
  Z[m>=60&N>=3]
}

medianLC_forecast<-function(Gruppe, Level_alert=10) {
  D<-c()
  regZyk <- whichZykl(Gruppe)
  for (i in 1:length(regZyk)) {
    regData <- Gruppe[Zykl %in% c(regZyk[i]-1, regZyk[i])]
    if (regData[, .N] < 10){ return("insufficient Data")}
    else{
    lm1.model <- lm(Date ~ Level, data=regData)
    D_0 <- predict.lm(lm1.model, newdata = data.frame(Level=0))
    D_0<-as.Date(D_0, origin="1970-01-01")
    D_100 <- predict.lm(lm1.model, newdata = data.frame(Level=100))
    D_100<-as.Date(D_100, origin="1970-01-01")
    d<-c(D_0,D_100)
    D<-c(D,abs(diff.Date(d)))
    }
    }
  return(median(D))
}
die übrigen Funktionen bleiben wie von Dir angegeben.

leider läuft medianLC_forecast nicht. Wenn ich die Schritte einzeln nacheinander ausführe läuft es... als Funktion noch nicht.
Aber meine eigentliche Frage ist: Lässt sich die For-schleife hier vermeiden?

Danke im Voraus :!:
Nachtrag:
Hier der funktionsfähige Code

Code: Alles auswählen

medianLC_forecast<-function(Gruppe, Level_alert=10) {
  D<-c()
  regZyk <- whichZykl(Gruppe)
  for (i in 1:length(regZyk)) {
    regData <- Gruppe[Zykl %in% c(regZyk[i]-1, regZyk[i])]
    if (regData[, .N] < 10){ return("insufficient Data")}
    else{
    lm1.model <- lm(Date ~ Level, data=regData)
    D_0 <- predict.lm(lm1.model, newdata = data.frame(Level=0))
    D_0<-as.Date(D_0, origin="1970-01-01")
    D_100 <- predict.lm(lm1.model, newdata = data.frame(Level=100))
    D_100<-as.Date(D_100, origin="1970-01-01")
    d<-c(D_0,D_100)
    D<-c(D,abs(diff.Date(d)))
    }
    }
  return(median(D))
}
Die Frage bleibt aber weiterhin bestehen, lässt sich die for-Schleife hier vermeiden?
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Data.table mit unterschiedlichen Ergebnissen

Beitrag von jogo »

Hallo Regression,

ich werde mir Deine Funktion demnächst genauer anschauen.
Stellenweise zweifel ich an der Logik:
1. regZyk muss in Zweierschritten durchlaufen werden.
2. der Rückgabe wert scheint mir nicht schlüssig: meine Idee hierzu wäre, nur D000 und D100 (und vielleicht noch einige Nebeninformation) in das Ergebnis zu packen. Die Berechnung von Median kann dann außerhalb erfolgen.
3. Du hast die Funktion whichZykl() umgestaltet; sie liefert jetzt ein anderes Ergebnis. Deshalb muss auch

Code: Alles auswählen

if (regData[, .N] < 10) { return("insufficient Data") }
umgestaltet werden - eventuell ist next zu verwenden, aber eher würde ich diese Bedingung einer nachfolgenden Funktion überlassen (siehe 2.)

Nachtrag (nur so eine Idee):
Wenn man statt

Code: Alles auswählen

Example_Set[, Zykl:=rleidv(Level_diff>0), V1]
hier eine richtige Nummer für den Zyklus generiert, wird vieles einfacher ...
z.B. (rleidv(...) +1) %/% 2
Was hältst Du davon?

Gruß, Jörg
Regression
Beiträge: 76
Registriert: Mo Jan 15, 2018 9:57 am

Re: Data.table mit unterschiedlichen Ergebnissen

Beitrag von Regression »

jogo hat geschrieben: Mi Mär 07, 2018 2:22 pm
Stellenweise zweifel ich an der Logik:
1. regZyk muss in Zweierschritten durchlaufen werden.
In diesem Fall ja, da ich nur zwei Lebenszyklen habe, allerdings habe ich auch gruppen die bis zu 10 Lebenszyklen haben.
jogo hat geschrieben: Mi Mär 07, 2018 2:22 pm 2. der Rückgabe wert scheint mir nicht schlüssig: meine Idee hierzu wäre, nur D000 und D100 (und vielleicht noch einige Nebeninformation) in das Ergebnis zu packen. Die Berechnung von Median kann dann außerhalb erfolgen.
Wie meinst Du es?
da, die Daten meist unvollständig sind, Berechne ich den Zeitpunkt mit Level=100 und den mit Level=0, damit ich zwei Daten zum "Start und Endpunkt" habe. Die Differenz der beiden Werte ergibt dann die Lebensdauer von diesem Zyklus.

jogo hat geschrieben: Mi Mär 07, 2018 2:22 pm Nachtrag (nur so eine Idee):
Wenn man statt

Code: Alles auswählen

Example_Set[, Zykl:=rleidv(Level_diff>0), V1]
hier eine richtige Nummer für den Zyklus generiert, wird vieles einfacher ...
z.B. (rleidv(...) +1) %/% 2
Was hältst Du davon?
Hier kann ich Dir leider nicht folgen

Code: Alles auswählen

Example_Set[, Zykl:=rleidv(Level_diff>0), V1]
Generiert doch bereits eine Richtige Nummer für den Zyklus, entsprechend der Gruppe.

LG
Regression
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Data.table mit unterschiedlichen Ergebnissen

Beitrag von jogo »

Regression hat geschrieben: Do Mär 08, 2018 10:41 am
jogo hat geschrieben: Mi Mär 07, 2018 2:22 pm
Stellenweise zweifel ich an der Logik:
1. regZyk muss in Zweierschritten durchlaufen werden.
In diesem Fall ja, da ich nur zwei Lebenszyklen habe, allerdings habe ich auch gruppen die bis zu 10 Lebenszyklen haben.
Es gehören momentan immer zwei Werte von $Zykl zu einem Zyklus:
1. die Flanke (eine positive Differenz)
2. die nachfolgende Degression (die nachfolgenden negativen Differenzen)
Bitte schaue Dir dazu die Daten an:

Code: Alles auswählen

library("data.table")
library("readxl")
Example_Set <- read_excel("Example_Set.xlsx")
setDT(Example_Set)

Gruppen <- Example_Set[, unique(V1)]
Example_Set[, Level_diff := Level - shift(Level), V1]
Example_Set[, Zykl:=rleidv(Level_diff>0), V1]
Example_Set[, .(.N, m=max(Level)), by=.(V1, Zykl)]
Example_Set[V1==Gruppen[5]]
# oder besser noch:
Example_Set[V1==Gruppen[7]]
jogo hat geschrieben: Mi Mär 07, 2018 2:22 pm 2. der Rückgabe wert scheint mir nicht schlüssig: meine Idee hierzu wäre, nur D000 und D100 (und vielleicht noch einige Nebeninformation) in das Ergebnis zu packen. Die Berechnung von Median kann dann außerhalb erfolgen.
Wie meinst Du es?
da, die Daten meist unvollständig sind, Berechne ich den Zeitpunkt mit Level=100 und den mit Level=0, damit ich zwei Daten zum "Start und Endpunkt" habe. Die Differenz der beiden Werte ergibt dann die Lebensdauer von diesem Zyklus.
ach so; und von der Lebensdauer willst Du dann über die Zyklen hinweg den Median bestimmen, richtig?
jogo hat geschrieben: Mi Mär 07, 2018 2:22 pm Nachtrag (nur so eine Idee):
Wenn man statt

Code: Alles auswählen

Example_Set[, Zykl:=rleidv(Level_diff>0), V1]
hier eine richtige Nummer für den Zyklus generiert, wird vieles einfacher ...
z.B. (rleidv(...) +1) %/% 2
Was hältst Du davon?
Hier kann ich Dir leider nicht folgen

Code: Alles auswählen

Example_Set[, Zykl:=rleidv(Level_diff>0), V1]
Generiert doch bereits eine Richtige Nummer für den Zyklus, entsprechend der Gruppe.
siehe oben
Die Operation (... + 1) %/% 2 führt zu folgenden Ergebnissen:
1 --> 1
2 --> 1
3 --> 2
4 --> 2
...

Gruß, Jörg
Regression
Beiträge: 76
Registriert: Mo Jan 15, 2018 9:57 am

Re: Data.table mit unterschiedlichen Ergebnissen

Beitrag von Regression »

jogo hat geschrieben: Do Mär 08, 2018 2:02 pm ach so; und von der Lebensdauer willst Du dann über die Zyklen hinweg den Median bestimmen, richtig?
Ja- exakt!
jogo
Beiträge: 2085
Registriert: Fr Okt 07, 2016 8:25 am

Re: Data.table mit unterschiedlichen Ergebnissen

Beitrag von jogo »

Code: Alles auswählen

library("data.table")
library("readxl")
Example_Set <- read_excel("Example_Set.xlsx")
setDT(Example_Set)

Gruppen <- Example_Set[, unique(V1)]
Example_Set[, Level_diff := Level - shift(Level), V1]
Example_Set[, z:=rleidv(Level_diff>0), V1]
Example_Set[, Zykl := (z+1) %/% 2]

Example_Set[, .(.N, m=max(Level)), by=.(V1, Zykl, z)]
# Example_Set[V1==Gruppen[5]]
# Example_Set[V1==Gruppen[7]]
# Gruppen

whichZykl <- function(Gruppe) {
  Z <- Gruppe[, .(.N, m=max(Level)), by=.(Zykl, z)]
  if (Z[, .N] %% 2) Z <- tail(Z, -1)
  Z[m>=60, last(Zykl)]
}

date_forecast<-function(Gruppe, Level_alert=10) {
  regZyk <- whichZykl(Gruppe)
  regData <- Gruppe[Zykl==regZyk]
  if (regData[, .N] < 10) return("insufficient Data")
  
  lm1.model <- lm(Date ~ Level, data=regData)
  D <- predict.lm(lm1.model, newdata = data.frame(Level=10))
  as.character(as.POSIXct(D, origin="1970-01-01"))
}

Example_Set[, date_forecast(.SD), by=V1]
Example_Set[, head(.SD,1), by=.(V1, Zykl)]
Example_Set[, tail(.SD,1), by=.(V1, Zykl)]

#######################

ZyklDauer <- function(ZyklData) { ### berechnet nicht wirklich die Dauer, sondern
                                  ### die Zeitpunkte für Level=100 und Level=0
  lm1.model <- lm(Date ~ Level, data=ZyklData)
  
  D <- predict.lm(lm1.model, newdata = data.frame(Level=c(100, 0)))
  D <- as.POSIXct(D, origin="1970-01-01")
  return(list(D100=D[1], D000=D[2], n=ZyklData[, .N]))
}

D <- Example_Set[, ZyklDauer(.SD), by=.(V1, Zykl)]
D[, Dauer := D000-D100]
D[n>=10, .(medDauer=median(Dauer)), V1]
so meinte ich das mit der Trennung von Datenwühlerei und Bestimmung des Medians

Gruß, Jörg
Regression
Beiträge: 76
Registriert: Mo Jan 15, 2018 9:57 am

Re: Data.table mit unterschiedlichen Ergebnissen

Beitrag von Regression »

Wow... DANKE Jörg!
Hast mir wirklich geholfen :!: :!: :!:
Möchte nun den Letzten Lebenszyklus ploten:

Code: Alles auswählen

plot_last_flanc<-function(Gruppe) {
  regZyk <- whichZykl(Gruppe)
  regData <- Gruppe[Zykl %in% c(regZyk-1, regZyk)]
  
  lm1.model <- lm(Date ~ Level, data=regData)
  t<-regData$V1[1]
  plot( regData$Date ~ regData$Level,  main=t)
 abline(lm1.model, col="red")
  }
  Example_Set[, plot_last_flanc(.SD), by=V1]
  
Funktioniert alles soweit gut, außer dass der Titel übergeben wird :?: :|

Ist bestimmt etwas sehr simples was ich grad nicht sehe, hast Du eine Idee?

Danke im Voraus!
Antworten