R braucht ein Paket, um Excel-Dateien zu lesen
Base R liest Klartextformate ohne Weiteres, aber .xlsx ist kein Text - es ist ein gezipptes XML-Bündel, und .xls davor war ein Binärformat. Es wartet kein eingebautes read.xlsx() auf dich. Um Excel-Dateien zu öffnen, installierst du ein Paket, und die Standardwahl ist readxl: Es liest sowohl .xlsx als auch .xls, hat keine externen Abhängigkeiten (kein Java, keine Excel-Installation nötig) und macht eine Sache gut.
install.packages("readxl") # once per machine
library(readxl) # once per session
Die Ausschnitte auf dieser Seite brauchen ein lokal installiertes readxl, deshalb sind sie als statischer Code statt als ausführbare Blöcke gezeigt - führ sie in deiner eigenen R-Sitzung aus. Falls Pakete neu für dich sind, die Kurzfassung: install.packages() lädt es einmal herunter, library() lädt es jedes Mal, wenn du R startest.
read_excel(): die Grundlagen
Ein Aufruf liest das erste Blatt einer Arbeitsmappe nach R:
library(readxl)
sales <- read_excel("sales.xlsx")
head(sales)
str(sales)
Dieselben Gewohnheiten wie bei jedem Import: str(), um den Typ jeder Spalte zu prüfen, head(), um die ersten Zeilen zu beäugen. Wird die Datei nicht gefunden, ist die Ursache fast immer das Arbeitsverzeichnis - file.exists("sales.xlsx") sagt es dir in einer Sekunde, und die Lösung ist dieselbe wie bei CSV-Dateien: einen vollständigen Pfad nutzen oder das Arbeitsverzeichnis auf den Ordner der Datei setzen.
Zurück kommt ein Tibble - die Tidyverse-Variante des Data Frames. Für alles, was du als Einsteiger tust, verhält es sich genau wie ein Data Frame (es ist einer, mit Extras): $ holt Spalten, nrow() zählt Zeilen, es fließt in dplyr-Verben. Die sichtbaren Unterschiede sind kosmetisch und angenehm - es gibt nur die ersten zehn Zeilen mit Spaltentypen unter den Namen aus, statt alles auszukippen. Besteht eine ältere Funktion auf einem schlichten Data Frame, konvertiert as.data.frame(sales).
Blätter, Bereiche und das Überspringen von Ballast
Echte Arbeitsmappen sind selten eine saubere Tabelle, die bei Zelle A1 beginnt. readxls Argumente behandeln das übliche Chaos.
Welche Blätter gibt es? Frag, bevor du liest:
excel_sheets("report.xlsx")
# [1] "Summary" "Q1" "Q2" "Q3" "Raw data"
sheet = wählt eines aus, über Name oder Position:
q3 <- read_excel("report.xlsx", sheet = "Q3")
raw <- read_excel("report.xlsx", sheet = 5)
Bevorzuge den Namen - sheet = 5 liest still das falsche Blatt an dem Tag, an dem jemand die Register umsortiert.
range = liest ein exaktes Rechteck, in Excels eigener Notation. Das ist der sauberste Weg, Logozeilen, Titelzeilen und verirrte Notizen rund um die eigentliche Tabelle zu überspringen:
budget <- read_excel("budget.xlsx", range = "B4:E20")
budget <- read_excel("budget.xlsx", sheet = "Plan", range = "B4:E20")
skip = und col_names = sind die lockerere Alternative, wenn du weißt, wie viele Ballastzeilen über den Daten stehen, aber nicht, wo diese enden:
# Data starts after 3 title rows, first real row is the header:
df <- read_excel("export.xlsx", skip = 3)
# No header row at all - supply names yourself:
df <- read_excel("export.xlsx", col_names = c("id", "region", "amount"))
col_names = TRUE (die Voreinstellung) nutzt die erste Zeile als Namen; FALSE erzeugt ...1, ...2 und behandelt Zeile eins als Daten.
Excel schreiben braucht ein anderes Paket
readxl ist bewusst nur lesend. Wenn eine Kollegin deine Ergebnisse als Tabelle will, ist der schnellste Weg writexl - ein Einzeiler ohne Abhängigkeiten:
install.packages("writexl")
writexl::write_xlsx(results, "results.xlsx")
Brauchst du mehr als rohe Werte - fette Kopfzeilen, fixierte Bereiche, Zellfarben, mehrere formatierte Blätter in einer Arbeitsmappe -, ist das openxlsx-Gebiet:
library(openxlsx)
write.xlsx(list(Summary = summary_df, Detail = detail_df), "report.xlsx")
Aus einer benannten Liste wird ein Blatt pro Element. openxlsx kann Excel-Dateien auch lesen, du siehst es also in freier Wildbahn für beide Richtungen; für reines Lesen bleibt readxl das einfachere Werkzeug.
Die pragmatische Alternative: eine CSV exportieren
Manchmal gewinnt die am wenigsten clevere Lösung. Ist die Arbeitsmappe einmalig - jemand hat dir eine Tabelle gemailt und du brauchst die Zahlen jetzt -, öffne sie in Excel, exportiere das Blatt über "Speichern unter" als CSV und lies es mit dem Werkzeug, das du schon kennst:
df <- read.csv("sales.csv")
Kein Paket, keine Blattnamen, keine verbundenen Zellen. Der vollständige Ablauf steht unter CSV einlesen. Die Abwägungen: Du verlierst die anderen Blätter, du plättest formatierungsbasierte Information (Zellfarben, die etwas "bedeuten" - ohnehin ein Datendesign-Geruch), und der Export ist ein manueller Schritt, den jemand vergessen wird, wenn sich die Quelldatei ändert. Für eine wiederkehrende Pipeline lies die .xlsx direkt; für einen einmaligen Import ist CSV ehrlich gesagt in Ordnung.
Die klassischen Excel-Importfallen
Excel-Dateien bringen Probleme mit, die CSVs nicht haben, weil Tabellenkalkulationen Menschen Dinge tun lassen, die Tabellen nicht tun sollten.
Datumswerte kommen als Zahlen an. Excel speichert Datumswerte als fortlaufende Tageszählung, und wenn eine Spalte Typen mischt oder seltsam formatiert war, landest du bei 44688, wo du ein Datum erwartet hast. readxl konvertiert echte Datumszellen meist korrekt, aber wenn du doch die Rohzahl bekommst, konvertiere mit Excels Epoche - die 1899-12-30 ist, nicht 1970:
as.Date(44688, origin = "1899-12-30")
# [1] "2022-05-07"
Verbundene Zellen zerfallen in Leerstellen. Eine über drei Spalten verbundene Kopfzeile kommt als ein Wert und zwei leere Zellen zurück; ein über zehn Zeilen verbundenes Kategorielabel wird zu einem Wert und neun fehlenden. readxl kann keine Absicht wiederherstellen, die nur visuell existierte - erwarte, diese Lücken nach dem Import selbst zu füllen.
Eine einzige verirrte Zelle macht aus einer Spalte Text. Spaltentypen werden aus den Daten geraten, deshalb lässt ein einzelnes "n/a", eine in die Zahlen getippte Notiz oder ein Leerzeichen in einer "leeren" Zelle die ganze Spalte als character zurückkommen. str() direkt nach dem Einlesen erwischt das; das Argument col_types (z. B. col_types = c("text", "numeric", "date")) erzwingt die Sache, wenn das Raten immer wieder danebenliegt.
Das Motto: Eine Tabellenkalkulation ist eine Leinwand, auf die Menschen malen, keine Tabelle. Lies sie mit dem Skeptikerhut auf, führ str() aus und prüfe ein paar Werte gegen das Original, bevor du dem Import traust.
Was du mitnimmst
- Base R kann
.xlsxnicht lesen - installiere readxl, dannread_excel("file.xlsx"). excel_sheets()listet auf, was in einer Arbeitsmappe steckt;sheet =(bevorzugt Namen) wählt eines aus;range = "B4:E20"schneidet genau die gewünschte Tabelle heraus.- Du bekommst ein Tibble zurück - einen Data Frame mit angenehmerer Ausgabe.
- Schreiben läuft über ein anderes Paket:
writexl::write_xlsx()für schlichte Ausgabe, openxlsx für formatierte Arbeitsmappen. - Für Einmalfälle ist der Export einer CSV aus Excel und die Nutzung von
read.csv()eine völlig respektable Abkürzung. - Achte auf die drei Klassiker: Datumswerte als fortlaufende Zahlen (Ursprung
1899-12-30), verbundene Zellen, die zu Leerstellen werden, und eine schlechte Zelle, die eine Spalte auf Text zieht.
Als Nächstes: die andere Richtung - deine Data Frames in CSV- und RDS-Dateien schreiben.
Häufig gestellte Fragen
Wie liest man eine Excel-Datei in R ein?
Installiere das Paket readxl einmal mit install.packages("readxl"), lade es mit library(readxl) und ruf dann read_excel("file.xlsx") auf. Es gibt ein Tibble (einen modernen Data Frame) zurück, gebaut aus dem ersten Tabellenblatt. Mit dem Argument sheet = liest du ein anderes Blatt über Name oder Position.
Kann R Excel-Dateien ohne Paket lesen?
Nein. Base R hat keinen Leser für .xlsx oder .xls - das sind binäre bzw. gezippte Formate, kein Text. Du nutzt entweder ein Paket (readxl ist der Standard; openxlsx funktioniert auch) oder exportierst das Blatt aus Excel als CSV und nutzt read.csv(), was gar kein Paket braucht.
Wie liest man in R ein bestimmtes Tabellenblatt einer Excel-Datei?
Übergib sheet = an read_excel: read_excel("report.xlsx", sheet = "Q3") über den Namen oder sheet = 3 über die Position. Weißt du nicht, was die Arbeitsmappe enthält, gibt excel_sheets("report.xlsx") alle Blattnamen als Zeichenvektor zurück.
Wie schreibt man aus R eine Excel-Datei?
readxl liest nur. Zum Schreiben lautet der Einzeiler writexl::write_xlsx(df, "out.xlsx"). Brauchst du Formatierung - Farben, Spaltenbreiten, mehrere gestaltete Blätter -, nimm stattdessen das Paket openxlsx, das gestaltete Arbeitsmappen programmatisch bauen kann.