"Median" bestimmen

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

Moderatoren: EDi, jogo

Antworten
MSch
Beiträge: 15
Registriert: Di Mai 28, 2019 1:21 pm

"Median" bestimmen

Beitrag von MSch » Fr Jul 12, 2019 4:04 pm

Hallo Leute,

ich hab eine Tabelle bestehend aus zwei Spalten. Zum einen eine Volumen-Spalte zum anderen deine Dosis-Spalte. Nun habe ich darin etwa 200 Messpunkte. Jeder Messpunkt gibt an wieviel Volumen eine gewisse Dosis abbekommt.

also z.B.
34 cc bekommen 10 Gy
29 cc bekommen 10.3 Gy
53 cc bekommen 10.8 Gy

usw.

Nun sollte ich den Median bezüglich der Dosis in Abhängigkeit vom Volumen berechnen. Also muss ich alle Volumina aufsummieren bis ich die Hälft des Volumens erreicht habe und an dieser Stelle will ich den Dosis wert abrufen. Nun sollte ich das alles mit If abfragen und Forschleife hinbekommen aber ich wollte fragen ob es nicht auch einen einfacheren Weg gibt.

Hab leider mit der normalen Bibliothek/Hilfe kein passenden Befehl mit Stichwörtern wie Median gefunden.

Hufeisen
Beiträge: 122
Registriert: Fr Aug 31, 2018 6:34 pm

Re: "Median" bestimmen

Beitrag von Hufeisen » Fr Jul 12, 2019 4:43 pm

Zuerst wäre es eine gute Idee, die Spalten in ein numerisches Format umzuwandeln. Das ist ein bisschen unhandlich (es geht vielleicht auch einfacher :?: ). Der Code sollte sich auch auf eine Spalte anwenden lassen (ohne Gewähr :lol:). Dann solltest Du vielleicht noch mal erklären, was Du genau suchst. Für mich klingt es eher danach, als suchst Du die Zeile, in der für die Spalte Volumen die kumulierte Summe / Summe = 0.5 ist. Für diese Zeile soll dann der Wert der Spalte Dosis ausgelesen werden. Soweit, so klar. Aber was soll passieren, wenn es keinen Wert gibt, bei dem genau das halbe Volumen erreicht ist. Soll dann ähnlich wie beim Median imputiert werden oder soll der nächst beste Wert genommen werden?

Code: Alles auswählen

# strings zu Zahlen
  Volumen <- "34 cc bekommen"
  Dosis <- "10 Gy"

  # Zahlen extrahieren
  substring(Volumen, first = 1, last = which(strsplit(Volumen, "")[[1]]==" ")[1] - 1)
  substring(Dosis, first = 1, last = which(strsplit(Dosis, "")[[1]]==" ")[1] - 1)

  # Output
  # > substring(Volumen, first = 1, last = which(strsplit(Volumen, "")[[1]]==" ")[1] - 1)
  # [1] "34"
  # > substring(Dosis, first = 1, last = which(strsplit(Dosis, "")[[1]]==" ")[1] - 1)
  # [1] "10"

#  Du suchst vermutlich so etwas: Kumulierte Summe / Summe
  mein_vektor <- c(1, 2, 3)
  cumsum(mein_vektor) / sum(mein_vektor)

  # Output
  # >  cumsum(mein_vektor) / sum(mein_vektor)
  # [1] 0.1666667 0.5000000 1.0000000

MSch
Beiträge: 15
Registriert: Di Mai 28, 2019 1:21 pm

Re: "Median" bestimmen

Beitrag von MSch » Fr Jul 12, 2019 5:25 pm

Die Spalten sind natürlich numerisch dachte in der Darstellung ist es etwas anschaulicher da mein Problem ja ehr abstrakt ist.

Also im Prinzip ist es eine differenzielle Darstellung eines sogenannten DVHs also eines Dosis Volumen Histograms.
Für mich klingt es eher danach, als suchst Du die Zeile, in der für die Spalte Volumen die kumulierte Summe / Summe = 0.5 ist
Genau das tue ich auch was dem Median der Dosis entspricht. Da natürlich meine Messpunkte nicht unendlich klein sind besteht das Problem natürlich dass der Median nicht exakt auf eine Zeile fallen wird aber dieser muss nicht exakt sein bzw. wird in ausreichender Genauigkeit über die Anzahl der Messpunkte bestimmt.

Also dein Skript löst nun nicht wirklich mein Problem aber mit "cumsum" spare ich mir schon mal ein Befehle. Aber ich würde gern das iterative Abfragen der Summe ob bereits die hälfte des Volumens aufsummiert ist umgehen bzw. schöner gestalten.

Bis jetzt fällt mir nur die Möglichkeit ein dass ich das Gesamtvolumen berechne und anschließend solange aufsummiere und jedes mal mit der if abfrage überprüfe ob Vol_Ges/2 erreicht ist und dann meine Laufvariable nehme um die passenden Dosisspalte zu finden.
0

Hufeisen
Beiträge: 122
Registriert: Fr Aug 31, 2018 6:34 pm

Re: "Median" bestimmen

Beitrag von Hufeisen » Fr Jul 12, 2019 6:43 pm

Edit: Habe noch ein wenig geändert.
MSch hat geschrieben:
Fr Jul 12, 2019 5:25 pm
Also dein Skript löst nun nicht wirklich mein Problem aber mit "cumsum" spare ich mir schon mal ein Befehle. Aber ich würde gern das iterative Abfragen der Summe ob bereits die hälfte des Volumens aufsummiert ist umgehen bzw. schöner gestalten.
Ich wollte mich auch erst vergewissern, was Du genau möchtest. Ich nehme an, die Hälfte des Volumens muss erreicht sein und 0.49 ist zu wenig? Dann ginge es so:

Code: Alles auswählen

# Beispieldaten erzeugen
Medizin <- data.frame(Volumen = sample(20:80, 20, replace = TRUE), Dosis = 10 + seq(from = 0, by = 0.3, length.out = 20))

# Wann ist 0.5 überschritten
Medizin$relatives_Volumen <- cumsum(Medizin$Volumen) / sum(Medizin$Volumen)
which(Medizin$relatives_Volumen >= 0.5) [1]

	# [1] 11

# die Zeile des df
Medizin[which(Medizin$relatives_Volumen >= 0.5) [1], ]

	#    Volumen Dosis relatives_Volumen
	# 11      23    13          0.522602

# nur die Dosis
Medizin[which(Medizin$relatives_Volumen >= 0.5) [1], "Dosis"]

	# [1] 13

# Median
median(Medizin$Dosis)
# 12.85

# mein df
> Medizin
   Volumen Dosis relatives_Volumen
1       53  10.0        0.05843440
2       27  10.3        0.08820287
3       80  10.6        0.17640573
4       24  10.9        0.20286659
5       35  11.2        0.24145535
6       33  11.5        0.27783903
7       50  11.8        0.33296582
8       64  12.1        0.40352811
9       25  12.4        0.43109151
10      60  12.7        0.49724366
11      23  13.0        0.52260198
12      22  13.3        0.54685777
13      40  13.6        0.59095921
14      60  13.9        0.65711136
15      52  14.2        0.71444322
16      62  14.5        0.78280044
17      41  14.8        0.82800441
18      60  15.1        0.89415656
19      46  15.4        0.94487321
20      50  15.7        1.00000000

MSch
Beiträge: 15
Registriert: Di Mai 28, 2019 1:21 pm

Re: "Median" bestimmen

Beitrag von MSch » Mo Jul 15, 2019 10:50 am

Hi Hufeisen,

die If-Abfrage muss halt doch sein da komm ich net rum. Aber immerhin ganz ohne Schleifen. Deine Lösung gefällt mir sehr gut. Zurm reinen Verständnis und da ich noch etwas neu bin in R würde mich noch interessieren warum du die stelle [1] immer angibst und was genau damit definiert wird.


Bsp.: (Unterstrichen also mit

Code: Alles auswählen

[u][/u]
)

Code: Alles auswählen

Medizin$relatives_Volumen <- cumsum(Medizin$Volumen) / sum(Medizin$Volumen)
which(Medizin$relatives_Volumen >= 0.5) [u][1][/u]

Medizin[which(Medizin$relatives_Volumen >= 0.5) [u][1][/u], ]



Medizin[which(Medizin$relatives_Volumen >= 0.5) [u][1][/u], "Dosis"]

Hufeisen
Beiträge: 122
Registriert: Fr Aug 31, 2018 6:34 pm

Re: "Median" bestimmen

Beitrag von Hufeisen » Mo Jul 15, 2019 1:04 pm

MSch hat geschrieben:
Mo Jul 15, 2019 10:50 am
die If-Abfrage muss halt doch sein da komm ich net rum.
Bastel dir mal eine Lösung mit if-Abfrage. Wenn es klemmt, kannst du ja hier fragen. Versuch macht klug :).

Die eckige Klammer mit der eins [1] wählt das erste Element des durch die Funktion which(...) erzeugten Vektors aus. So sieht der Output ohne eckige Klammer aus.

Code: Alles auswählen

which(Medizin$relatives_Volumen >= 0.5)
 [1] 11 12 13 14 15 16 17 18 19 20
Übersetzt heißt das, dass die Zeilen 11 bis 20 Werte größer gleich 0.5 aufweisen. Du suchst aber nur die erste Zeile, bei der das der Fall ist. Deshalb wähle ich direkt das erste Element aus.

Code: Alles auswählen

which(Medizin$relatives_Volumen >= 0.5) [1]
[1] 11
Weiter im Skript nutze ich dann diese Codezeile zur Auswahl der 11. Zeile, um die Dosis oder die ganze Zeile des df auszugeben.

Das subsetting in R ist am Anfang sicherlich verwirrend, weil es viele Möglichkeiten gibt, das im Code darzustellen. Du kannst bei Gelegenheit ja mal hier gucken: http://adv-r.had.co.nz/Subsetting.html. Außerdem gibt es noch Funktionen wie base::subset() und weil das natürlich viel zu wenige Möglichkeiten sind, gibt es noch weitere Lösungen in anderen Paketen :lol:.

MSch
Beiträge: 15
Registriert: Di Mai 28, 2019 1:21 pm

Re: "Median" bestimmen

Beitrag von MSch » Mo Jul 15, 2019 1:18 pm

Hey Hufeisen,

ne wollte eine Lösung ohne If, was deine natürlich ist. War ein kleiner Fehler meiner Seite (daher ist deine schon ziemlich genau das was ich mir vorgestellt habe).
Wegen der [1] hab ich nur nicht begriffen dass alle Werte ausgegeben werden >= 0.5 (war im Kopf einfach bei If Abfragen die ja nach der erfüllten Bedingung eh aufhört).
Danke noch für den Link zu den Subsettings. Finde diese immer noch sehr verwirrend und hoffe mit der Seite einen weiteren Schritt in Richtung
R-Experte *träum* zu machen.


Liebe Grüße
Michael

Antworten