EMZETT.
Login

Kurz: Ein Data Frame ist die zentrale Tabellenstruktur: Spalten sind Vektoren (jeweils ein Typ), Zeilen Beobachtungen.

Teil des Kurses R

Kapitel 4 von 9 im Kurs R. Mit Fortschritt, Quiz und Zertifikat auf der Lernseite.

Tabellen in R

Ein Data Frame ist die zentrale Tabellenstruktur: Spalten sind Vektoren (jeweils ein Typ), Zeilen Beobachtungen.

df <- data.frame(
  name = c("Mia", "Tom", "Zoe", "Ben", "Eva"),
  alter = c(17, 25, 31, 9, 40),
  stadt = c("Berlin", "Hamburg", "Berlin", "Köln", "Berlin"),
  punkte = c(120, 80, 200, NA, 150),
  stringsAsFactors = FALSE
)
df
str(df)
dim(df); nrow(df); ncol(df); names(df)
summary(df$alter)
df$name
df[2, ]
df[, "alter"]
df[df$alter > 18, ]
df[df$stadt == "Berlin", c("name", "punkte")]
df[order(-df$alter), ]

Ausgabe:

name alter       stadt punkte
1  Mia    17      Berlin    120
2  Tom    25     Hamburg     80
3  Zoe    31      Berlin    200
4  Ben     9 K\303\266ln     NA
5  Eva    40      Berlin    150
'data.frame':	5 obs. of  4 variables:
 $ name  : chr  "Mia" "Tom" "Zoe" "Ben" ...
 $ alter : num  17 25 31 9 40
 $ stadt : chr  "Berlin" "Hamburg" "Berlin" "K\303\266ln" ...
 $ punkte: num  120 80 200 NA 150
[1] 5 4
[1] 5
[1] 4
[1] "name"   "alter"  "stadt"  "punkte"
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
    9.0    17.0    25.0    24.4    31.0    40.0
[1] "Mia" "Tom" "Zoe" "Ben" "Eva"
  name alter   stadt punkte
2  Tom    25 Hamburg     80
[1] 17 25 31  9 40
  name alter   stadt punkte
2  Tom    25 Hamburg     80
3  Zoe    31  Berlin    200
5  Eva    40  Berlin    150
  name punkte
1  Mia    120
3  Zoe    200
5  Eva    150
  name alter       stadt punkte
5  Eva    40      Berlin    150
3  Zoe    31      Berlin    200
2  Tom    25     Hamburg     80
1  Mia    17      Berlin    120
4  Ben     9 K\303\266ln     NA

Spalten und Zeilen ändern

df <- data.frame(name = c("Mia", "Tom", "Zoe"), alter = c(17, 25, 31), punkte = c(120, 80, 200))
df$erwachsen <- df$alter >= 18
df$stufe <- ifelse(df$punkte >= 100, "Gold", "Silber")
df$punkte_prozent <- round(df$punkte / sum(df$punkte) * 100, 1)
df
df <- rbind(df, data.frame(name = "Ben", alter = 9, punkte = 50, erwachsen = FALSE, stufe = "Bronze", punkte_prozent = 0))
df <- df[df$name != "Tom", ]
rownames(df) <- NULL
df
df$stufe <- NULL
colnames(df)[colnames(df) == "punkte"] <- "score"
head(df, 2)
subset(df, alter > 10, select = c(name, alter))
with(df, mean(score))
within(df, { doppelt <- score * 2 })
transform(df, alter_in_10 = alter + 10)

Ausgabe:

name alter punkte erwachsen  stufe punkte_prozent
1  Mia    17    120     FALSE   Gold             30
2  Tom    25     80      TRUE Silber             20
3  Zoe    31    200      TRUE   Gold             50
  name alter punkte erwachsen  stufe punkte_prozent
1  Mia    17    120     FALSE   Gold             30
2  Zoe    31    200      TRUE   Gold             50
3  Ben     9     50     FALSE Bronze              0
  name alter score erwachsen punkte_prozent
1  Mia    17   120     FALSE             30
2  Zoe    31   200      TRUE             50
  name alter
1  Mia    17
2  Zoe    31
[1] 123.3333
  name alter score erwachsen punkte_prozent doppelt
1  Mia    17   120     FALSE             30     240
2  Zoe    31   200      TRUE             50     400
3  Ben     9    50     FALSE              0     100
  name alter score erwachsen punkte_prozent alter_in_10
1  Mia    17   120     FALSE             30          27
2  Zoe    31   200      TRUE             50          41
3  Ben     9    50     FALSE              0          19

Zusammenfassen und Gruppieren

daten <- data.frame(
  stadt = c("Berlin", "Hamburg", "Berlin", "Köln", "Berlin", "Hamburg"),
  punkte = c(120, 80, 200, 90, 150, 60),
  alter = c(17, 25, 31, 9, 40, 22)
)
aggregate(punkte ~ stadt, data = daten, FUN = mean)
aggregate(cbind(punkte, alter) ~ stadt, data = daten, FUN = max)
tapply(daten$punkte, daten$stadt, sum)
table(daten$stadt)
prop.table(table(daten$stadt))
sapply(split(daten$punkte, daten$stadt), mean)
by(daten$punkte, daten$stadt, summary)[["Berlin"]]
colMeans(daten[, c("punkte", "alter")])
cor(daten$punkte, daten$alter)
daten[order(daten$stadt, -daten$punkte), ]
unique(daten$stadt)
cumsum(daten$punkte)

Ausgabe:

stadt   punkte
1      Berlin 156.6667
2     Hamburg  70.0000
3 K\303\266ln  90.0000
        stadt punkte alter
1      Berlin    200    40
2     Hamburg     80    25
3 K\303\266ln     90     9
     Berlin     Hamburg K\303\266ln
        470         140          90
 
     Berlin     Hamburg K\303\266ln
          3           2           1
 
     Berlin     Hamburg K\303\266ln
  0.5000000   0.3333333   0.1666667
     Berlin     Hamburg K\303\266ln
   156.6667     70.0000     90.0000
   Min. 1st Qu.  Median    Mean 3rd Qu.    Max.
  120.0   135.0   150.0   156.7   175.0   200.0
  punkte    alter
116.6667  24.0000
[1] 0.5626313
        stadt punkte alter
3      Berlin    200    31
5      Berlin    150    40
1      Berlin    120    17
2     Hamburg     80    25
6     Hamburg     60    22
4 K\303\266ln     90     9
[1] "Berlin"      "Hamburg"     "K\303\266ln"
[1] 120 200 400 490 640 700

Zusammenführen (Merge)

kunden <- data.frame(id = 1:4, name = c("Mia", "Tom", "Zoe", "Ben"))
bestellungen <- data.frame(kunde_id = c(1, 1, 3, 5), betrag = c(25, 60, 100, 15))
merge(kunden, bestellungen, by.x = "id", by.y = "kunde_id")                 # innerer Join
merge(kunden, bestellungen, by.x = "id", by.y = "kunde_id", all.x = TRUE)   # linker Join
merge(kunden, bestellungen, by.x = "id", by.y = "kunde_id", all = TRUE)     # voller Join
umsatz <- aggregate(betrag ~ kunde_id, bestellungen, sum)
umsatz
kunden$umsatz <- umsatz$betrag[match(kunden$id, umsatz$kunde_id)]
kunden$umsatz[is.na(kunden$umsatz)] <- 0
kunden

Ausgabe:

id name betrag
1  1  Mia     25
2  1  Mia     60
3  3  Zoe    100
  id name betrag
1  1  Mia     25
2  1  Mia     60
3  2  Tom     NA
4  3  Zoe    100
5  4  Ben     NA
  id name betrag
1  1  Mia     25
2  1  Mia     60
3  2  Tom     NA
4  3  Zoe    100
5  4  Ben     NA
6  5 <NA>     15
  kunde_id betrag
1        1     85
2        3    100
3        5     15
  id name umsatz
1  1  Mia     85
2  2  Tom      0
3  3  Zoe    100
4  4  Ben      0

Fehlende Werte

d <- data.frame(a = c(1, NA, 3, 4), b = c("x", "y", NA, "z"))
is.na(d)
colSums(is.na(d))
complete.cases(d)
na.omit(d)
d$a[is.na(d$a)] <- mean(d$a, na.rm = TRUE)
d
mean(c(1, NA, 3), na.rm = TRUE)

Ausgabe:

a     b
[1,] FALSE FALSE
[2,]  TRUE FALSE
[3,] FALSE  TRUE
[4,] FALSE FALSE
a b
1 1
[1]  TRUE FALSE FALSE  TRUE
  a b
1 1 x
4 4 z
         a    b
1 1.000000    x
2 2.666667    y
3 3.000000 <NA>
4 4.000000    z
[1] 2

Der eingebaute Datensatz mtcars

data(mtcars)
head(mtcars[order(-mtcars$mpg), c("mpg", "cyl", "hp")], 4)
table(mtcars$cyl)
aggregate(mpg ~ cyl, data = mtcars, FUN = function(x) round(mean(x), 1))
round(cor(mtcars$mpg, mtcars$wt), 3)
sapply(mtcars[, 1:4], function(x) round(mean(x), 2))
nrow(subset(mtcars, mpg > 25 & am == 1))

Ausgabe:

mpg cyl  hp
Toyota Corolla 33.9   4  65
Fiat 128       32.4   4  66
Honda Civic    30.4   4  52
Lotus Europa   30.4   4 113
 
 4  6  8
11  7 14
  cyl  mpg
1   4 26.7
2   6 19.7
3   8 15.1
[1] -0.868
   mpg    cyl   disp     hp
 20.09   6.19 230.72 146.69
[1] 6

Merke

  • data.frame(...): Spalten gleicher Länge; df$spalte, df[zeile, spalte]
  • Filtern mit logischen Bedingungen, Sortieren mit order()
  • Gruppieren: aggregate, tapply, split + sapply
  • Zusammenführen: merge(..., by =, all.x =)
  • Fehlende Werte: is.na, na.omit, complete.cases

Übungsaufgabe

Berechne mit aggregate den mittleren Verbrauch (mpg) in mtcars je Zylinderzahl und sortiere nach dem Ergebnis.

Quiz zur Selbstkontrolle

Weiter im Kurs

Zurück: Faktoren, Matrizen und Listen

Weiter: Kontrollfluss und Funktionen

Alle Kapitel: R im Überblick