Hallo Bernhard,
ich habe mal getestet, sowohl mit neu kreierten Datensätzen als auch in meinem Originaldatensatz.
Schritt 1 (Finde heraus, welche Zeilen zusammengefasst werden sollen) scheint zuverlässig zu klappen. In den kleinen "künstlichen" Datensätzen hat alles gepasst. Der Originaldatensatz hat 73000 Beobachtungen und nur knapp 400 erfüllen die Kriterien. Ich kann nicht sagen, ob alle einschlägigen Fälle erkannt wurden, aber die Fälle, die erkannt wurden, wurden korrekt erkannt, das habe ich "händisch". Soweit so gut.
Probleme habe ich bei Schritt 2 (Fasse Zeilen zusammen). Das Ergebnis ist eine Liste, in der jede der verbleibenden Beobachtungen ein Element darstellt. Jedes dieser Elemente ist ein Tibble. Sofern die Variablen nicht verändert wurden, sind es normale Spalten des jeweiligen Tibble. Die Spalte der Variablen, die verändert wurden (im Beispiel unten das Stoppdatum und Var2) sind aber widerum selbst Tibble, deren Elemente wiederum die Variablenwerte sind. Ich gestehe, meine Beschreibung ist deswegen so holprig, weil ich die Struktur selbst noch nicht durchblicke. Vielleicht ist das Beispiel hilfreicher:
Ich habe unten das Beispiel aktualisiert. Bitte beachte:
- In meiner ursprünglichen Beschreibung war das Stoppdatum der vorhigen Beobachtung eines Blocks das Startdatum der nächsten Beobachtung. Im Originaldatensatz liegt das Stoppdatum ein Tag vor dem Startdatum. Ich habe dies sowohl in den Beispiel als auch in deinem Code angepasst.
- ich habe deinen Code so überarbeitet, dass die Variablennamen etc zum Beispiel passen.
- Das Ergebnis des Schritt 2 (Fasse Zeilen zusammen) wird als Objekt "neu" gespeichert und dann in einen tibble (df_2) umgewandelt.
Code: Alles auswählen
# 0. Erzeuge Beispieldatensatz
library(tidyverse)
Id<-c(1,1,1,1,2,3,3,3)
Startdatum<-as.Date(c("2020-06-22","2020-06-25","2020-07-29","2020-08-16","2020-06-22","2020-09-22","2020-09-24","2020-10-22"))
Stoppdatum<-as.Date(c("2020-06-24","2020-07-28","2020-08-02","2020-08-19","2020-06-24","2020-09-23","2020-09-28","2020-10-22"))
Var1<-c("a","b","c","D","E","g","H","J")
Var2<-c("g","h","j","k","l","K","L","B")
df<-tibble(Id,Startdatum,Stoppdatum,Var1,Var2)
# 1. Finde heraus, welche Zeilen zusammengefasst werden sollen
lines <- nrow(df)
join <- integer(lines)
i <- 1 # markiert die gerade bearbeiteten Zeilen in d
ji <- 1 # zählt die gerade bearbeitete Gruppe zusammengehöriger Zeilen und wird in join eingetragen
while(TRUE){
join[i] <- ji
if (i >= lines) break
i <- i + 1
if(df$Id[i-1] != df$Id[i] | (df$Stoppdatum[i-1] + 1) != df$Startdatum[i]) ji <- ji + 1
}
print(join) # Das ist ein Vector mit einem Eintrag pro Zeile im Datensatz
# Zeilen mit gleichem Eintrag in join müssen zusammengefasst werden
# 2. Fasse Zeilen zusammen
neu<-by(df, join, FUN = function(ausschnitt){
r <- ausschnitt[1,] # r steht für result und ist erstmal eine Kopie der ersten Zeile jedes Blocks
r$Stoppdatum <- ausschnitt[nrow(ausschnitt), "Stoppdatum"]
# TODO: hier ggf. noch Werte von Var1, Var2, Var3 etc anpassen
r$Var2 <- ausschnitt[nrow(ausschnitt), "Var2"]
r
})
# 3. wandle "neu" in einen normalen tibble um:
df_2<- do.call("rbind", neu)
# ==> das ist leider noch kein "normaler" tibble. Die einzelnen Zelleinträge in den Spalten Stoppdatum und Var2 sind selbst widerum tibbles.
str(df_2$Stoppdatum)
Kurz, meine Frage wäre: wie wandle ich das Objekt "neu" in einen herkömmlichen Tibble um?
Herzliche Grüße
Jörg