Seite 1 von 2

Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Verfasst: Fr Feb 15, 2019 8:25 pm
von Dodo
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

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Verfasst: Sa Feb 16, 2019 2:07 pm
von jogo
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

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Verfasst: Sa Feb 16, 2019 4:11 pm
von Dodo
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))
}

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Verfasst: Sa Feb 16, 2019 7:06 pm
von jogo
Hallo Dodo,

warum gibst Du keinen Kommentar zu meinem Code?

Gruß, Jörg

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Verfasst: Sa Feb 16, 2019 8:42 pm
von Dodo
Hallo Jörg,
ich konnte es grade eben erst ausprobieren. So funktioniert es ! vielen vielen Dank :)

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Verfasst: So Feb 17, 2019 2:00 pm
von jogo
prima.

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Verfasst: Di Mai 07, 2019 3:16 pm
von Ilonia
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

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Verfasst: Di Mai 07, 2019 4:04 pm
von jogo
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

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Verfasst: Mi Mai 08, 2019 11:01 am
von Athomas
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]

Re: Aufeinanderfolgende Tage mit bestimmter Bedingung erkennen

Verfasst: Mi Mai 08, 2019 11:12 am
von Ilonia
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