14  Daten importieren

In R können Daten auf vielfältige Weise importiert werden. Das Grundproblem beim “Tausch” von Daten zwischen verschiedenen Anwendungen (z.B. SPSS oder Statistica) liegt im verwendeten Format. So können native SPSS-Dateien nur mit einem Zusatzpaket importiert werden, für Statistica gibt es ein solches Zusatzpaket (derzeit) nicht. In beiden Fällen ist es aber möglich, die Daten über das CSV-Format zu tauschen. Hierfür speichert man in SPSS den Datensatz als CSV-Datei ab und liest diese in R ein.

Bedenken Sie ebenfalls, dass R Dezimalstellen mit einem Punkt angibt, und nicht mit einem Komma. So kann es zu Fehlern kommen, wenn die zu importierenden Werte nicht ebenfalls die Dezimalstellen mit einem Punkt angeben! Dies ist ein weiterer häufiger Anfängerfehler!

14.1 Import aus Textdateien

In einer Textdatei (mit Dateiendung .txt) liegen unsere Daten wie folgt vor:

m 28 80 170
w 18 55 174
w 25 74 183
m 29 101 190
m 21 84 185
w 19 74 178
w 27 65 169
w 26 56 163
m 31 88 189
m 22 78 184 

Angenommen, diese Textdatei hieße Datentabelle.txt, und läge in unserem Arbeitsverzeichnis, dann können wir die Daten mit der Funktion read.table() in R einlesen.

# importiere Daten aus "Datentabelle.txt" 
MeineTabelle <- read.table("Datentabelle.txt", header=TRUE)
## Warning in file(file, "rt"): kann Datei 'Datentabelle.txt' nicht öffnen: Datei
## oder Verzeichnis nicht gefunden
## Error in file(file, "rt"): kann Verbindung nicht öffnen
# ausgeben 
MeineTabelle
## Error in eval(expr, envir, enclos): Objekt 'MeineTabelle' nicht gefunden

Liegt die Datei im Internet, kann die Adresse mit der Funktion url() übergeben werden.

# importiere Daten aus "Datentabelle.txt" 
MeineTabelle <- read.table(url("https://www.produnis.de/R/data/Datentabelle.txt"), header=TRUE)

# ausgeben 
MeineTabelle
##    Geschlecht Alter Gewicht Groesse
## 1           m    28      80     170
## 2           w    18      55     174
## 3           w    25      74     183
## 4           m    29     101     190
## 5           m    21      84     185
## 6           w    19      74     178
## 7           w    27      65     169
## 8           w    26      56     163
## 9           m    31      88     189
## 10          m    22      78     184

Der Parameter header=TRUE gibt an, dass in der ersten Zeile der Textdatei die Spaltennamen (Variablennamen) angegeben sind.

Da wir sonst keine Parameter übergeben haben, geht R davon aus, dass die Werte durch ein Leerzeichen getrennt sind, was in unserem Beispiel auch stimmt. Sollte die Tabelle in diesem Format vorliegen (die Daten sind mit einem Komma getrennt) …

m,28,80,170
w,18,55,174
w,25,74,183
m,29,101,190
m,21,84,185
w,19,74,178
w,27,65,169
w,26,56,163
m,31,88,189
m,22,78,184

…dann müssen wir mit der Option sep (für Datenseparator) angeben, dass die Daten mit einem Komma getrennt sind.

# importiere Daten aus "Datentabelle.txt" 
# Daten sind mit Komma getrennt 
MeineTabelle <- read.table("Datentabelle.txt", sep=",", header=TRUE)

In beiden Fällen wurde die Texttabelle als Datenframe in R importiert. Die Funktion class() bestätigt uns dies.

# welche Datenklasse wurde erzeugt? 
class(MeineTabelle)
## [1] "data.frame"

Aber welche Datentypen wurden in den Spalten erzeugt?

# welcher Datentyp liegt in Spalte 1 vor? 
class(MeineTabelle[,1])
## [1] "character"
# welcher Datentyp liegt in Spalte "Alter" vor?
class(MeineTabelle$Alter)
## [1] "integer"

Die Spalte Geschlecht wurde als character angelegt, die Variable Alter ist numerisch.

Möchten wir Geschlecht in einen Faktor umwandeln, ``überschreiben’’ wir einfach die Spalte entsprechend:

# "Geschlecht" soll factor werden
MeineTabelle$Geschlecht <- factor(MeineTabelle$Geschlecht)

# überprüfen, ob es geklappt hat
class(MeineTabelle$Geschlecht)
## [1] "factor"

14.2 Import aus CSV-Datei

Das CSV-Format (für comma-separated-values) wird von vielen Anwendungen unterstützt. So können auch Tabellen, die in LibreOffice oder Excel angelegt wurden, als CSV-Datei gespeichert werden. Wenn Sie eine Datei im CSV-Format speichern, fragt Sie Ihre Anwendung nach dem gewünschten Datenseparator, also nach dem Zeichen, durch welches die Werte voneinander getrennt sind. Standardmäßig wird hier ein Komma “,” verwendet (wie der Name CSV vermuten lässt, und was zusätzlich sicherstellt, dass die zu importierenden Daten ihre Dezimalstellen mit einem Punkt abbilden, denn sonst würde nach jedem Dezimalkomma ein neuer Wert beginnen!) oder ein Semikolon “;” . Ich persönlich verwende gerne das Semikolon.

Der Import in R erfolgt ebenfalls über die Funktion read.table(). Neben dem Parameter header muss ihr der eingestellte Datenseparator übergeben werden.

Angenommen, die CSV-Datei hieße DieDaten.csv, läge in unserem Arbeitsverzeichnis und hätte den Datenseparator “;”, dann erfolgt der Import per read.table() mit dem Befehl:

# importiere Daten aus "DieDaten.csv" 
NeueTabelle <- read.table("DieDaten.csv", sep=";", header=TRUE)
## Warning in file(file, "rt"): kann Datei 'DieDaten.csv' nicht öffnen: Datei oder
## Verzeichnis nicht gefunden
## Error in file(file, "rt"): kann Verbindung nicht öffnen

Liegt die Datei im Internet, kann die Adresse per url() Funktion übergeben werden.

# importiere Daten aus dem Internet 
NeueTabelle <- read.table(url("http://www.produnis.de/R/data/DieDaten.csv"), sep=";", header=TRUE)

# anzeigen 
NeueTabelle
##     Name   Geschlecht Lieblingsfarbe Einkommen
## 1   Hans    maennlich          gruen      1233
## 2   Caro     weiblich           blau       800
## 3   Lars intersexuell           gelb      2400
## 4   Ines     weiblich        schwarz      4000
## 5 Samira     weiblich           gelb       899
## 6  Peter    maennlich          gruen      1100
## 7  Sarah     weiblich           blau      1900

Sollte die CSV-Datei mit dem Datenseparator TAB (für Tabulator) erstellt worden sein, lautet der Befehl:

# importiere Daten # Daten sind mit TAB separiert! 
NeueTabelle <- read.table("DieDaten.csv", sep=""͡, header=TRUE)

(Separieren Sie Ihre Daten möglichst niemals mittels Tabulator, da es hier zu ungewollten Effekten kommen kann.)

Sollte read.table)() keine brauchbaren Daten erzeugen (z.B. wegen Sonderzeichen in den Daten oder wenn die Daten per TAB separiert wurden), kann auf die Funktion read.csv() zurückgegriffen werden. Letztendlich ruft diese Funktion intern auch “nur” read.table() auf, jedoch mit jeder Menge voreingestellter Parameter.

# importiere Daten mit read.csv() # Daten sind mit TAB separiert!
NeueTabelle <- read.csv("DieDaten.csv", sep=""͡, header=TRUE)

14.3 Import aus SPSS-Datei

Um native SPSS-Dateien in R zu importieren, müssen zunächste Zusatzpakete installiert werden, siehe hierzu Kapitel 16.

Zum Import von SPSS-Dateien installieren und aktivieren wir das Paket haven.

# installiere das Zusatzpaket "haven" 
install.packages("haven")
# aktiviere das Paket "haven" 
library("haven")

Das Paket haven bietet für jeden SPSS-Dateityp die passende Funktion an. Angenommen, die SPSS-Datei hieße “alteDaten.sav” und läge in unserem Arbeitsverzeichnis, dann kann sie mit der Funktion read_sav() in R importiert werden.

# importiere SPSS-Datei "alteDaten.sav" 
alteDaten <- read_sav("alteDaten.sav")
## Error: 'alteDaten.sav' does not exist in current working directory ('/home/produnis/Dokumente/Programmierung/R/R-Buch/R-buch-quarto').

In SPSS werden kategoriale Daten häufig mit Labels versehen.

# Lade Test-SPSS-Datei mit Labels 
spss <- haven::read_sav(url("https://www.produnis.de/R/data/alteDaten-lang.sav"))
head(spss)
## # A tibble: 6 × 6
##   v1                 v2                 v3            v4       v5       thetruth
##   <dbl+lbl>          <dbl+lbl>          <dbl+lbl>     <dbl+lb> <dbl+lb> <dbl+lb>
## 1 4 [strongly agree] 4 [strongly agree] 4 [strongly … NA       NA       4 [stro…
## 2 4 [strongly agree] 4 [strongly agree] 4 [strongly … NA       NA       4 [stro…
## 3 4 [strongly agree] 4 [strongly agree] 4 [strongly … NA       NA       4 [stro…
## 4 4 [strongly agree] 3 [agree]          3 [agree]      4 [str…  4 [str… 4 [stro…
## 5 3 [agree]          3 [agree]          2 [disagree]   2 [dis…  4 [str… 4 [stro…
## 6 2 [disagree]       3 [agree]          3 [agree]      2 [dis…  4 [str… 4 [stro…

Wir sehen, dass die Werte der Spalten gelabelt sind (4=strongly agree, 3=agree, usw.). Die Labels stehen in eckigen Klammern neben dem eingentlichen Wert der Variable.

Die enthaltenen Labels kann man sich mit der Funktion attr() anzeigen lassen.

# Namen der Variablen 
attr(spss, "names")
## [1] "v1"       "v2"       "v3"       "v4"       "v5"       "thetruth"

Das Label einer Variable wird angezeigt mit

# Label der Variablen 
attr(spss$v1, "label")
## [1] "Blue Question"

Die Labels innerhalb einer Variable mit

# Label der Variablenwerte für "v1"
attr(spss$v1, "labels")
## strongly disagree          disagree             agree    strongly agree 
##                 1                 2                 3                 4 
##         no answer 
##                 9

In R ist die Verwendung von Wertelabels eher untypisch. Es empfiehlt sich, die Ausprägungsstufen so wie sie sind als Werte einzutragen, also z.B. direkt “männlich” - “weiblich” - “divers” anstatt 0 - 1 - 2 und anschließender Labelung. So werden die Ausprägungen auch auf den Grafiken entsprechend “aussagekräftig” angezeigt.

Wir wandeln die Variablen in Faktoren um, welche die Labels als Levelnamen nutzen (die Funktion mutate() wird später im Abschnitt Tidyverse (siehe Kapitel 24) genauer erläutert. Der Punkt innerhalb der as_factor()-Funktion bedeutet, dass der Datenstrom der Pipe verwendet werden soll).

library(tidyverse) 
spss %>% 
  mutate(haven::as_factor(.)) 
## # A tibble: 45,278 × 6
##   v1             v2             v3             v4             v5        thetruth
##   <fct>          <fct>          <fct>          <fct>          <fct>     <fct>   
## 1 strongly agree strongly agree strongly agree <NA>           <NA>      strongl…
## 2 strongly agree strongly agree strongly agree <NA>           <NA>      strongl…
## 3 strongly agree strongly agree strongly agree <NA>           <NA>      strongl…
## 4 strongly agree agree          agree          strongly agree strongly… strongl…
## 5 agree          agree          disagree       disagree       strongly… strongl…
## 6 disagree       agree          agree          disagree       strongly… strongl…
## # ℹ 45,272 more rows

Weitere Informationen zum Umgang mit gelabelten Datensätzen erhalten Sie im Tidyverse-Abschnitt zum Datenimport (siehe Abschnitt 25.1).

14.4 Import aus Excel-Datei

Um xlsx-Dateien in R zu importieren, muss das Zusatzpakete readxl installiert werden. Der Datenimport erfolgt dann mit der Funktion read_excel():

# installiere das Zusatzpaket "readxl" 
install.packages("readxl")
# aktiviere das Paket "readxl" 
library("readxl")

# importiere Excel-Datei "alteDaten.xlsx" 
alteDaten <- read_excel("alteDaten.xlsx")

Soll ein bestimmtes Tabellenblatt der xlsx-Datei importiert werden, kann diese mit dem Parameter sheet übergeben werden.

# importiere Tabelle "Tabelle1" aus Excel-Datei "alteDaten.xlsx"
alteDaten <- read_excel("alteDaten.xlsx", sheet="Tabelle1")

Soll nur ein bestimmter Bereich der Tabelle importiert werden, kann diese mit dem Parameter range übergeben werden.

# importiere aus Excel-Datei "alteDaten.xlsx" 
# Tabellenblatt "Tabelle1" 
# im Bereich A2 bis D3 
alteDaten <- read_excel("alteDaten.xlsx", sheet="Tabelle1", range="A2:D3")

14.5 Import aus .ods-Datei

Um ods-Dateien (z.B. aus Libreoffice oder OpenOffice) in R zu importieren, muss das Zusatzpakete readODS installiert werden. Der Datenimport erfolgt dann mit der Funktion read_ods():

# installiere das Zusatzpaket "readODS"
install.packages("readODS")

# aktiviere das Paket "readODS" 
library("readODS")

# importiere ods-Datei "tolleDaten.ods" 
tolleDaten <- read_ods("tolleDaten.ods")

Soll ein bestimmtes Tabellenblatt der ods-Datei importiert werden, kann diese mit dem Parameter sheet übergeben werden.

# importiere Tabelle "Tabelle1" aus ods-Datei "cooleDaten.ods"
cooleDaten <- read_ods("cooleDaten.ods", sheet="Tabelle1")

Soll nur ein bestimmter Bereich der Tabelle importiert werden, kann diese mit dem Parameter range übergeben werden.

# importiere aus ods-Datei "cooleDaten.ods" 
# Tabellenblatt "Tabelle1" 
# im Bereich A2 bis D3 
alteDaten <- read.ods("cooleDaten.ods", sheet="Tabelle1", range="A2:D3")

14.6 Import mit RStudio

Mit RStudio können Daten sehr leicht importiert werden. Im Datenfenster klicken Sie oben auf Import Dataset.

Es öffnet sich ein kleines Fenster, in welchem Sie das gewünschte Import-Format auswählen können (Abbildung 14.1). Wie Sie sehen, werden native Dateien aus Excel, SPSS, SAS und Stata unterstützt.

Abb. 14.1: importiere Daten

Wir nehmen in diesem Beispiel From SPSS.

Da der Datenimport das Zusatzpaket haven erfordert, wird es zur Installation vorgeschlagen, sofern es noch nicht installiert ist (Abbildung 14.2). Wir bestätigen in diesem Fall mit Yes.

Abb. 14.2: Zusatzpakete installieren

Nun öffnet sich das eigentliche Importierfenster (Abbildung 14.3).

Abb. 14.3: Importfenster

Klicken Sie oben rechts auf den Browse-Knopf und wählen Sie die SPSS-Datei aus, die Sie importieren möchten. Für Abbildung 14.3 habe ich die Datei alteDaten-I.sav in meinem Arbeitsverzeichnis ausgewählt. Sobald Sie eine Datei ausgewählt haben, wird unter Data Preview eine Vorschau des zu importierenden Datensatzes angezeigt. Wie Sie sehen hat mein alter Datensatz die Variablen v1, v2, v3 , usw.

Darunter sehen Sie die Ausprägungen der Variablen.

Unter dem Vorschaufenster können Sie im linken Abschnitt (Import Options) den Objektnamen eintragen, den der Datensatz in R haben soll. Ich habe in Abbildung 14.3 den Namen alteDaten_l gewählt. Das Format ist schon automatisch auf SAV eingestellt (denn der Dateiname endet mit .sav). Der Haken bei Open Data Viewer bewirkt, dass der Datensatz nach dem Import im Scritpfenster angezeigt wird.

Im rechten Abschnitt (Code Preview) sehen Sie die R-Befehle, die in der Konosle ausgeführt werden, um den Import durchzuführen.

Klicken Sie unten rechts auf Import.

14.7 Importierte Daten ins richtige Format bringen

In R werden Dezimalstellen mit einem Punkt angegeben. Dies kann beim Importieren von Daten Probleme bereiten, insbesondere dann, wenn die zu importierenden Daten ihre Dezimalstelle mit einem Komma angeben.

Als Beispiel soll folgende CSV-Tabelle dienen. Sie enthält die beiden Variablen Anwesenheit und Note (mehr Informationen gibt es hier im Blogpost).

Mittels read.table() in Kombination mit url() lesen wir die CSV-Datei in unsere R-Session.

# einlesen
df <- read.table(url("http://www.produnis.de/R/data/anwesenheitnoten.csv"), 
            sep=";", 
            header=TRUE)

# anzeigen
df
##    Anwesenheit Note
## 1         90,9  1,7
## 2         40,9    5
## 3          100    1
## 4         81,8     
## 5            0    5
## 6          100    2
## 7         27,3  3,7
## 8         27,3    5
## 9         54,5  3,3
## 10        54,5     
## 11        45,5    4
## 12         100  1,3
## 13          50  3,3
## 14        27,3    4
## 15        68,2  2,3
## 16         100     
## 17         100    1
## 18          50    2
## 19        63,6  2,7
## 20        16,7     
## 21        31,8    4
## 22        72,7  3,3
## 23        27,3    4
## 24        31,8    3
## 25        18,2    4
## 26          80  1,7
## 27        90,9  1,3
# Datentyp
str(df)
## 'data.frame':    27 obs. of  2 variables:
##  $ Anwesenheit: chr  "90,9" "40,9" "100" "81,8" ...
##  $ Note       : chr  "1,7" "5" "1" "" ...

Die Daten sind als chr eingelesen worden. Mit der Funktion as.numeric() können wir solche Daten in numeric umwandlen, eigentlich…

dummy <-c("1", "5", "9", "18")
# anzeigen
dummy
## [1] "1"  "5"  "9"  "18"
# wandle chr in numeric um:
as.numeric(dummy)
## [1]  1  5  9 18

Bei den zuvor importierten Daten funktioniert dies aber nicht:

as.numeric(df$Anwesenheit)
## Warning: NAs durch Umwandlung erzeugt
##  [1]  NA  NA 100  NA   0 100  NA  NA  NA  NA  NA 100  50  NA  NA 100 100  50  NA
## [20]  NA  NA  NA  NA  NA  NA  80  NA

Das liegt an der Dezimaltrennung per Kommata. Wir müssen zunächst alle Kommata in Punkte umwandeln. Dies erfolgt mit der Funktion gsub(), die als Parameter den zu suchenden Wert gefolgt vom zu ersetzenden Wert entgegennimmt.

# ersetze alle Kommata durch Punkte
# in df$Note
gsub(",", ".", df$Note)
##  [1] "1.7" "5"   "1"   ""    "5"   "2"   "3.7" "5"   "3.3" ""    "4"   "1.3"
## [13] "3.3" "4"   "2.3" ""    "1"   "2"   "2.7" ""    "4"   "3.3" "4"   "3"  
## [25] "4"   "1.7" "1.3"

Jetzt bauen wir die beiden Funktionen zusammen:

as.numeric(gsub(",", ".", df$Note))
##  [1] 1.7 5.0 1.0  NA 5.0 2.0 3.7 5.0 3.3  NA 4.0 1.3 3.3 4.0 2.3  NA 1.0 2.0 2.7
## [20]  NA 4.0 3.3 4.0 3.0 4.0 1.7 1.3

Genau so wollten wir es haben. Ändern wir nun das Datenframe entsprechend:

df$Anwesenheit <- as.numeric(gsub(",", ".", df$Anwesenheit))
df$Note <- as.numeric(gsub(",", ".", df$Note))
#anzeigen
df
##    Anwesenheit Note
## 1         90.9  1.7
## 2         40.9  5.0
## 3        100.0  1.0
## 4         81.8   NA
## 5          0.0  5.0
## 6        100.0  2.0
## 7         27.3  3.7
## 8         27.3  5.0
## 9         54.5  3.3
## 10        54.5   NA
## 11        45.5  4.0
## 12       100.0  1.3
## 13        50.0  3.3
## 14        27.3  4.0
## 15        68.2  2.3
## 16       100.0   NA
## 17       100.0  1.0
## 18        50.0  2.0
## 19        63.6  2.7
## 20        16.7   NA
## 21        31.8  4.0
## 22        72.7  3.3
## 23        27.3  4.0
## 24        31.8  3.0
## 25        18.2  4.0
## 26        80.0  1.7
## 27        90.9  1.3
# Datentyp
str(df)
## 'data.frame':    27 obs. of  2 variables:
##  $ Anwesenheit: num  90.9 40.9 100 81.8 0 100 27.3 27.3 54.5 54.5 ...
##  $ Note       : num  1.7 5 1 NA 5 2 3.7 5 3.3 NA ...

Jetzt ist alles richtig eingelesen.