Dateien aus verschlüsseltem Home-Verzeichnis kopieren und löschen

Ich habe mir kürzlich eine neue Festplatte gekauft und darauf ein neues Ubuntu eingerichtet. Nun möchte ich die Daten von meiner alten Festplatte herunterladen und auf die neue Festplatte spielen. Das Problem ist allerdings, dass ich mein Home-Verzeichnis auf der alten Festplatte mit Hilfe von eCryptfs verschlüsselt hatte. In diesem Artikel erkläre ich schrittweise, wie man dennoch die Daten aus einem verschlüsselten Verzeichnis verschieben, kopieren und löschen kann.

  1. Zunächst ist es hilfreich, wenn man sein altes Login-Passwort griffbereit hat. Alternative kann man auch das eCryptfs Mount-Passwort verwenden. Das hat man sich im Optimalfall nach der Installation notiert, oder zu einem späteren Zeitpunkt mit Hilfe des folgenden Befehls angeschaut:

    ecryptfs-unwrap-passphrase
  2. Im Anschluss muss man das Laufwerk/Speichermedium mounten, auf dem sich das verschlüsselte Verzeichnis befindet. Tipp: interne Festplatten und deren Partitionen sind nicht automatisch gemountet – auch nicht, wenn das Symbol in der Seitenleiste von Ubuntu angezeigt wird. In dem Falle muss man einfach einmal auf das Symbol klicken.
  3. Daraufhin gibt man im Terminal einen der beiden folgenden Befehle ein (mit Root-Rechten!; siehe auch UbuntuUsers Forum):

    # Verzeichnis nur mit Leserechten einbinden
    sudo ecryptfs-recover-private
     
    # Verzeichnis mit Schreibrechten einbinden
    # in "man ecryptfs-recover-private" ist die Option --rw etwas versteckt genannt
    sudo ecryptfs-recover-private --rw

    eCryptfs durchsucht nun alle gemounteten Medien nach eCryptfs-verschlüsselten Verzeichnissen. Das kann eine Weile dauern.

    INFO: Searching for encrypted private directories (this might take a while)…

  4. Hat eCryptfs die Suche beendet, wird für jedes gefundene Verzeichnis gefragt, ob es eingebunden werden soll. Dabei sollte man beachten, dass auch das Verzeichnis des angemeldeten Nutzers gefunden wird (in meinem Falle also nicht nur das alte, sondern auch das neue Home-Verzeichnis).

    INFO: Found [/media/neuerusername/XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX/.ecryptfs/alterusername/.Private].

    Nun wird man zunächst nach seinem Login-Passwort gefragt:

    INFO: Found your wrapped-passphrase
    Do you know your LOGIN passphrase? [Y/n]

    Falls man dieses nicht kennt, wird man nach dem (meist 32-stelligen) Mount-Passwort gefragt:

    INFO: To recover this directory, you MUST have your original MOUNT passphrase.
    INFO: When you first setup your encrypted private directory, you were told to record
    INFO: your MOUNT passphrase.
    INFO: It should be 32 characters long, consisting of [0-9] and [a-f].

    Enter your MOUNT passphrase:

  5. Hat man eines der beiden Passwörter korrekt eingegeben, so wird das Verzeichnis innerhalb des Ordners /tmp eingehängt:

    INFO: Success! Private data mounted at [/tmp/ecryptfs.PW48rluR].

  6. Nun kann man das Verzeichnis im Datei-Browser öffnen – entweder durch klicken, oder durch den Start von nautilus (mit dem Verzeichnis als Parameter) aus dem Terminal heraus:

    nautilus /tmp/ecryptfs.PW48rluR
  7. Hinweis: Sollten sich in dem Verzeichnis nur Dateien befinden, die z.B. mit ECRYPTFS_FNEK_ENCRYPTED. beginnen, hat man das Mount-Passwort sehr wahrscheinlich falsch eingegeben.

Ubuntu ISO-Dateien nach dem Download überprüfen

Nach dem Download von Ubuntu (oder anderer Dateien aus dem Internet) überprüfe ich immer, ob die Datei(en) korrekt heruntergeladen wurde(n). Eine Möglichkeit ist, die MD5-Summe der ISO-Dateien zu berechnen.

Unter Linux steht dazu der Befehl md5sum zur Verfügung

1
2
3
4
# MD5-Summen aller *.iso-Dateien berechnen und in md5sums.txt schreiben:
md5sum *.iso > md5sums.txt
# Inhalt der Datei anzeigen:
cat md5sums.txt

Als Ausgabe bekommt man z.B.:

8d72e2db7e72e13813731eab37a14d26  ubuntu-13.04-desktop-amd64.iso
5d5d1a7da2a0659b163d4f8bd70fbe6f  ubuntu-13.04-desktop-i386.iso
21ec41563ff34da27d4a0b56f2680c4f  ubuntu-13.10-desktop-amd64.iso
d0508f909c2c71d96aeac5efb0329b33  ubuntu-13.10-desktop-i386.iso

Unter MacOSX steht dazu der Befehl md5 zur Verfügung

1
2
3
4
# MD5-Summen aller *.iso-Dateien berechnen und in md5sums.txt schreiben:
md5 *.iso > md5sums.txt
# Inhalt der Datei anzeigen:
cat md5sums.txt

Als Ausgabe bekommt man z.B.:

MD5 (ubuntu-13.04-desktop-amd64.iso) = 8d72e2db7e72e13813731eab37a14d26
MD5 (ubuntu-13.04-desktop-i386.iso) = 5d5d1a7da2a0659b163d4f8bd70fbe6f
MD5 (ubuntu-13.10-desktop-amd64.iso) = 21ec41563ff34da27d4a0b56f2680c4f
MD5 (ubuntu-13.10-desktop-i386.iso) = d0508f909c2c71d96aeac5efb0329b33

Nun muss man nur noch die ermittelten Summen mit den erwarteten Summen vergleichen. Leider werden auf der Downloadseite von Ubuntu nicht mehr standardmäßig die MD5-Testsummen bereitgestellt. Allerdings gibt es eine Seite mit allen bisherigen Testsummen für Ubuntu.

Zeilenumbrüche und Absätze in LaTeX

In LaTeX gibt es mehrere Möglichkeiten „in die nächste Zeile zu springen“.

Zum einen kann ein Text in inhaltliche Einheiten („Absätze“) eingeteilt werden. Absätze zeichnen sich in der Regel dadurch aus, dass die erste Zeile eingerückt ist, und ein einen Abstand zwischen zwei Absätzen gibt. Absätze können entweder durch eine einfache Leerzeile oder durch den Befehl \par erzeugt werden:

1
2
3
4
Text des ersten Absatzes. Die erste Zeile des ersten Absatzes eines Kapitels/Section,... ist in der Regel nicht eingerückt.
 
Text des zweiten Absatzes. Dieser wird durch eine leere Zeile nach dem ersten Absatz erzeugt.\par
Text des dritten Absatzes. Dieser wird durch den Befehl \\par erzeugt.

Eine weitere Möglichkeit, die man allerdings nur in Ausnahmefällen verwenden sollte, sind Zeilenumbrüche. Diese teilen den Text nicht in logische Abschnitte ein, sondern veranlassen LaTeX nur in die nächste Zeile zu springen. Eine Einrückung der ertsen Zeile oder ein Abstand zum vorhergehenden Text erfolgt nicht. Mir fällt auch kein Beispiel ein, in dem ein Zeilenumbruch innerhalb eines laufenden Textes sinnvoll verwendet werden kann. Man kann einen Zeilenumbruch durch die Befehle \\ und \newline erzeugen.

1
ErsteZeile\\zweite Zeile\newline dritte Zeile\newline{}vierte Zeile

Mit \linebreak hat man zudem die Möglichkeit, LaTeX einen Zeilenumbruch nahezulegen (siehe auch goLaTeX und Befehls-Glossar auf WikiBooks).

Einträge ohne Nummerierung zum Inhaltsverzeichnis hinzufügen

Manchmal möchte man Einträge für Kapitel im Inhaltsverzeichnis finden, allerdings ohne Nummerierung. Haufig findet man dies für Anhänge, Danksagungen, etc., da diese nicht zum eigentlichen Inhalt der Arbeit gehören.

In der Regel teilt man dazu die Arbeit in verschiedene Bereiche ein (siehe auch WikiBooks):

1
2
3
4
5
6
7
8
9
10
11
12
13
14
\begin{document}
\frontmatter    % Römische Seitenzahlen, Chapter ohne Nummerierung
% Titelseite, Summaries, Inhaltsverzeichnis,...
 
\mainmatter     % Nummerierte Chapter, Arabische Seitenzahlen
% Einleitung, Methoden, Ergebnisse, Diskussion, (Referenzen),...
 
\appendix       % Chapter beginnen mit einem Buchstaben
% Anhänge, (Glossar, Index),...
 
\backmatter     % Chapter ohne Nummerierung
% Danksagung, ERklärung, Lebenslauf,...
 
\end{document}

Wer diese Einteilung nicht nutzen möchte, kann auch manuell Einträge zum Inhaltsverzeichnis („table of contents“, TOC) hinzufügen. Dazu erstellt man mit Hilfe des * einen Eintrag, der nicht zum Inhaltsverzeichnis hinzugefügt wird. Im Anschluss fügt man den Eintrag manuell hinzu

\chapter{Anhang}
\addcontentsline{toc}{chapter}{Anhang}

Aktuelle Jahreszahl in einem LaTeX-Dokument anzeigen

In LaTeX kann man das aktuelle Datum in einen Text einfügen. In der Präambel findet man z.B. häufig die Angabe:

\date{\today}

Dieser Befehl fügt in den Titel des Dokumentes das aktuelle Datum ein, z.B. October 2, 2013.

Manchmal möchte man allerdings nur die aktuelle Jahreszahl, den Monat oder den Tag in das Dokument einfügen. Diese Zahlen sind in den TeX-Primitiven \year, \month, \day gespeichert und können mit Hilfe von \the oder \number in das Dokument eingefügt werden.

\documentclass[a4paper]{article}
\usepackage[english,ngerman]{babel}
\begin{document}
%
% Die Ausgabe von \today ist abhängig von der Sprache:
Deutsche Ausgabe: \today
\selectlanguage{english}\\
Englische Ausgabe: \today \\
%
% Einzelne Werte einfügen
Aktueller Tag: \the\day\\
Aktueller Monat: \the\month\\
Aktuelles Jahr: \the\year
\end{document}

Weitere Beispiele und Details finden sich auf WikiBooks.org.

Befehle die ich häufig in der LaTeX-Präambel verwende

Seit ich mit LaTeX begonnen habe, habe ich viele Pakete kennengelernt und eigene Befehle entwickelt. Alle haben irgendwo einen Platz in der Präambel gefunden. Problematisch wird es, wenn ich mit alten LaTex-Dokumenten arbeite, in denen ich bestimmte Befehle noch nicht verwendet habe. Oder wenn ich die Präambel eines Dokumentes kopiere, in dem unnötige Pakete eingebunden werden. Oftmals vergesse ich auch altenative Parameter, die man für ein Paket verwenden kann.

Da das alles sehr lästig ist, beginne ich jetzt diese Liste mit Befehlen aus meinen Präambeln. Dabei stelle ich kurz vor, warum ich ein Paket verwende und welche Prameter man verwenden kann.

Als allgemeine Einleitung zu LaTeX eigenet sich auf jedenfall „The not so Short Introduction to LaTeX„, die es in einer Kurzfassung auch auf deutsch gibt.

Dokumententyp

  1. 1
    
    \documentclass[a4paper,twoside,12pt]{scrartcl}

    Mit dieser Zeile wird der Dokumententyp scrartcl verwendet. Häufig verwendete Dokumententypen sind:

    • article – Kurze Artikel
    • report – Lange Berichte
    • book – Bücher
    • scrartcl – Kurze Artikel (KOMA Script)
    • scrreprt – Lange Berichte (KOMA Script)
    • scrbook – Bücher (KOMA Script)

    KOMA-Script erlaubt eine bessere Anpassung z.B. an DIN-Formate.
    Wichtige Optionen sind der Dokumententypen sind:

    • a4paper – DIN-A4 als Seitengröße verwenden (Andere: letterpaper)
    • twoside – Doppelseitigen Satz verwenden (Standard: oneside)
    • 12pt – Angabe der Schriftgröße in Punkten (Standard: 10pt)
    • titlepage – Nach dem Dokumententitel eine neue Seite beginnen (Standard bei book und report; bei article ist der Standard notitlepage)
    • twocolumn – Teile die Seiten in zwei Spalten auf (Standard: onecolumn)
    • openright, openany – Sollen Kapitel immer auf der rechten Seite begonnen werden?
  2. 1
    
    \pagestyle{headings}

    In LaTeX gibt es drei verschiedene Seitenlayouts:

    • plain – Setze die Seitenzahl zentriert unten auf die Seite.
    • headings – Zeige Seitenzahl und Kapitelnamen in der Kopfzeile jeder Seite an.
    • empty – Zeige weder Seitenzahlen, noch Kapitelnamen an.

Sprache und Zeichensatz

  1. 1
    
    \usepackage[english]{babel}

    Verschiedene Sprachen haben auch verschiedene Trennungsregeln. Unter anderem werden diese in Paket babel definiert.

    • english – englische Trennungsregeln verwenden
    • ngerman – deutsche Trennungsregeln verwenden (neue Rechtschreibung)
    • german – deutsche Trennungsregeln verwenden (alte Rechtschreibung)
    • ngerman,english – deutsche und englische Trennungsregeln laden (z.B. bei mehrsprachigen Dokumenten). Im Dokument die aktiven Trennungsregeln umschalten mit:
      \selectlanguage{ngerman}
  2. 1
    2
    3
    
    \usepackage{ucs}              % Unicode (u.A. UTF-8) hinzuladen!
    \usepackage[utf8x]{inputenc}  % Verwende UTF-8 als Zeichensatz.
    \usepackage[T1]{fontenc}      % Trennung von Umlauten ermöglichen(?)

    Sofern man Sonderzeichen aus mehreren Sprachen in einem Dokument verwendet (z.B. Sonderzeichen in den Autorennamen der Literaturliste), sollte man den Unicode-Zeichensatz UTF-8 als Zeichensatz seines Dokumentes verwenden. Das Dokument selbst sollte dann auch in diesem Zeichensatz gespeichert werden. Man sollte auch beachten, dass zusätzliche Dokumente wie .bib-Dateien auch im UTF-8 Zeichensatz gespeichert werden müssen. Im Referenzmanager JabRef kann man unter file / database properties / encoding UTF-8 einstellen!

Beispiel

Ein Dokument mit den oben beschriebenen Werten für die Präambel könnte folgendermaßen aussehen:

1
2
3
4
5
6
7
8
9
10
11
12
% Dokumententyp
\documentclass[a4paper,twoside,12pt]{scrartcl}
\pagestyle{headings}
% Sprache und Zeichensatz
\usepackage[english]{babel}
\usepackage{ucs}              % Unicode (u.A. UTF-8) hinzuladen!
\usepackage[utf8x]{inputenc}  % Verwende UTF-8 als Zeichensatz.
\usepackage[T1]{fontenc}      % Trennung von Umlauten ermöglichen(?)
 
\begin{document}
Text
\end{document}

LaTeX-Datei in mehrere Dateien aufteilen

Abschlussarbeiten oder Publikationen können oft viel Text enthalten. Große LaTeX-Dateien werden allerdings sehr schnell unübersichtlich. Daher kann man z.B. Kapitel, Deckblätter, Glossare,… in eigene Dateien auslagern. Diese Dateien werden dann in einer Haupt-Datei wieder zusammengeführt, indem man sie mit dem Befehl \input() einbindet. Im Vergleich zu include() kann input():

  • innerhalb der Präambel verwendet werden (z.B. für ein Glossar)
  • innerhalb einer mit input() eingefügten Datei verwendet werden (Verschachtelung)
  • verwendet werden, ohne das zwingend ein Zeilenumbruch erfolgt

(siehe dazu auch: Vergleich von input und include).

Angenommen die Abschlussarbeit befindet sich in der Datei arbeit.tex. Diese könnte z.B. folgenden Inhalt haben:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
\documentclass[12pt,twoside]{article}
 
\title{Meine Abschlussarbeit}
\author{Max Mustermann}
\date{\today}
 
\begin{document}
 
\maketitle
\tableofcontents{}
 
\input{einleitung}    % binde die Datei einleitung.tex ein
\input{methoden}      % binde die Datei methoden.tex ein
% ... (weitere Dateien Einbinden)
 
\end{document}

In diesem Falle muss es zwei weitere Dateien geben: einleitung.tex und methoden.tex.
Diese beiden Dateien entahlten die Inhalte, die mit Hilfe der Datei arbeit.tex zusammengefügt werden.
In der Datei einleitung.tex könnte Folgendes stehen:

1
2
3
% !TEX root = arbeit.tex
\section{Einleitung}
Einführung in die Thematik dieser Arbeit.

In der Datei methoden.tex könnte z.B. folgender Inhalt stehen:

1
2
3
% !TEX root = arbeit.tex
\section{Methoden}
Verwendete Methoden.

Die einzelnen Dateien für die Sections haben dabei keine eigene Präambel und kein eigenes \begin{document}. Arbeitet man also an einer dieser Dateien und startet aus seinem Editor heraus latex/pdflatex für diese Datei, bekommt man in der Regel eine Fehlermeldung:

! LaTeX Error: Missing \begin{document}.

Daher sollte man zu Beginn jeder Datei die Zeile % !TEX root = arbeit.tex hinzufügen. Diese Zeile teilt LaTeX mit, welches die Haupt-Datei (root = Wurzel) der Arbeit ist. Im Anschluss verwendet LaTeX anstatt der aktuellen Datei immer die Haupt-Datei (hier: arbeit.tex) zum setzen und nicht die aktuell bearbeitete Datei.
Siehe dazu auch codepills.

Die richtigen Tasten auf deutscher Tastatur bei englischer Tastaturbelegung finden

Der ein oder andere kennt das Problem: der Rechner funktioniert nicht, und man muss ins Wiederherstellungs-Terminal. Zu dem Zeitpunkt ist allerdings die korrekte Tastaturbelegung noch nicht geladen. Man hat zwar eine deutsche Tastatur angeschlossen, aber die gedrückten Tasten (deren Signale) werden so interpretiert, als handele es sich um eine englische Tastatur. Dann geht das suchen los, denn Passwörter und Terminal-Befehle wollen richtig eingegeben werden.

Die folgende kleine Liste enthält häufig benötigte Zeichen, sowie die Taste oder Tastenkombination, die dazu auf einer deutschen Tastatur gedrückt werden muss.

Gewünschtes Zeichen Taste / Tastenkombintation
* ⇧ Shift + 8
| ⇧ Shift + #
@ ⇧ Shift + 2
?
/
y z
z y
= ´

Eine Liste zu einem data.frame konvertieren in R

Manchmal liegen in R Daten in Form einer Liste vor (z.B. die Ausgabe der Funktion hist()). In einer Liste können Daten enthalten sein, die eine unterschiedliche Länge haben. Im Falle von hist() sind z.B. Arrays unterschiedlicher Länge gemeinsam mit einfachen Variablen in einer Liste kombiniert.

Für weitere Analysen kann es jedeoch hilfreich sein, die gleich langen Teile in einen separaten data.frame auszulagern. Dann kann z.B. mit Hilfe der Funktion subset() relativ einfach Bereiche aus den Daten herausfiltern.

In R gibt es keine vorgefertigte Funktion, die direkt Daten vom Typ list in Daten vom Typ data.frame konvertieren kann. Das liegt daran, dass in einem data.frame alle enthaltenen Variablen (in der Regel Arrays) die gleiche Länge haben müssen. Unsere Entscheidung, welche Variablen aus der Liste in den data.frame übernommen werden sollen, müssen wir R mitteilen.

Das folgende Beispiel zeigt, wie man das sehr einfach bewerkstelligen kann:

1
2
3
4
5
6
7
8
# Liste mit Arrays ("x", "y", "sd") und einer Variablen ("name")
liste = list(x=c(1:5), y=c(11:15), sd=c(0,1,2,0,0), name="Meine Liste")
 
# data.frame ("df") erzeugen mit den Variablen "x", "y" und "sd"
df = with(data=liste, expr=data.frame(x, y))
 
# Struktur des data.frames ausgeben
str(df)
'data.frame':	5 obs. of  3 variables:
 $ x : int  1 2 3 4 5
 $ y : int  11 12 13 14 15
 $ sd: num  0 1 2 0 0

Im Anschluss kann man sehr einfach nur bestimmte Teile des data.frame ausgeben lassen.
Das kann man z.B. direkt über den Index (df[zeile, spalte]) oder über die Funktion subset() machen.

1
2
3
4
5
6
7
8
9
# Nur das zweite und vierte Element (Zeile) anzeigen
df[c(2,4),]
 
# Nur die Elemente (Zeilen) anzeigen, bei denen x>2 ist
df[(df$x>2),]
 
# Nur die Elemente (Zeilen) der Variablen (Spalten) x und y ausgeben,
# bei denen sd<1 und x>2 ist
subset(df, subset=(x>2 & sd<1), select=c(x,y))

Klassifizierung von Messwerten in R

Stell Dir vor, Du hast die Länge von 1000 Fischen gemessen. Im Anschluss möchtest Du die eine Häufigkeitsverteilung (Histogramm) der Größen erstellen. Je nachdem wie genau du gemessen hast, wirst du keine zwei Fische mit der gleichen Länge finden. Daher bist Du gut beraten, die Daten zunächst in bestimmte Längenklassen einzuteilen (z.B. „Anzahl von Fischen zwischen 23cm und 24cm“). Für diese Klassifizierung (binning) steht Dir in R die Funktion hist() zur Verfügung.

Nehmen wir mal an, die Längen der Fische folgen einer Normalverteilung. Im Durschnitt haben die Fische eine Länge von 25cm (± 5cm)

1
2
3
# Ziehe Eintausend Zufallszahlen aus einer Normalverteilung
# (Mittelwert: 25; Standardabweichung: 5)
laengen = rnorm(n=1e3, mean=25, sd=5)

Mit der Funktion hist() kannst Du die Daten nun in Klassen einteilen und plotten lassen.

1
2
3
# Klassifiziere die Daten
# (=Erstelle eine Histogramm und stelle es dar)
gebinnt = hist(laengen, plot=TRUE)
Automatisch erstelltes Histogramm der Beispieldaten. Die Klassengrenzen wurden von R bestimmt.
Automatisch erstelltes Histogramm der Beispieldaten. Die Klassengrenzen wurden von R bestimmt.

hist() erstellt nun eine list, in der die Klassengrenzen (breaks), die Häufigkeiten (counts), Dichten (densitiy) und Klassenmitten (mids), sowie der Name der ursprünglichen Variable (xname) und die Information, ob die Klassen alle gleich groß sind (equidist), gespeichert werden:

1
str(gebinnt)
List of 7
 $ breaks     : num [1:9] 5 10 15 20 25 30 35 40 45
 $ counts     : int [1:8] 3 29 140 370 312 129 15 2
 $ intensities: num [1:8] 0.0006 0.0058 0.028 0.074 0.0624 0.0258 0.003 0.0004
 $ density    : num [1:8] 0.0006 0.0058 0.028 0.074 0.0624 0.0258 0.003 0.0004
 $ mids       : num [1:8] 7.5 12.5 17.5 22.5 27.5 32.5 37.5 42.5
 $ xname      : chr "laengen"
 $ equidist   : logi TRUE
 - attr(*, "class")= chr "histogram"

Für weitere Analysen kannst Du selbst noch die Breite der Klassen (breite) und den Anteil der Klassen an der Stichprobe (anteil) zur Liste hinzufügen:

1
2
gebinnt$breite = diff(gebinnt$breaks)
gebinnt$anteil = gebinnt$counts / sum(gebinnt$counts)

Eigene Klassenbreiten festlegen

Du hast natürlich auch die Möglichkeit, selbst Klassengrenzen (breaks) anzugeben. Die Klassen müssen auch nicht alle gleich Groß sein. Bei einigen Daten können z.B. logarithmische Bin-Größen sinnvoll sein.

1
2
3
4
# Klassen mit Klassenbreite 1 (cm) erstellen
gebinnt = hist(
  laengen, plot=T, breaks=c(0:50)
  , xlab="Länge (cm)", ylab="Häufigkeit", main="Häufigkeitsverteilung")
Histogramm mit selbst gewählten Klassengrenzen (hier: Klassenbreite=1cm)
Histogramm mit selbst gewählten Klassengrenzen (hier: Klassenbreite=1cm)

Hierbei muss man allerdings darauf achten, dass keiner der Werte ausgeschlossen wurde, weil er ausserhalb der gewählten Klassen lag bzw. auf die untere (oder obere) Klassengrenze gefallen ist.

Fehler in hist.default(laengen, plot = T, breaks = c(15:50), xlab = "Länge (cm)",  : 
  einige 'x' nicht gezählt: evtl. überdecken die 'breaks' nicht den gesamten Bereich von 'x'

Daher sollte man immer prüfen, ob die Summe der Werte in den Klassen auch tatsächlich der Stichprobengröße entspricht.

# Sind alle Messwerte der Stichpobe im Histogramm berücksichtigt?
sum(gebinnt$counts)

Eventuell muss man dann weitere Klasse hinzunehmen, bzw. die untere (oder obere) Klassengrenze zu einer Klasse hinzu zählen (Option include.lowest=T).

Alternativen

Alternativ zur Funktion hist() könnte man ein Histogramm auch durch die Anwendung der Funktion table() auf gerundete Daten (round()) erstellen: table(round(daten)).

Die Funktion table() ist dazu gedacht die „Anzahl gleicher Werte zu ermitteln“. Das entspricht aber nicht ganz dem Gedanken der Klassifizierung.