Ein Verzeichnis durchsuchen

Eine Liste (technisch: ein Vektor) mit den Dateinamen eines Verzeichnisses zu bekommen, ist in R total simpel. Es genügt der Befehl list.files, der verschiedene nützliche Parameter bietet. Die drei wichtigsten habe ich hier aufgelistet, insbesondere die Angabe eines regulären Ausdrucks mittels pattern ist sehr hilfreich, sofern man Dateien systematisch benannt hat. Man denke an alle Exceldateien, die mit “Quartalsreporting” beginnen und 2019 enthalten.

  • path gibt den zu durchsuchenden Pfad an. Ist kein Pfad angegeben, wird das aktuelle Arbeitsverzeichnis (siehe getwd und setwd) genommen.
  • pattern ermöglicht es, die Dateiliste mittels regulärer Ausdrücke zu filtern. Reguläre Ausdrücke sind eine in der IT übliche und sehr flexible Methode, Mengen von Strings zu beschreiben. Reguläre Ausdrücke können recht komplex sein, häufig kommt man aber mit einem einfachen Ausdruck zu Rande. Mehr über reguläre Ausdrücke findet ihr im Kapitel Strings.
  • recursive bezieht die Unterordner in die Suche mit ein, d.h. alle Dateien aus den Unterordnern werden als relativer Pfad (von der Form Unterordner/Dateiname oder Unterordner/Unterordner/Dateiname) mit ausgegeben.

Alle Parameter zum Befehl list.files findet ihr in meinem kostenlosen R-Glossar, in dem eine ständig wachsende Zahl R-Befehle mit Erklärung und Beispielen aufgelistet sind.

# gibt einen Vektor mit allen Dateien im aktuellen Arbeitsverzeichnis zurück
Dateien <- list.files() 
 
# gibt einen Vektor mit allen Dateien in einem bestimmten Verzeichnis zurück
list.files (path = "C:/Ordner/Unterordner")
 
# bezieht die Unterordner in die Suche mit ein
list.files(recursive = TRUE)
 
# auch Ordner werden mit zurückgegeben, allerdings kann man nicht mehr zwischen
# einem Ordner und einer Datei ohne Endung (ja, die gibt es, wenn auch selten) 
# unterscheiden
list.files(include.dirs = TRUE)
 
#liefert einen Vektor mit allen Dateien, welche die Endlung xlsx haben. 
# Das $-Zeichen in einem regulären Ausdruck bedeutet das Ende des Strings. 
# Würden wir es weglassen, dann würden alle Dateien, welche irgendwo xlsx im Namen
# haben, zurückgegeben.
list.files(pattern = "xlsx$")
 
#alle Dateien, die mit Report anfangen und die Endung .csv haben
list.files(pattern = "^Report(.*)\\.csv$", ignore.case=TRUE)

Es gibt übrigens auch den Befehl list.dirs, der entsprechend nur die Verzeichnisse zurückgibt. Allerdings gibt es weniger Parameter, nur path, full.names (default=TRUE) und recursive (default=TRUE) sind möglich. So werden z.B. immer die versteckten Ordner angezeigt, bei list.files gibt es dafür den Parameter all.files (default = FALSE).

GRATIS 5-Tage Minikurs: Datenanalyse in R

Du kennst Dich noch nicht so gut damit aus, wie man einen Datensatz in R analysiert? Ich bin da, um Dir zu helfen. Hole Dir jetzt meinen kostenlosen Datenanalyse mit R – Kurs und fange an, Dir diese zukunftsweisenden Skills anzueignen.

Ein Verzeichnis durchsuchen

Eine Liste (technisch: ein Vektor) mit den Dateinamen eines Verzeichnisses zu bekommen, ist in R total simpel. Es genügt der Befehl list.files, der verschiedene nützliche Parameter bietet. Die drei wichtigsten habe ich hier aufgelistet, insbesondere die Angabe eines regulären Ausdrucks mittels pattern ist sehr hilfreich, sofern man Dateien systematisch benannt hat. Man denke an alle Exceldateien, die mit “Quartalsreporting” beginnen und 2019 enthalten.

  • path gibt den zu durchsuchenden Pfad an. Ist kein Pfad angegeben, wird das aktuelle Arbeitsverzeichnis (siehe getwd und setwd) genommen.
  • pattern ermöglicht es, die Dateiliste mittels regulärer Ausdrücke zu filtern. Reguläre Ausdrücke sind eine in der IT übliche und sehr flexible Methode, Mengen von Strings zu beschreiben. Reguläre Ausdrücke können recht komplex sein, häufig kommt man aber mit einem einfachen Ausdruck zu Rande. Mehr über reguläre Ausdrücke findet ihr im Kapitel Strings.
  • recursive bezieht die Unterordner in die Suche mit ein, d.h. alle Dateien aus den Unterordnern werden als relativer Pfad (von der Form Unterordner/Dateiname oder Unterordner/Unterordner/Dateiname) mit ausgegeben.

Alle Parameter zum Befehl list.files findet ihr in meinem kostenlosen R-Glossar, in dem eine ständig wachsende Zahl R-Befehle mit Erklärung und Beispielen aufgelistet sind.

# gibt einen Vektor mit allen Dateien im aktuellen Arbeitsverzeichnis zurück
Dateien <- list.files() 
 
# gibt einen Vektor mit allen Dateien in einem bestimmten Verzeichnis zurück
list.files (path = "C:/Ordner/Unterordner")
 
# bezieht die Unterordner in die Suche mit ein
list.files(recursive = TRUE)
 
# auch Ordner werden mit zurückgegeben, allerdings kann man nicht mehr zwischen
# einem Ordner und einer Datei ohne Endung (ja, die gibt es, wenn auch selten) 
# unterscheiden
list.files(include.dirs = TRUE)
 
#liefert einen Vektor mit allen Dateien, welche die Endlung xlsx haben. 
# Das $-Zeichen in einem regulären Ausdruck bedeutet das Ende des Strings. 
# Würden wir es weglassen, dann würden alle Dateien, welche irgendwo xlsx im Namen
# haben, zurückgegeben.
list.files(pattern = "xlsx$")
 
#alle Dateien, die mit Report anfangen und die Endung .csv haben
list.files(pattern = "^Report(.*)\\.csv$", ignore.case=TRUE)

Es gibt übrigens auch den Befehl list.dirs, der entsprechend nur die Verzeichnisse zurückgibt. Allerdings gibt es weniger Parameter, nur path, full.names (default=TRUE) und recursive (default=TRUE) sind möglich. So werden z.B. immer die versteckten Ordner angezeigt, bei list.files gibt es dafür den Parameter all.files (default = FALSE).

LERNE DATA SCIENCE mit R

Ein Data Science Experte ist in der heutigen datengetriebenen Welt viel gefragt. Mit der entsprechenden Erfahrung kann man sich den gutbezahlten, interessanten Job aussuchen. In meinem Onlinekurs Data Science mit R lernst Du die Grundlagen.

Verzeichnisse prüfen, erstellen und löschen

Um zu prüfen, ob ein Verzeichnis existiert, gibt es den Befehl dir.exists. Um ein Verzeichnis anzulegen, benutzt man dir.create.

Nur der Lösch-Befehl fällt etwas aus dem Rahmen und heißt unlink. Wichtig bei unlink ist, dass der Parameter recursive=TRUE gesetzt wird. Das hängt damit zusammen, dass unlink auch für Dateien verwendet werden kann. Auch ein leeres Verzeichnis kann nicht gelöscht werden, wenn recursive=FALSE. Der Rückgabewert, der zwar nicht wiedergegeben wird, aber per Variable abgefangen werden kann (siehe Skript), ist bei Erfolg 0, bei Fehler 1. Allerdings gilt das Fehlen des Verzeichnisses nicht als Fehler. Konnte das Verzeichnis hingegen nicht gelöscht werden, weil die Berechtigung fehlt oder es aktuell in Verwendung ist (z.B. wenn eine Datei aus dem Verzeichnis durch ein Programm geöffnet ist), dann gibt unlink 1 als Wert zurück.

# prüft, ob das Verzeichnis temp exisitert
dir.exists("temp")
 
# erstelle das Verzeichnis temp
dir.create("temp")
 
# jetzt, da wir es angelegt haben, gibt die Funktion TRUE zurück 
dir.exists("temp")
 
# auch per list.files kann man es sehen
list.files(pattern="temp", include.dirs=TRUE)
 
#häufig wird dir.exists und dir.create kombiniert
if (!dir.exists("temp")) dir.create("temp")
 
# Das Verzeichnis temp wieder löschen, inklusive aller darin enthaltenen Dateien. 
# Dabei ist wichtig, recursive=TRUE zu setzen
a <- unlink("temp", recursive=TRUE)
print(a)

Dateien in R erstellen, kopieren, umbennen und löschen

Was können wir mit Dateien anstellen? Na ja, prüfen, ob sie existieren, erstellen, kopieren, umbenennen oder löschen. Wobei das Erstellen ohne Zusammenhang eher selten vorkommt, meist schreibt man dann doch direkt eine csv- oder xlsx-Datei oder wenigstens Text in die Datei. Wie man letzteres macht, erfahrt ihr weiter unten im nächsten Abschnitt.

An sich sind die Befehle ziemlich klar aufgebaut, nämlich file.xxx. Alle Befehle nehmen nicht nur einzelne Strings mit einem Dateinamen entgegen sondern auch Vektoren von Dateinamen und führen den Befehl für alle darin enthaltenen Dateien aus.

  • file.exists prüft, ob eine oder mehrere Dateien bereits existieren und gibt dementsprechend einen Vektor mit TRUE oder FALSE zurück
  • file.create erzeugt eine leere Datei bzw. überschreibt eine existierende, sofern der Parameter overwrite=TRUE gesetzt wird.
  • file.rename benennt Dateien um
  • file.remove entfernt eine oder mehrere Dateien. Als Rückgabewert wird TRUE oder FALSE zurückgegeben, je nachdem ob eben das Löschen geklappt hat oder nicht
  • file.copy kopiert Dateien. Dabei gibt es die Parameter overwrite, copy.mode und copy.date. Overwrite sorgt dafür, dass eine schon existierende Datei überschrieben wird, mit copy.mode=TRUE kopiert R die Berechtigungen mit (Lese-/Schreib-Einschränkungen) und mit copy.date=TRUE wird das Erstellungsdatum der ursprünglichen Datei kopiert.
# prüft, ob eine Datei existiert
file.exists("abc.txt")
# erzeugt eine leere Datei
file.create("abc.txt")
# die Datei abc.txt in cde.txt umbenennen
file.rename("abc.txt", "cde.txt")
# Versucht, die Datei abc.txt zu löschen. Diese existiert aber nicht mehr, da wir sie ja 
# umbenannt habe. Daher wird eine Meldung und FALSE zurückgegeben.
file.remove("abc.txt")
# Erzeugt den Ordner Backup und kopiert die Datei cde.txt dorthin
dir.create("Backup")
file.copy("cde.txt","Backup/cde.txt",overwrite=TRUE,copy.date=TRUE)
# file.remove nimmt auch einen Vektor mit den Dateinamen entgegen und erzeugt dann 
# einen Ausgabevektor mit TRUE/FALSE
file.remove(c("cde.txt","abc.txt"))
# Das Backup-Verzeichnis wieder löschen
unlink("Backup",recursive=TRUE)

Datei-Informationen wie Datum oder Größe in R

Als letztes zeige ich euch noch, wie ihr Informationen zu Dateien in R auslesen könnt. Die wichtigsten sind vermutlich Dateigröße oder Änderungsdatum. So könnte man das Änderungsdatum checken, um zu sehen, ob es ein Update der Datei gab und es sich lohnt, den Inhalt einzulesen. Die R-Funktionen dafür sind überschaubar denn eigentlich gibt es nur file.info. Die weiteren hier aufgezählten Funktionen rufen file.info auf, sind aber eventuell bequemer in der Anwendung.

Ein bisschen tricky sind die Berechtigungen (Spalte mode), da diese kodiert sind und man sich die Werte herauspulen muss. Andererseits benötigt man diese Details eher selten.

  • file.info liefert einen data.frame mit 7 Spalten, jede Zeile entspricht einer angegeben Datei.
    • size: Die Dateigröße in Bytes
    • isdir: Handelt es sich um ein Verzeichnis
    • mode: gibt eine dreistellige Oktalzahl mit den Rechten zurück. Das Ganze ist ein bisschen kompliziert. Die drei Ziffern stehen für den Besitzer der Datei, die Gruppe, der der Besitzer angehört und jeder. Eine Ziffer setzt sich zusammen aus Lesen (Wert 4), Schreiben (Wert 2) und Ausführen (Wert 1), also z.B. 6 für Lese- und Schreibzugriff.
    • mtime: Zeitstempel, wann die Datei das letzte Mal geändert wurde
    • ctime: Zeitstempel, wann der Status der Datei das letzte Mal geändert wurde, also z.B. durch chmod auf Unix. Unter Windows entspricht das dem Erstellungsdatum.
    • atime: Zeitstempel, wann das letzte Mal auf die Datei zugegriffen wurde
    • exe: Die Ausführbarkeit auf Windows-PCs. Mögliche Werte sind “no”, “msdos”,”win16″, “win32”, “win64” und “unknown”
  • file.access testet eine Datei auf die Zugriffsmöglichkeiten, welche man mit dem Parameter mode definiert. Dabei wird 0 für Erfolg und -1 für Misserfolg zurückgegeben
    • 0: Existenz (default)
    • 1: Ausfürbarkeit
    • 2: Schreibrechte
    • 3: Leserechte
  • file.mtime gibt einen Zeitstempel (POSIXct) zurück, wann die Datei zum letzten Mal modifiziert wurde
  • file.size gibt die Größe der Datei in Bytes zurück. Um zur nächst größeren Einheit (Kilobyte, Megabyte, Gigabyte, …) zu kommen, muss man die Zahl durch 1024 teilen. Zur Illustration habe ich unten im Beispiel eine Funktion geschrieben, die einen Parameter für die Größeneinheit entgegennimmt.
# gibt einen data.frame mit vielen Informationen (Größe, Datum, ...) zu den übergebenen Dateien zurück 
file.info("cde.txt")
# Eistiert die Datei
file.access("cde.txt")
file.access("cde.txt", mode=1)
file.access("cde.txt", mode=2)
file.access("cde.txt", mode=3)
# Wann wurde die Datei zum letzten Mal modifiziert
file.mtime("cde.txt")
# die Größe der Datei in Bytes
file.size("cde.txt")
# Eine Funktion, um die Dateigröße auch in anderen Einheiten wiederzugeben
Dateigroesse <- function(Dateien, Einheit="MB") {
  # Einheit in Großbuchstaben umwandeln
  Einheit <- toupper(Einheit)
  # Fehlermeldung bei nicht unterstützter Einheit
  if(!(Einheit %in% c("B","KB","MB","GB"))) {
    print("Die Funktion unterstützt nur die Einheiten B, KB, MB und GB")
    return()
  }
  # Faktor für Einheit
   Faktor <- ifelse(Einheit=="B",1,
            ifelse(Einheit=="KB",1024,
            ifelse(Einheit=="MB",1024^2,
            ifelse(Einheit=="GB",1024^3,
            NA))))
  # Rückgabe von Bytegröße/Faktor, gerundet auf 2 Stellen
  return(round(file.size(Dateien)/Faktor,2))
}
Dateigroesse("Dateisystem_in_R.html","KB")

So, nun seid ihr Experten in Sachen Verzeichnisse und Dateien. Ich bin gespannt, welche tollen Projekte und Automatisierungen ihr damit umsetzt.

Happy coding,
Euer Holger

GRATIS 5-Tage Minikurs: Datenanalyse in R

Du kennst Dich noch nicht so gut damit aus, wie man einen Datensatz in R analysiert? Ich bin da, um Dir zu helfen. Hole Dir jetzt meinen kostenlosen Datenanalyse mit R – Kurs und fange an, Dir diese zukunftsweisenden Skills anzueignen.

LERNE DATA SCIENCE mit R

Ein Data Science Experte ist in der heutigen datengetriebenen Welt viel gefragt. Mit der entsprechenden Erfahrung kann man sich den gutbezahlten, interessanten Job aussuchen. In meinem Onlinekurs Data Science mit R lernst Du die Grundlagen.