Zeitraum wählen/Dopplungen mitteln/Mittelwerte anhängen/Dopplungen löschen

Allgemeine Statistik mit R, die Test-Methode ist noch nicht bekannt, ich habe noch keinen Plan!

Moderatoren: EDi, jogo

Antworten
Everlast

Zeitraum wählen/Dopplungen mitteln/Mittelwerte anhängen/Dopplungen löschen

Beitrag von Everlast »

Hallo liebe Forengemeinde,

ich bin neu hier und habe natürlich direkt ein paar Fragen. Zwar hatte ich vor einigen Semestern einen Grundkurs in R, muss jedoch zugeben dass ich dennoch als Anfännger durchgehe. Daher bin ich vorallem dankbar wenn ich danach auch verstehe was ich tue.

Nun aber zur Fragestellung. Ich habe einen Datensatz. Darin enthalten sind eine Messtellennumer, die Koordinaten der Messstelle, eine Schadstoffkonzentration und das Datum der Messung. In diesem Datensatz habe ich bereits Fehlwerte ersetzt, Ausreißer beseitigt das Datum auf Jahr/Monat/Tag aufgeteilt etc. Nun möchte ich allerdings auf Zeiträume zugreifen. Bei diesen handelt es sich um Messzyklen in denen jede Messstelle mindestens ein Mal beprobt wurde, jedoch manche auch häufiger. Innerhalb dieser Messzyklen möchte ich die Schadstoffwerte der mehrfach vorhandenen Messstellen mitteln, so dass für jede Messstelle pro Zyklus nur noch ein Wert vorliegt.

Code: Alles auswählen

head(basisdaten)

   Mst       x       y  mgl       Datum Jahr Monat Tag
1 3381 3695962 5494193 0.019 08.12.1989 1989    12   8
2 3381 3695962 5494193 0.027 10.10.1991 1991    10  10
3 3381 3695962 5494193 0.011 15.08.1989 1989     8  15
4 3381 3695962 5494193 0.032 26.08.1992 1992     8  26
5 3382 3695975 5494285 0.012 12.10.2001 2001    10  12
6 3382 3695975 5494285 0.002 18.09.2002 2002     9  18
(Werte geändert)

Mein Ansatz wäre nun gewesen einen Messzyklus über das Datum vorzugeben, mit duplicated() nach doppelten Werten innerhalb von diesem zu suchen und im Fall von TRUE diese zu mitteln mitsammt der Messstelle + Koordinaten, an die Tabelle an zu hängen und die anderen Werte raus zu werfen. Jetzt habe ich aber natürlich bei allen Messstellen die irgendwo ein zweites Mal auftauchen TRUE stehen und ich will ja nicht den Mittelwert aller Messstellen sondern immer nur der identischen.

Ich bin dankbar für jede Form der Hilfe :)
bigben
Beiträge: 2778
Registriert: Mi Okt 12, 2016 9:09 am

Re: Zeitraum wählen/Dopplungen mitteln/Mittelwerte anhängen/Dopplungen löschen

Beitrag von bigben »

Du kannst Tag, Monat und Jahr in ein Datumsformat umwandeln und dann Zeitausschnitte mit < und > definieren. Wenn die Daten basisdaten heißen, dann poste doch statt des Beispiels oben mal

Code: Alles auswählen

dput(basisdaten)
, damit wir ein paar Beispieldaten haben, um Dir Lösungen zu zeigen. Gerne mit geänderten Werten und gerne gekürzt.

LG,
Bernhard
---
Programmiere stets so, dass die Maxime Deines Programmierstils Grundlage allgemeiner Gesetzgebung sein könnte
Everlast

Re: Zeitraum wählen/Dopplungen mitteln/Mittelwerte anhängen/Dopplungen löschen

Beitrag von Everlast »

Erstmal danke für die Antwort Bernhard,


was das Datumsformat angeht, ich habe ja bereits ein Datum die Angabe Jahr/Monat/Tag habe ich zusätzlich definiert.
Hier die dput Ausgabe eines reduzierten und geänderten Datensatzes.

Code: Alles auswählen

dput(basisdaten)
structure(list(Mst = structure(c(5L, 4L, 4L, 3L, 3L, 2L, 2L, 
2L, 2L, 6L, 6L, 1L), .Label = c("3260", "3286A", "3288", "3289", 
"3289A", "3290"), class = "factor"), x = c(3599314.24, 3599318.73, 
3599318.73, 3599331.14, 3599331.14, 3599332.98, 3599332.98, 3599363.14, 
3599363.14, 3599365.18, 3499365.18, 3599382.9), y = c(5495292.58, 
5495297.71, 5495297.71, 5495204.46, 5495204.46, 5495197.28, 5495199.28, 
5495189.17, 5495189.17, 5495183.06, 5495183.06, 5494275.1), mg_l = c(0.064, 
0.064, 0.072, 0.064, 0.059, 0.054, 0.054, 0.054, 0.055, 0.064, 
0.076, 0.011), Datum = structure(c(1L, 1L, 6L, 4L, 7L, 2L, 7L, 
2L, 7L, 3L, 8L, 5L), .Label = c("09.01.1995", "09.02.1995", "09.02.2011", 
"09.03.1995", "17.10.2003", "22.05.1994", "22.09.1994", "22.09.2011"
), class = "factor"), Jahr = c(1995L, 1995L, 1994L, 1995L, 1994L, 
1995L, 1994L, 1995L, 1994L, 1995L, 2011L, 2003L), Monat = c(1L, 
1L, 5L, 3L, 9L, 2L, 9L, 2L, 9L, 2L, 9L, 10L), Tag = c(9L, 9L, 
22L, 9L, 22L, 9L, 22L, 9L, 22L, 9L, 22L, 17L)), .Names = c("Mst", 
"x", "y", "mg_l", "Datum", "Jahr", "Monat", "Tag"), class = "data.frame", row.names = c(NA, 
-12L))
Dass ich das Datum über < & > auswählen kann habe ich vermutet, hat leider nicht so ganz geklappt. Da jedoch die Messzyklen jeweils drei Jahre umfassen bin ich auf == und das Jahr ausgewichen, was funktioniert hat.
jogo
Beiträge: 2086
Registriert: Fr Okt 07, 2016 8:25 am

Re: Zeitraum wählen/Dopplungen mitteln/Mittelwerte anhängen/Dopplungen löschen

Beitrag von jogo »

Hallo Everlast,

willkommen im Forum!
Everlast hat geschrieben: Di Jul 11, 2017 5:23 pm Mein Ansatz wäre nun gewesen einen Messzyklus über das Datum vorzugeben, mit duplicated() nach doppelten Werten innerhalb von diesem zu suchen und im Fall von TRUE diese zu mitteln mitsammt der Messstelle + Koordinaten, an die Tabelle an zu hängen und die anderen Werte raus zu werfen. Jetzt habe ich aber natürlich bei allen Messstellen die irgendwo ein zweites Mal auftauchen TRUE stehen und ich will ja nicht den Mittelwert aller Messstellen sondern immer nur der identischen.
Mein Ansatz wäre ein völlig anderer:
1. sortieren nach Datum
2. dann kumulativ sowas wie length(unique(bisherigeMessstellen)) konstruieren
3. Das erste Datum, an dem length(unique(bisherigeMessstellen)) identisch mit der Anzahl aller Messstellen ist, ist das Ende des ersten Messzyklus, richtig?
Soll mit den übrigen Daten ähnlich verfahren werden für weitere Messzyklen?
Wenn die Messzyklen nummeriert sind, kann tapply() die Mittelwerte berechnen. ... oder auch aggregate()

Ich habe da mal etwas vorbereitet (für nach dem Sortieren):

Code: Alles auswählen

set.seed(42)
D <- data.frame(Mst=sample(c("3260", "3286A", "3288", "3289", "3289A", "3290"), 80, rep=TRUE))

Zyk <- function(x) {
  n <- length(x)   # Länge von x
  z <- integer(n)  # ... so lang muss auch z sein, hier wird für jeden Wert in x die Nummer des Zyklus gespeichert
  z.id <- 1L         #  Wir starten mit Zyklus 1
  s <- integer(0)  #  In diesem Vektor werden je Zyklus die schon vorhandenen Werte von x erfasst.
  sn <- length(unique(x))  # so viele verschiedene Werte von x gibt es insgesamt
  for (i in 1:n) {  # jetzt klappern wir den Vektor x elementweise ab
    z[i] <- z.id     # aktuelle Nummer des Zyklus eintragen
    s <- union(s, x[i])  # Mengenoperation: x[i] zur Menge der gesichteten x-Werte hinzufügen
    if (length(s)==sn) {  # ist der Zyklus komplett? wenn ja:
      z.id <- z.id+1   # Beim nächsten x[i] beginnt ein neuer Zyklus
      s <- integer(0)  # Im neuen Zyklus wurde noch kein x-Wert gesichtet (Menge leer)
    }
  }
  return(z)  # liefer den generierten Vektor mit Zyklennummern zurück 
}

D$z <- Zyk(D$Mst)
Ist das in Ordnung, dass der letzte Zyklus nicht vollständig ist? Oder möchtest Du die Daten eventuell um diesen Teil kürzen?
Für eine bessere Übersicht:

Code: Alles auswählen

D$m <- as.integer(D$Mst)
D
Falls Du den unvollständigen Zyklus doch abschneiden möchtest, kannst Du das so machen:

Code: Alles auswählen

# Abschneiden des unvollständigen Zyklus:
i <- D$z==max(D$z)
if (length(unique(D$z[i]))!=length(unique(D$Mst))) D <- D[!i,]
D
Für Deine Daten könnte das dann so aussehen:

Code: Alles auswählen

B <- basisdaten[with(basisdaten, order(Jahr, Monat, Tag)),]
B$z <- Zyk(B$Mst)
aggregate(mg_l ~ z + Mst, data=B, FUN=mean)
Gruß, Jörg
Everlast

Re: Zeitraum wählen/Dopplungen mitteln/Mittelwerte anhängen/Dopplungen löschen

Beitrag von Everlast »

Hallo Jörg,

danke für den Ansatz, bei dem du die Umsetzung direkt mitgeliefert hast! Hab das ganze jetzt mal nachgemacht und es funktioniert wunderbar, soll heißen die Messstellen sind danach nur noch einmalig vorhanden und ich habe die gemittelten Werte. Dafür erstmal vielen Dank! :D
Jetzt muss ich nur noch die Koordinaten anhängen, was keine größere Schwierigkeit ist (immerhin das kann ich ;) )

Allerdings habe ich die Funktion aus der sich Zyk ergibt nicht ganz verstanden. Es ist mir leider nicht gelungen eigenständig eine Dauer/ein Datum für den Messzyklus zu definieren. Mit ein bisschen "pfuschen" kriege ich für den von mir gesuchten Zeitraum zwar jetzt alles hin was ich brauche, zu verstehen wie ich die Funktion richtig anwende würde mich allerdings trotzdem interessieren. Natürlich nur wenn es keine Umstände macht.

mfg

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

Re: Zeitraum wählen/Dopplungen mitteln/Mittelwerte anhängen/Dopplungen löschen

Beitrag von jogo »

Hallo Johann,
Everlast hat geschrieben: Mi Jul 12, 2017 7:52 pm danke für den Ansatz, bei dem du die Umsetzung direkt mitgeliefert hast! Hab das ganze jetzt mal nachgemacht und es funktioniert wunderbar, soll heißen die Messstellen sind danach nur noch einmalig vorhanden und ich habe die gemittelten Werte. Dafür erstmal vielen Dank! :D
ja, das war ein reizvolles Problem. Nachdem ich die Idee fertig hatte, bekam ich dieses seltsame Zucken in den Fingern (das muss ich sofort ausprobieren).
Jetzt muss ich nur noch die Koordinaten anhängen, was keine größere Schwierigkeit ist (immerhin das kann ich ;) )
prima
Allerdings habe ich die Funktion aus der sich Zyk ergibt nicht ganz verstanden.
Ich habe die Nachricht nochmal editiert und reichlich Kommentare eingefügt. Bitte auch immer die Hilfetexte der verwendeten Funktionen lesen und selber mit den Funktionen rumspielen.
Es ist mir leider nicht gelungen eigenständig eine Dauer/ein Datum für den Messzyklus zu definieren. Mit ein bisschen "pfuschen" kriege ich für den von mir gesuchten Zeitraum zwar jetzt alles hin was ich brauche, zu verstehen wie ich die Funktion richtig anwende würde mich allerdings trotzdem interessieren. Natürlich nur wenn es keine Umstände macht.
Da kann ich endlich mal wieder den Umgang mit den Datumsfunktionen trainieren ;)

Code: Alles auswählen

B <- basisdaten[with(basisdaten, order(Jahr, Monat, Tag)),]
B$D <- as.Date(B$Datum, format="%d.%m.%Y")
B$z <- Zyk(B$Mst)
ZykDauer <- function(x) max(x) - min(x)
Zyklen <- data.frame(Dauer=tapply(B$D, B$z, ZykDauer), Beginn=tapply(B$D, B$z, min), Ende=tapply(B$D, B$z, max))
oder auch ohne extra Funktion:

Code: Alles auswählen

Zyklen <- data.frame(Beginn=tapply(B$D, B$z, min), Ende=tapply(B$D, B$z, max))
Zyklen$Dauer <- with(Zyklen, Ende - Beginn)
BTW: Wenn man ohnehin das Datum ordentlich definiert, kann man es auch beim Sortieren verwenden ...

Gruß, Jörg
Everlast

Re: Zeitraum wählen/Dopplungen mitteln/Mittelwerte anhängen/Dopplungen löschen

Beitrag von Everlast »

Hallo Jörg,

danke für die Unterstützung war mir eine große Hilfe! Funktioniert alles so wie es soll.
Bin schon dabei die Daten weiter auszuwerten, früher oder später stehen die Chancen gut das ich nochmal nach Tipps frage. Aber für die nächsten Schritte hab ich erstmal schon Pläne :)

mfg,

Johann
Antworten