Fehlerbalken in R-Grafik einzeichnen

In wissenschaftlichen Publikationen werden häufig Messwerte in Grafiken dargestellt. Messungen sind allerdings immer fehlerbehaftet. Daher sollte man dem Leser mitteilen, wie verlässlich die gemessenen Werte sind. In der deskriptiven Statistik gibt es dafür diverse Kennzahlen, wie z.B. die Standardabweichung oder den Standardfehler. Diese werden oft als Fehlerbalken in die Grafiken eingefügt.

errorbars
Grafisch dargestellte Messwerte mit Fehlerbalken.

In R gibt es leider keine Standardmethode, die diese Aufgabe übernimmt. Zunächst hatte ich nach Anleitungen im Internet eigene Funktionen für diese Aufgabe erstellt.

  • Eine Lösung fand ich bei Stackoverflow. Allerdings wurden hier die horizontalen Linien bei einer logarithmischen X-Achse nicht korrekt angezeigt (links und rechts waren die Linien unterschiedlich lang).
  • Die Lösung von MonkeysUncle war in der Hinsicht besser. Allerdings wurde keine horizontale Linie angezeigt, wenn der Fehler 0 war. Zudem wurde gar kein Fehlerbalken angezeigt, wenn die untere Grenze des Fehlers (bei logarithmischer Y-Achse) im negativen Bereich lag.

Schließlich habe ich die Funktion errbar() im Paket Hmisc gefunden (siehe auch StackOverflow). Hier werden:

  1. Die horizontalen Linien auch bei logarithmischer X-Achse korrekt gezeichnet.
  2. Bei logarithmischer Y-Achse und negativer unteren Fehlergrenze, wird zumindest die obere Fehlergrenze geplottet.
  3. Eine horizontale Linie wird auch hinzugefügt, wenn der Fehler 0 ist.
  4. Die Y-Ranges werden automatisch gewählt, wenn die Fehlerbalken ausserhalb der Grafik liegen würden.

Das folgende Beispiel zeigt, wie man Datenpunkte mit ihren Fehlerbalken in eine Grafik einträgt.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# Datenpunkte (x, y) mit einer Standardabweichung (sd)
daten = data.frame(
  x  = c(1:5)
  , y  = c(1.1, 1.5, 2.9, 3.8, 5.2)
  , sd = c(0.2, 0.3, 0.2, 0.0, 0.4)
)
 
# Paket "Hmisc" installieren und laden 
install.packages("Hmisc", dependencies=T)
library("Hmisc")
 
# Plot mit automatischer Wahl des Y ranges
with (
  data = daten
  , expr = Hmisc::errbar(x, y, y+sd, y-sd, pch=1)
)
 
# Datenpunkte mit Fehlerbalken zu einem
# existierenden Koordinatensystem hinzufügen (add=T)
plot(daten$x, daten$y, type="n", xlab="X-Werte", ylab="Y-Werte")
with (
  data = daten
  , expr = Hmisc::errbar(x, y, y+sd, y-sd, pch=2, add=T)
)

Die Funktion errbar() erweitert die Funktion plot(). Daher können die Grafikparameter von plot() und par() (hier z.B. pch) verwendet werden. Zusätzlich gibt es noch Parameter, mit denen sich z.B. die breite der horizontalen Begrenzung (cap) steuern lässt.

Funktion aus einem bestimmten R-Paket laden

Die Programmiersprache R kann durch Funktionen erweitert werden, die von anderen Nutzern erstellt wurden. Oftmals sind diese Erweiterungen in Paketen zusammengefasst. Ein Problem tritt allerdings dann auf, wenn in unterschiedlichen Paketen Funktionen enthalten sind, die den gleichen Namen tragen (siehe: Stackoverflow).

Ich nutze z.B. folgende Pakete sehr häufig:

  • sfsmisc – Mit der Funktion eaxis() lassen sich schöne logarithmische Achsen erstellen. Die Beschriftung wird dabei von der Funktion pretty10exp() übernommen.
  • Hmisc– Mit der Funktion errbar() lassen sich sehr leicht Fehlerbalken in Plots eintragen.
  • TeachingDemos – Mit der Funktion subplot() lassen sich sehr einfach Insets zu Plots hinzufügen.

Lädt man allerdings die Pakete,

## Installation der Pakete
install.packages("sfsmisc", dependencies=T)
install.packages("Hmisc", dependencies=T)
install.packages("TeachingDemos", dependencies=T)
 
## Laden der Pakete
library(package = "sfsmisc")
library(package = "Hmisc")
library(package = "TeachingDemos")

dann erhält man folgende Fehlermeldungen:

Attache Paket: ‘Hmisc’

Das folgende Objekt ist maskiert from ‘package:survival’:
    untangle.specials

Das folgende Objekt ist maskiert from ‘package:sfsmisc’:
    errbar

Das folgende Objekt ist maskiert from ‘package:base’:
    format.pval, round.POSIXt, trunc.POSIXt, units

Man kann erkennen, dass sowohl Hmisc als auch sfsmisc eine Funktion namens errbar() enthalten.

Attache Paket: ‘TeachingDemos’

Das folgende Objekt ist maskiert from ‘package:Hmisc’:
    cnvrt.coords, subplot

Man kann erkennen, dass sowohl TeachingDemos als auch Hmisc eine Funktion mit Namen subplot() enthalten.

Um nun die Funktion aus einem bestimmten Paket zu verwenden, kann man R dies mit Hilfe von zwei Doppelpunkten :: mitteilen:

# Verwende die Funktion subplot() aus dem Paket TeachingDemos
TeachingDemos::subplot(...)
 
# Verwende die Funktion errbar() aus dem Paket Hmisc
Hmisc::errbar(...)

Meine Empfehlung: Wenn man Funktionen aus einem Paket verwendet, sollte man beim Aufruf der Funktion immer diese Notation verwenden. Zum einen hilft es dem Leser zu erkennen, woher diese Funktion stammt. Zum anderen verhindert man unnötige Verwirrung, wenn man zu einem späteren Zeitpunkt Pakete einbindet, die Funktionen mit gleichem Namen enthalten.

Webseite komplett herunterladen

Informationen im Internet sind kurzlebig und können nur abgerufen werden, sofern ein Internet-Anschluss verfügbar ist. Problematisch wird es also, wenn Websites gelöscht werden, oder man gerade keinen Zugriff auf das Internet hat (z.B. auf Reisen).

Gelöschte oder ältere Versionen von Websites findet man in Internet Archiven wie der WayBackMachine. Man kann sich die Webseiten allerdings auch selbst zum offline lesen herunterladen.

Ein beliebtes Programm dafür ist wget:

wget -r -k -E -l 8 http://de.wikipedia.org

Mit diesem Befehl würde man die deutsche Version der Wikipedia herunterladen. Die verwendeten Optionen haben folgende Bedeutungen:

-r Websites zum Herunterladen rekursiv durchlaufen.
-l 8 Bei der Rekursion maximal 8 Ebenen („Ordner“) tief vordringen (Standard ist 5)
-k Konvertiere Links, damit sie lokal funktionieren.
-E Erzwinge die Dateiendung „.html“; Das ist besonders dann nützlich, wenn man „.php“ oder „.asp“-Dateien herunterlädt.

Weietere Optionen und Informationen findest Du im Wiki von UbuntuUsers.

Falls Du diesen Befehl häufiger verwenden, Du Dir aber die ganzen Optionen nicht merken möchtest, kannst Du Dir einen Alias anlegen. Solltest Du die bash als Standard-Terminal (Shell) verwenden, musst Du dazu lediglich folgende Zeile in die Datei .bashrc in Deinem Home-Verzeichnis eintragen:

alias wdown='wget -r -k -E -l 8'

Im Anschluss steht Dir der Terminal-Befehl wdown zur Verfügung und Du könntest Dir die deutsche Wikipedia folgendermaßen herunterladen:

wdown http://de.wikipedia.org

Bevor Du allerdings Seite herunterlädst, solltest Du Dich mit den Urheberrechten auseinander setzen.

Plot-Funktion in R erweitern

Manchmal möchte man eine bestehende Funktion in der Programmiersprache R um einen eigenen Parameter erweitern. Die Parameter der Ausgangsfunktion sollen dabei einfach übernommen werden, ohne sie innerhalb der eigenen Funktion definieren und einzeln übergeben zu müssen. Die Weiterleitung von Parametern kann in R durch ... realisiert werden.

Im folgenden Beispiel erweitere ich die R-Funktion plot(). In der neuen Funktion plot.mein() kann zusätzlich eine rote horizontale und/oder vertikale Linie eingezeichnet werden.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
# Definition der neuen Funktion
plot.mein <- function(..., hline=NULL, vline=NULL) {
  # Plote die Daten
  # Leite die Grafik-Parameter direkt an die Funktion plot() weiter
  plot(...)
 
  # Füge eventuell eine horizontale rote Linie hinzu
  if(!is.null(hline)) {
    abline(h=hline, col="#ff0000")
  }
 
  # Füge eventuell eine vertikale rote Linie hinzu
  if(!is.null(vline)) {
    abline(v=vline, col="#ff0000")
  }
}
# Die Parameter x, y und type werden direkt an die Funktion plot weitergeleitet
plot.mein(c(1:6), c(16:11), hline=3, vline=2, type="b")
 
# Wenn die Namen der Parameter angegeben werden,
# dann spielt auch die Reihenfolge beim Aufruf keine Rolle
plot.mein(hline=3, x=c(1:6), vline=2, y=c(16:11), type="b")

Man kann auch die Standard-Parameter der Ausgangsfunktion ändern. Dazu muss der Parameter in der Definition der eigenen Funktion mit dem gewünschten Wert eingetragen werden (hier: type="o"). Der Parameter muss zusätzlich explizit an die Ausgangsfunktion übergeben werden (hier: type=type).

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# Ändere den Standardwert für type
plot.mein <- function(..., hline=NULL, vline=NULL, type="o") {
  # type muss explizit übergben werden
  plot(..., type=type)
 
  # [...]
 
}
 
# Der in plot.mein() festgelegte Standadwert für type ("o") wird verwendet
plot.mein(c(1:6), c(16:11), hline=3, vline=2)
 
# Hier wird der beim Aufruf angegebene Wert für type ("b") verwendet
plot.mein(c(1:6), c(16:11), hline=3, vline=2, type="b")

Grafik-Parameter in R zeitweise verändern

R ist eine Programmiersprache, mit deren Hilfe man Statistiken berechnen und die Ergebnisse grafisch darstellen kann. Dabei kann man auch mehrere solcher Grafiken in eine einzige Datei (z.B. PDF-Datei) speichern.

Die Ausgabegeräte („output device“, z.B. PDF-Datei) haben voreingestellte Werte für z.B. die Rahmenbreite, Textfarben, Textgrößen, usw.. Manchmal möchte man dabei für einen einzigen Plot die Standard-Parameter des Ausgabegerätes verändern(sie auch: Dokumentation zu par() und WikiBooks-Artikel zu par()). Für weitere Plots sollen dann wiederum die Standard-Parameter verwendet werden. Dazu kann man die Parameter vor der Veränderung zwischenspeichern und im Anschluss wieder einsetzen.

Im folgenden Beispiel werden drei einfache Grafiken in eine gemeinsame PDF-Datei geplottet. Im zweiten Plot werden die Ränder, sowie die Ausrichtung der Beschriftungen verändert. Im dritten Plot werden dann wieder die Standard-Parameter verwendet:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# Ausgabegerät setzen (hier: PDF-Datei)
pdf("plots.pdf")
 
# Plot mit Standard-Parametern
plot(
    x = 1, y = 1
    , xlab = "X-Achsenbeschriftung"
    , ylab = "Y-Achsenbeschriftung"
    , main = "Plot mit Standard-Parametern"
)
 
# Alle änderbaren Standardparameter speichern
original_parameter = par(no.readonly=TRUE)
 
# Plot mit geändertem Rahmen und linksbündigen Beschriftungen
par( mar = c(4,4,1,0) + 0.1 , adj = 0)
plot(
    x = 1, y = 1
    , xlab = "X-Achsenbeschriftung"
    , ylab = "Y-Achsenbeschriftung"
    , main = "Plot mit eigenen Parametern"
)
 
# Standard-Parameter einsetzen
par(original_parameter)
 
# Erneut mit Standard-Parametern plotten
plot(
    x = 1, y = 1
    , xlab = "X-Achsenbeschriftung"
    , ylab = "Y-Achsenbeschriftung"
    , main = "Plot mit Standard-Parametern"
)
 
# Ausgabegerät schließen (hier: Daten in PDF-Datei speichern)
dev.off()

Im oben stehenden Beispiel wurden all diejenigen Parameter zwischengespeichert, die auch tatsächlich geändert werden können. Parameter wie z.B. cin oder csi können zwar gelesen, aber nicht geändert werden. Um nur änderbare Parameter auszulesen, muss in der Funktion par() die Option no.readonly auf TRUE gesetzt werden. Ansonsten bekommt man folgende Fehlermeldung:

Warnmeldungen:
1: In par(original_parameter) : graphical parameter "cin" cannot be set
2: In par(original_parameter) : graphical parameter "cra" cannot be set
3: In par(original_parameter) : graphical parameter "csi" cannot be set
4: In par(original_parameter) : graphical parameter "cxy" cannot be set
5: In par(original_parameter) : graphical parameter "din" cannot be set

Anstatt alle änderbaren Parameter zwischen zu speichern, kann man sich auch nur eine Auswahl an Parametern merken:

12
13
# Auswahl an änderbaren Standardparametern speichern
original_parameter = par(c("mar", "adj"))

Abkürzungen in gnuplot

Das Programm gnuplot dient dazu, Daten in einem Koordinatensystem graphisch darzustellen. Gnuplot kann über den Befehl

gnuplot

im interaktiven Modus gestartet werden. Um die Eingabe der Befehle zu beschleunigen, gibt es für häufig verwendete Befehle Kurzschreibweisen. Einige davon sind in der folgenden Tabelle aufgelistet:

Befehl Abkürzung Beispiel
using u, usi plot "file.dat" u 1:2
title t plot 1 t "Linie 1"
with w plot 2 w lines
lines l plot 2 with l
linespoints lp, linesp plot 2 with linesp
linetype lt plot 2 w l lt 3
linecolor lc plot 2 w l lc rgb "#cccccc"
linewidth lw plot 2 w l lw 5
points p plot 2 with p
pointtype pt plot 2 w p pt 6
pointsize ps plot 2 w p ps .5
pointinterval pi ?pointinterval
xrange xr set xr [-5:5]
yrange yr set yr [1:2]
terminal term set term pdf
postscript post set terminal post
output out set out "filename.dat"
replot rep

Weitere Details findest Du in der gnuplot-Dokumentation.

Informationen über Prozessoren unter Linux herausfinden

Manchmal ist es notwendig, genauere Informationen über den Rechner zu bekommen, auf dem man gerade arbeitet. Sofern man eine grafische Oberfläche zur Verfügung hat, sind diese Informationen meist mit einigen Mausklicks zu bekommen. Aber auch im Terminal lassen sich detaillierte Informtionen ausgeben.

Grafisch:
Bei Ubuntu Linux kann man z.B. auf die System-Schaltfläche, und im Anschluss auf „Über diesen Rechner“ klicken (alternativ: in den Systemeinstellungen im Bereich „System“ auf „Informationen“ klicken):

Bildschirmfoto vom 2013-08-16 08:24:00
Informationen über die Hardware Deines Computers kannst Du auch über die grafische Benutzeroberfläche bekommen.

Im Terminal:
Manch einer arbeitet allerdings auf Systemen, auf denen nicht zwangsläufig eine grafische Oberfläche zur Verfügung steht – z.B. wenn man sich im Terminal per SSH auf einen Server einloggt. In diesem Falle kann man sich aktuelle Informationen über die CPUs aus der Datei /proc/cpuinfo ausgeben lassen:

cat /proc/cpuinfo

oder:

more /proc/cpuinfo

Die unter „cpu MHz“ angegebene Zahl gibt allerdings nicht zwangläufig die maximal mögliche Taktfrequenz an, sondern nur die aktuell verwendete Taktfrequenz. Moderne Systeme regeln die Taktfrequenz herunter, wenn derzeit nur eine geringere Leistung benötigt wird (weitere Informationen). Um die maximale Leistung für die Prozessoren zu erzwingen, kann das Programm stress verwendet werden (siehe auch: linux.die.net).

Falls das Paket util-linux installiert ist, bekommst du detaillierte Informationen über den Terminal-Befehl:

lscpu

(siehe dazu auch Interpreting output of cat /proc/cpuinfo)