Datenaufbereitung Bachelorarbeit

Allgemeine Fragen zur Programmierung mit R.

Datenaufbereitung Bachelorarbeit

Beitragvon Martha » Di 13. Aug 2019, 12:47

Hallo!
Nachdem ich jetzt schon wirklich lange versuche, halbwegs alleine (hab schon 2x Fragen im Forum gestellt) mit der Aufbereitung und Auswertung der Daten für meine Bachelorarbeit klarzukommen, gebe ich dies jetzt auf. Ich brauche dringend Hilfe. Es hängt ständig an Kleinigkeiten...
Um was geht's? Ich habe eine Tabelle mit Daten, die über mehrere Jahre zu mehreren Hundert Lämmern erhoben wurden. Mir geht es vor allem um die Gewichte. Zu jedem Lamm gibt es in einer Spalte ein Geburtsgewicht und in einer anderen Gewichtsdaten, die zu unterschiedlichen Zeitpunkten erhoben wurden. Daraus folgt, dass jedes Lamm mehrere Zeilen hat, in denen alle Daten, außer die Gewichtsdaten und das passende Datum dazu, übereinstimmen. Fehler konnte ich soweit schon aussortieren/korrigieren und die Tabelle in eine einigermaßen ordentliche Form bringen.
Hier ein kleiner Ausschnitt der Tabelle:
Unbenannt.JPG
Unbenannt.JPG (38.98 KiB) 64-mal betrachtet

TIERNR_neu beinhaltet immer die Rasse (hier nur Merinos = ML) und die Tiernummer (365, 387, 391). Es wurde nicht immer nur 3x gewochen, manchmal auch mehr oder weniger. Auch die zeitlichen Abstände dazwischen variieren.

Jetzt würde ich gerne eine neue Spalte einfügen, in welcher mir die absoluten Zunahmen angezeigt werden. Es müsste also die 1. Wiegung minus das Geburtsgewicht, dann die 2. Wiegung minus die 1. etc.pp. gerechnet werden - und das für jedes Tier individuell. Hat jemand einen Tipp, wie ich das bewerkstelligen kann?

Und wie kann ich anschließend die Daten anhand den Tagen nach der Geburt in Gruppen aufteilen, um zu sehen, ob es signifikante Unterschiede in Woche X nach der Geburt gibt?

Vielen Dank schonmal für eure Hilfe! Das Forum ist echt super :) Danke, danke, danke!

Liebe Grüße
Martha
Martha
 
Beiträge: 7
Registriert: Mo 29. Jul 2019, 16:30
Danke gegeben: 0
Danke bekommen: 0 mal in 0 Post

Re: Datenaufbereitung Bachelorarbeit

Beitragvon jogo » Di 13. Aug 2019, 21:18

Hallo Martha,

Martha hat geschrieben: Ich habe eine Tabelle mit Daten, die über mehrere Jahre zu mehreren Hundert Lämmern erhoben wurden. Mir geht es vor allem um die Gewichte. Zu jedem Lamm gibt es in einer Spalte ein Geburtsgewicht und in einer anderen Gewichtsdaten, die zu unterschiedlichen Zeitpunkten erhoben wurden. Daraus folgt, dass jedes Lamm mehrere Zeilen hat, in denen alle Daten, außer die Gewichtsdaten und das passende Datum dazu, übereinstimmen. Fehler konnte ich soweit schon aussortieren/korrigieren und die Tabelle in eine einigermaßen ordentliche Form bringen.
Hier ein kleiner Ausschnitt der Tabelle: ...
Kannst Du bitte den output von
Code: Alles auswählen
str(DeinDataframe)
in die nächste Nachricht kopieren? Besonders bei Datumsangaben sieht man bei Bildern nicht, ob es character oder ein richtiges Datumsformat ist. Noch besser wäre es, Du würdest den output von
Code: Alles auswählen
dput(head(DeinDataframe, 10))
zeigen.

TIERNR_neu beinhaltet immer die Rasse (hier nur Merinos = ML) und die Tiernummer (365, 387, 391). Es wurde nicht immer nur 3x gewochen, manchmal auch mehr oder weniger. Auch die zeitlichen Abstände dazwischen variieren.
Sind die Werte der Wägungen chronologisch sortiert?

Jetzt würde ich gerne eine neue Spalte einfügen, in welcher mir die absoluten Zunahmen angezeigt werden. Es müsste also die 1. Wiegung minus das Geburtsgewicht, dann die 2. Wiegung minus die 1. etc.pp. gerechnet werden - und das für jedes Tier individuell. Hat jemand einen Tipp, wie ich das bewerkstelligen kann?
Es müssen für den ersten Wert der Zunahme Werte aus zwei Spalten verrechnet werden. Zuerst ist zu überlegen, wie die Berechnung aussehen würde, wenn nur ein Tier in dem Dataframe wäre.
Vielleicht so:
Code: Alles auswählen
Zunahme <- function(d) {
  d$zunahme <- c(d$GEWICHT[1] - d$GEBGEW[1], diff(d$GEWICHT))
  return(d)
}

Ich habe die Berechnung gleich in eine Funktion gepackt. Dabei ist wichtig, den gesamten Dataframe als Ergebnis zurückzuliefern.

Jetzt muss man den originalen Dataframe bezüglich der einzelnen Tiere zerhacken:
Code: Alles auswählen
L <- split(DeinDataframe, DeinDataframe$TIERNR_neu)
Dabei entsteht eine Liste von Dataframes. Über diese Liste scheucht man nun die frisch konstruierte Funktion drüber:
Code: Alles auswählen
Lneu <- lapply(L, FUN=Zunahme)

Anschließend wieder alle Teildataframes zu einem zusammenfügen:
Code: Alles auswählen
Ergebnis <- do.call(rbind, Lneu)


Und wie kann ich anschließend die Daten anhand den Tagen nach der Geburt in Gruppen aufteilen, um zu sehen, ob es signifikante Unterschiede in Woche X nach der Geburt gibt?
Dafür können wir die Funktion etwas erweitern. Hier eine kleine Fingerübung, bis klar ist, welche Datentypen Du in der Tabelle hast:
Code: Alles auswählen
x <- c("2017-02-02", "2017-02-22", "2017-03-08")
diff(as.Date(x))


Gruß, Jörg
üblicherweise bin ich öfter in jenem Forum: http://forum.r-statistik.de
jogo
 
Beiträge: 193
Registriert: Mo 26. Feb 2018, 09:56
Danke gegeben: 3
Danke bekommen: 1 mal in 1 Post

Re: Datenaufbereitung Bachelorarbeit

Beitragvon Martha » Mi 14. Aug 2019, 13:36

Hi!
Danke für die schnelle Antwort.
Hier erstmal der Output zu str().
Code: Alles auswählen
> str(AllData2)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   2220 obs. of  22 variables:
$ TIERNR_neu         : chr  "ML343" "ML343" "ML343" "ML338" ...
$ GEBDAT_lamm        : Date, format: "2016-12-28" "2016-12-28" "2016-12-28" "2016-12-28" ...
$ GEBGEW             : num  6.5 6.5 6.5 4.9 4.9 4.9 4.9 4.8 4.8 4.8 ...
$ GEW_DAT            : Date, format: "2017-02-02" "2017-02-22" "2017-03-08" "2017-02-02" ...
$ GEWICHT            : num  20 28 34 14 20 26 43 15 23 29 ...
$ GEBTYP             : Factor w/ 4 levels "1","2","3","4": 1 1 1 2 2 2 2 2 2 2 ...
$ SEX                : Factor w/ 2 levels "m","w": 2 2 2 2 2 2 2 2 2 2 ...
$ STATUS             : Factor w/ 2 levels "j","n": 1 1 1 1 1 1 1 1 1 1 ...
$ Schwanzlaenge.cm   : num  25.8 25.8 25.8 22.1 22.1 22.1 22.1 21.3 21.3 21.3 ...
$ Schwanzlaengeklasse: Factor w/ 4 levels "","k","l","m": 3 3 3 4 4 4 4 4 4 4 ...
$ DE_NR              : Factor w/ 461 levels "","DE010610356623",..: 93 93 93 182 182 182 182 188 188 188 ...
$ DE_NRMutter        : Factor w/ 561 levels "DE010610028001",..: 74 74 74 176 176 176 176 148 148 148 ...
$ DE_NRVater         : Factor w/ 11 levels "","DE010610264813",..: 10 10 10 10 10 10 10 10 10 10 ...
$ Lamm_OH            : Factor w/ 1280 levels "00796","00799",..: 597 597 597 892 892 892 892 829 829 829 ...
$ RASSE.x            : Factor w/ 2 levels "ML","RH": 1 1 1 1 1 1 1 1 1 1 ...
$ TIERNR.x           : int  343 343 343 338 338 338 338 351 351 351 ...
$ PRP                : logi  NA NA NA NA NA NA ...
$ SEXN               : Factor w/ 3 levels "0","1","2": 3 3 3 3 3 3 3 3 3 3 ...
$ REMONTE            : Factor w/ 2 levels "","RHB": 2 2 2 2 2 2 2 1 1 1 ...
$ ABDAT              : Date, format: NA NA NA NA ...
$ ABURS              : int  NA NA NA NA NA NA NA NA NA NA ...
$ BEM                : Factor w/ 17 levels "","Farbfehler",..: 1 1 1 1 1 1 1 2 2 2 ...

Der Output zu dput() ist zu umfangreich, um ihn hier abzubilden. Das würde den Rahmen sprengen...

Sind die Werte der Wägungen chronologisch sortiert?

Jupp, sind sie. Also immer "innerhalb" einer Tiernummer. Sozusagen alle Messdaten von z.B. Lamm ML340 sind chronologisch, dann kommt das nächste Tier.

Deine Lösung mit der Funktion und dem Splitten gefällt mir richtig gut :) Danke! Es funktioniert auch, allerdings gibt es ein Problem:
So würde von jeder Wägung das jeweilige Geburtsgewicht subtrahiert werden. Ich bräuchte diese Rechnung allerdings immer nur für die erste Wägung. Danach müsste es dann weitergehen mit Wägung2 minus Wägung1, Wägung3 minus Wägung2 etc.
Ein weiteres Problem ist, dass es nicht immer gleich viele Wägungen pro Tier sind. Meist sind es 3, teilweise aber auch nur 2 oder sogar 4.
Ich dachte, dass man die Funktion vielleicht um eine for-Schleife und eine if else Bedingung erweitern könnte. Also sowas wie "wenn es die 1. Wägung ist, dann ..., ansonsten ...". Und das wiederum müsste man ergänzen mit der Bedingung, dass R den zweiten Teil so lange durchführen soll wie weitere Wägungen vorliegen.
Ich habe es so versucht:
Code: Alles auswählen
Zunahme <- function(d){
for (i in 1:ncol(AllData2)) {
  if(d$GEWICHT == first(d$GEWICHT)){
    d$zunahme <- c(d$GEWICHT[1] - d$GEBGEW[1], diff(d$GEWICHT))
  }else if(d$GEWICHT != firtst(Gewicht)){
    d$zunahme <- c(d$GEWICHT[2,] - d$GEWICHT[1,])
  }
} return(d)
}

Das funktioniert allerdings nicht, es ist ziemlich chaotisch und der else Teil einfach falsch. Ich taste mich da gerade noch heran...

Liebe Grüße
Martha
Martha
 
Beiträge: 7
Registriert: Mo 29. Jul 2019, 16:30
Danke gegeben: 0
Danke bekommen: 0 mal in 0 Post

Re: Datenaufbereitung Bachelorarbeit

Beitragvon jogo » Mi 14. Aug 2019, 14:40

Hallo Martha,

Martha hat geschrieben:Hi!
Danke für die schnelle Antwort.
Hier erstmal der Output zu str().
Code: Alles auswählen
> str(AllData2)
Classes ‘tbl_df’, ‘tbl’ and 'data.frame':   2220 obs. of  22 variables:
...

Der Output zu dput() ist zu umfangreich, um ihn hier abzubilden. Das würde den Rahmen sprengen...
o.k., passt schon.
Du solltest deshalb auch nur dput(head(AllData2, 10)) (das wären dann nur für die ersten 10 Zeilen) zeigen.
Ich sehe, Du verwendest dplyr - damit lässt sich noch etwas eleganter programmieren ...
z.B.
Code: Alles auswählen
CO2 %>% group_by(Plant) %>% mutate(my=c(uptake[1]-conc[1], diff(conc)))

Bei Dir könnte das so aussehen:
Code: Alles auswählen
AllData2 %>% group_by(TIERNR_neu) %>% mutate(Zunahme=c(GEWICHT[1] - GEBGEW[1], diff(GEWICHT)))


Sind die Werte der Wägungen chronologisch sortiert?

Jupp, sind sie. Also immer "innerhalb" einer Tiernummer. Sozusagen alle Messdaten von z.B. Lamm ML340 sind chronologisch, dann kommt das nächste Tier.
genau darauf zielte meine Frage.

Deine Lösung mit der Funktion und dem Splitten gefällt mir richtig gut :) Danke! Es funktioniert auch, allerdings gibt es ein Problem:
So würde von jeder Wägung das jeweilige Geburtsgewicht subtrahiert werden.
Das stimmt nicht. Bitte schau Dir die Rechnung nochmal an:
Code: Alles auswählen
c(d$GEWICHT[1] - d$GEBGEW[1], diff(d$GEWICHT))


Ich bräuchte diese Rechnung allerdings immer nur für die erste Wägung. Danach müsste es dann weitergehen mit Wägung2 minus Wägung1, Wägung3 minus Wägung2 etc.
genau das macht die Berechnung.

Ein weiteres Problem ist, dass es nicht immer gleich viele Wägungen pro Tier sind. Meist sind es 3, teilweise aber auch nur 2 oder sogar 4.
auch diesbezüglich ist die Berechnung flexibel.

Am besten testest Du meine Funktion für nur ein Tier:
Code: Alles auswählen
Zunahme(subset(AllData2, TIERNR_neu=="ML338"))

bzw. in der dplyr-Version:
Code: Alles auswählen
subset(AllData2, TIERNR_neu=="ML338") %>% group_by(TIERNR_neu) %>% mutate(Zunahme=c(GEWICHT[1] - GEBGEW[1], diff(GEWICHT)))

(und bei Zweifeln bitte per Hand nachrechnen!)

Ich dachte, dass man die Funktion vielleicht um eine for-Schleife und eine if else Bedingung erweitern könnte. Also sowas wie "wenn es die 1. Wägung ist, dann ..., ansonsten ...". Und das wiederum müsste man ergänzen mit der Bedingung, dass R den zweiten Teil so lange durchführen soll wie weitere Wägungen vorliegen.
Ich habe es so versucht:
Code: Alles auswählen
Zunahme <- function(d){
for (i in 1:ncol(AllData2)) {...

Das funktioniert allerdings nicht, es ist ziemlich chaotisch und der else Teil einfach falsch. Ich taste mich da gerade noch heran...
Das ist klar, dass dies nicht funktioniert. Schau mal:
Du schreibst eine Funktion für einen Teildataframe d, der die Daten für nur ein Tier enthält ... und dann greifst Du auf den Gesamtdataframe AllData2 zu - das kann nur schiefgehen.

Gruß, Jörg
üblicherweise bin ich öfter in jenem Forum: http://forum.r-statistik.de
jogo
 
Beiträge: 193
Registriert: Mo 26. Feb 2018, 09:56
Danke gegeben: 3
Danke bekommen: 1 mal in 1 Post

Re: Datenaufbereitung Bachelorarbeit

Beitragvon Martha » Di 20. Aug 2019, 14:09

Hallo!
Erstmal Entschuldigung, dass ich mich jetzt erst melde und ein dickes Danke für deine Hilfe!!
Das stimmt nicht. Bitte schau Dir die Rechnung nochmal an

Keine Ahnung, was ich da gerechnet hatte... Hab' dann auch bemerkt, dass sie genau das tut und auch kapiert warum.

Ich habe die Rechnung dann auch angewandt, um die zeitliche Differenz zwischen den Wägungen zu berechnen (Variable heißt bei mir jetzt Zeit_Diff) und um anhand der absoluten Zunahmen und der Zeitdifferenz die täglichen Zunahmen (tägl_Zunahme) zu erhalten. Zusätzlich habe ich die zeitliche Differenz jeder Gewichtswägung zum Geburtstermin berechnet (Zeit_Diff_Geb) und alles stichprobenartig händisch überprüft.

Im nächsten Schritt wollte ich nun die Mittelwerte der täglichen Zunahmen der einzelnen Gruppen ab dem 8. bis zum 21. Lebenstag vergleichen. Die Gruppen setzten sich durch eine Aufteilung wie folgt zusammen:
Gliederung.jpg
Gliederung.jpg (29.51 KiB) 18-mal betrachtet

ML und RH bezeichnen die Rassen, 1 bzw. 2 den Geburtsstatus (also ob Einling oder Zwilling) und m bzw. w das Geschlecht.

Ich hatte dazu der Einfachheit halber zunächst folgendes gemacht:
Code: Alles auswählen
U22Tage <- AllData2 %>%
  group_by(TIERNR_neu) %>%
  filter(Zeit_Diff_Geb <= 21 & Zeit_Diff_Geb >= 8)

und dann über die filter-Funktion die Gruppen rausgesucht.

Das Problem ist, dass so zum Teil zu wenige Tiere in einer Gruppe verbleiben, als dass ich eine repräsentative Aussage raus ziehen könnte.
Meine erste Idee war (hab' ich aber nicht hinbekommen), eine Funktion zu schreiben, die mir die täglichen Zunahmen von Tag 8 bis Tag 21 nach Geburt verrechnet, damit ich einen Mittelwert der täglichen Zunahmen für diesen Zeitraum erhalte (tZ_u22). Überlegt hatte ich mir etwas wie:

wenn (Zeit_Diff_Geb [1] > 7 & < 22), dann wähle tägl_Zunahme als gesuchten Wert, aber
wenn (Zeit_Diff_Geb [1] > 7 & < 21), dann (((x - 7) * Zeit_Diff_Geb [1] * tägl_Zunahme[1] + y * Zeit_Diff_Geb [2] * tägl_Zunahme[2]) / (21 - 7)) als gesuchten Wert


wobei x die Tage bis zur ersten Wägung darstellt und y die Differenz von Tag x bis zum 21. Tag nach der Geburt.

In R eingetippt hatte ich
Code: Alles auswählen
func_u22 <- function(m){
  m$tZ_u22 <- if(m$Zeit_Diff_Geb[1] >= 8 & m$Zeit_Diff_Geb[1] <= 21){
    c(m$tägl_Zunahme)
  } else(m$Zeit_Diff_Geb[1] >= 8 & m$Zeit_Diff_Geb[1] <= 20){
    c(((m$Zeit_Diff_Geb[1] - 7) * m$Zeit_Diff_Geb[1] * m$tägl_Zunahme[1]
       + (m$Zeit_Diff_Geb[2] - m$Zeit_Diff_Geb[1]) * m$Zeit_Diff_Geb [2] * m$tägl_Zunahme[2])
       / (21 - 7))
  }
  return(m)
}

.... das funktioniert aber nicht - womit ich auch gar nicht gerechnet hatte. Es scheint mir sehr diffus zu sein.

Kannst du mir dahingehend vielleicht nochmal weiterhelfen bzw. einen Tipp geben?

Vielen lieben Dank schonmal für die Mühen und viele Grüße
Martha
Martha
 
Beiträge: 7
Registriert: Mo 29. Jul 2019, 16:30
Danke gegeben: 0
Danke bekommen: 0 mal in 0 Post

Re: Datenaufbereitung Bachelorarbeit

Beitragvon jogo » Mi 21. Aug 2019, 15:46

Hallo Martha,

Martha hat geschrieben:Im nächsten Schritt wollte ich nun die Mittelwerte der täglichen Zunahmen der einzelnen Gruppen ab dem 8. bis zum 21. Lebenstag vergleichen.
wie wäre es, wenn man das Gewicht des Schafes am 8. Lebenstag und am 21. Lebenstag ausrechnet (per Interpolation).

Ich hatte dazu der Einfachheit halber zunächst folgendes gemacht:
Code: Alles auswählen
U22Tage <- AllData2 %>%
  group_by(TIERNR_neu) %>%
  filter(Zeit_Diff_Geb <= 21 & Zeit_Diff_Geb >= 8)

und dann über die filter-Funktion die Gruppen rausgesucht.
Bewirkt das %>% group_by(TIERNR_neu) überhaupt etwas in diesem Zusammenhang?

In R eingetippt hatte ich
Code: Alles auswählen
func_u22 <- function(m){
  m$tZ_u22 <- if(m$Zeit_Diff_Geb[1] >= 8 & m$Zeit_Diff_Geb[1] <= 21){
    c(m$tägl_Zunahme)
  } else(m$Zeit_Diff_Geb[1] >= 8 & m$Zeit_Diff_Geb[1] <= 20){
    c(((m$Zeit_Diff_Geb[1] - 7) * m$Zeit_Diff_Geb[1] * m$tägl_Zunahme[1]
       + (m$Zeit_Diff_Geb[2] - m$Zeit_Diff_Geb[1]) * m$Zeit_Diff_Geb [2] * m$tägl_Zunahme[2])
       / (21 - 7))
  }
  return(m)
}

.... das funktioniert aber nicht - womit ich auch gar nicht gerechnet hatte. Es scheint mir sehr diffus zu sein.
Hier stimmt etwas nicht mit Deiner Konstruktion bei else

Gruß, Jörg
üblicherweise bin ich öfter in jenem Forum: http://forum.r-statistik.de
jogo
 
Beiträge: 193
Registriert: Mo 26. Feb 2018, 09:56
Danke gegeben: 3
Danke bekommen: 1 mal in 1 Post


Zurück zu Programmierung allgemein

Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 1 Gast

cron