Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

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

Moderatoren: EDi, jogo

Dodo
Beiträge: 8
Registriert: Fr Feb 15, 2019 8:00 pm

Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Beitrag von Dodo » Fr Feb 15, 2019 8:25 pm

Hallo Liebe Forum-Community,
Ich verzweifle an folgender Aufgabe. Ich habe folgende Dataframe.

Code: Alles auswählen

        Datum Bedingung
1  01.01.2011         N
2  02.01.2011         N
3  03.01.2011         Y
4  04.01.2011         Y
5  05.01.2011         Y
6  06.01.2011         N
7  07.01.2011         N
8  08.01.2011         Y
usw....

Nun möchte ich gerne "Events" aus der Dataframe rauslesen. Ein Event ist, wenn bei mindestens 3 aufeinanderfolgenden Tage die Bedingung "Y" ist.
Ich würde gerne solche Events erkennen und jeweils den Start, das Ende und die Dauer des Events als Output haben. Leider kenne ich mich mit R noch nicht so gut aus und weiß nicht weiter. Ich habe einige Ansätze probiert, komme aber zu keinem Ergebnis.


Vielen Dank für eure Hilfe

mit freundlichen Grüßen

Dodo

jogo
Beiträge: 1310
Registriert: Fr Okt 07, 2016 8:25 am

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Beitrag von jogo » Sa Feb 16, 2019 2:07 pm

Hallo Dodo,

willkommen im Forum!
Was hast Du denn bis jetzt probiert? Kannst Du uns das bitte zeigen?
(achte dabei auch auf die Formatierung von Code und Daten, siehe viewtopic.php?f=20&t=29 )
Ich bastel zur Zeit an einer Lösung unter Verwendung der Funktion rle()

Nachtrag (meine bisherige Bastelei):

Code: Alles auswählen

dat <- read.table(header=TRUE, stringsAsFactors = FALSE, text=
"Zeile Datum Bedingung
1 01.01.2011 N
2 02.01.2011 N
3 03.01.2011 Y
4 04.01.2011 Y
5 05.01.2011 Y
6 06.01.2011 N
7 07.01.2011 N
8 08.01.2011 Y")
r <- rle(dat$Bedingung)
R <- as.data.frame(unclass(r))
w <- which(R$values=="Y" & R$lengths>2)

cumsum(c(1, R$lengths))[w] # mit welchen Beobachtungen beginnen die Sequencen?
dat$Datum[cumsum(c(1, R$lengths))[w]] # Beginn
R$lengths[w] # wie lange dauern die gesuchten Sequenzen?
Gruß, Jörg

Dodo
Beiträge: 8
Registriert: Fr Feb 15, 2019 8:00 pm

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Beitrag von Dodo » Sa Feb 16, 2019 4:11 pm

Hallo Jörg,
vielen Dank erstmal für deine Hilfe.
Leider kenne ich mich in R noch nicht so gut aus und ich kenne nicht viele Funktionen. Bisher habe ich versucht die Events über eine for-Schleife mit if/else Verzweigung zu finden.

Code: Alles auswählen

Daten <-read.table("Test.txt", header=TRUE)
Nummer <-data.frame(Nummer=1:length(Daten$Datum))
Datenn <-cbind(Daten, Nummer)


DatennurY <-subset(Datenn, Tag=="Y")
DatennurY


fkt <-function(Datum, Nummer) {
  Event <-matrix(nrow=length(Nummer))
  for (i in 1:length(Nummer)){
    if (Nummer[i]+1==Nummer[i+1]){
      if (Nummer[i+1]+1==Nummer[i+2]){
        Event[i] <-"Y"
        Event[i+1] <-"Y"
        Event[i+2] <-"Y" 
      }
    } else {
      Event[i] <-"N"
      if (Nummer[i+1]+1==Nummer[i+2]) {
        if (Nummer[i+2]+1==Nummer[i+3]) {
          Event[i+1] <-"Y"
          Event[i+2] <-"Y"
          Event[i+1] <-"Y"
        }
      } else {
        Event[i+1] <-"N"
        if (Nummer[i+2]+1==Nummer[i+3]) {
          if(Nummer[i+3]+1)==Nummer[i+4]{
            Event[i+2] <-"Y"
            Event[i+3] <-"Y"
            Event[i+3] <-"Y"
          }
        } else {
          Event[i+2] <-"N"
        }
      }
    }
  }
  return(data.frame(Datum=Datum, Nummer=Nummer, Event=Event))
}

jogo
Beiträge: 1310
Registriert: Fr Okt 07, 2016 8:25 am

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Beitrag von jogo » Sa Feb 16, 2019 7:06 pm

Hallo Dodo,

warum gibst Du keinen Kommentar zu meinem Code?

Gruß, Jörg

Dodo
Beiträge: 8
Registriert: Fr Feb 15, 2019 8:00 pm

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Beitrag von Dodo » Sa Feb 16, 2019 8:42 pm

Hallo Jörg,
ich konnte es grade eben erst ausprobieren. So funktioniert es ! vielen vielen Dank :)

jogo
Beiträge: 1310
Registriert: Fr Okt 07, 2016 8:25 am

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Beitrag von jogo » So Feb 17, 2019 2:00 pm

prima.

Ilonia
Beiträge: 20
Registriert: Mi Aug 09, 2017 3:50 pm

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Beitrag von Ilonia » Di Mai 07, 2019 3:16 pm

Hallo zusammen!

Ich krame diesen alten Thread mal raus. Habe diesen gefunden, weil ich nach der Berechnung von der Dauer von Events gesucht habe. Das Ergbnis hat mir schon geholfen :)

Jetzt würde ich aber gerne aus einer weiteren Spalte die Summe bilden, die in diesem Zeitraum aufgetreten ist.

Die Grundlage ist der DF dat von oben im Post.

An diesen füge ich nun eine Spalte hinzu

Code: Alles auswählen

dat$Zahl <- c(0,0,2,5,3,0,0,2)
Als nächstes füge ich in einem weitern df die Dauer sowie der Beginn des Ereignisses zusammen, wie oben schon beschrieben

Code: Alles auswählen

df<- data.frame(dat$Datum[cumsum(c(1, R$lengths))[w]])
colnames(df)[1] <- c("Beginn")

df$Dauer <- R$lengths[w]
Was ich mir nun gerne noch hätte, wäre eine weitere Spalte in der für den Zeitraum mit "Y" die Werte der Spalte "Zahl" aufsummiert werden und in den neuen df als Spalte hinzugefügt werden. In diesem Beispiel sollte eine 10 in der Spalte stehen.

Ich habe versucht mit

Code: Alles auswählen

sum(dat[which(dat[,3]=="Y"),4])
die Summe zu bekommen, aber logischerweise kommt da nur die komplette Summe aller Werte in der Spalte raus.

Ich hoffe ich konnte mein Anliegen deutlich genug beschreiben.
Über Hilfe würde ich mich freuen!

Liebe Grüße

jogo
Beiträge: 1310
Registriert: Fr Okt 07, 2016 8:25 am

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Beitrag von jogo » Di Mai 07, 2019 4:04 pm

Hallo Ilonia,

so sollte es gehen:

Code: Alles auswählen

dat <- read.table(header=TRUE, stringsAsFactors = FALSE, text=
"Zeile Datum Bedingung
1 01.01.2011 N
2 02.01.2011 N
3 03.01.2011 Y
4 04.01.2011 Y
5 05.01.2011 Y
6 06.01.2011 N
7 07.01.2011 N
8 08.01.2011 Y")
dat$Zahl <- c(0,0,2,5,3,0,0,2)

r <- rle(dat$Bedingung)
R <- as.data.frame(unclass(r))
w <- which(R$values=="Y" & R$lengths>2)

b <- cumsum(c(1, R$lengths))[w]
df<- data.frame(Beginn=b, Dauer=R$lengths[w], Zsum=sum(dat$Zahl[b:(b+R$lengths[w]-1)]))
df
oder man verwendet mal seq() zum indizieren:

Code: Alles auswählen

df <- data.frame(Beginn=b, Dauer=R$lengths[w], Zsum=sum(dat$Zahl[seq(b, length.out=R$lengths[w])]))
Gruß, Jörg

Athomas
Beiträge: 176
Registriert: Mo Feb 26, 2018 8:19 pm

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Beitrag von Athomas » Mi Mai 08, 2019 11:01 am

Ich habe noch eine Alternative mit data.table gebastelt, die mir - wenn man sich mit data.table auskennt - etwas übersichtlicher erscheint.
Der wesentliche Teil ist die Berechnung der "EventNr":

Code: Alles auswählen

library(data.table)

#         >>> Beispieldaten

Beginn <- as.Date("2019-01-01")   
Ende   <- as.Date("2019-02-28")
Tage   <- seq(Beginn, Ende, by="1 day")
DT     <- data.table(Datum     = Tage, 
                     Bedingung = sample(c(TRUE,FALSE),length(Tage), replace=TRUE), 
                     Wert      = sample(1:10, length(Tage), replace=TRUE)
                     )
#         >>> Ende Beispieldaten

DT[  , EventNr:=cumsum(c(TRUE, tail(Bedingung, -1)!=head(Bedingung, -1) | !tail(Bedingung, -1)))]
DT[  , .(MinDat     = min(Datum), 
         MaxDat     = max(Datum), 
         AnzahlTage = .N, 
         SumWert    = sum(Wert), 
         Art        = min(Bedingung)), 
     by=EventNr][Art==1]
"Man kann richtige Fragen stellen und trotzdem falsche Antworten geben" (A. Nahles, 2019)

Ilonia
Beiträge: 20
Registriert: Mi Aug 09, 2017 3:50 pm

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Beitrag von Ilonia » Mi Mai 08, 2019 11:12 am

Hallo Jörg,

vielen Dank für deinen Code!
Er hat funktioniert!
Leider war ich etwas zu naiv und dachte ich kann ihn auf meine persönliche Problematik anwenden, was nicht funktioniert hat.
In diesem Beispiel war ja am Ende nur ein "Event" von Bedeutung.
Wenn man allerdings alle "Events" mit der Bedingung "Y" haben will und

Code: Alles auswählen

w <- which(R$values=="Y" & R$lengths>0)
setzt, hat dein Code leider nicht funktioniert.
Ich habe dann etwas rumgebastelt und bin zu folgender (nicht sehr sauberen, aber erfolgreichen! ) Lösung gekommen :)
Dabei habe ich deine letzte Zeile in zwei Schritte umgewandelt:

Code: Alles auswählen

df<- data.frame(Beginn=b, Dauer=R$lengths[w])

for(i in seq(1,length(b))){
  df$zsum[i]<-sum(dat$Zahl[b[i]:(b[i]+R$lengths[w[i]]-1)])
}
Dennoch vielen Dank für deine Hilfe!

LG

Antworten

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast