Skip to Tutorial Content

Tools in DataScience 2: data wrangling I

Hinweis:

  • An jenen Stellen, die mit einem Graduation-Cap gekennzeichnet sind , erarbeiten Sie sich die Inhalte selbstständig
  • An Stellen mit einer Wandtafel warten Sie bitte auf Input seitens der Dozierenden


Worum geht es in dieser Sitzung:

Sie werden heute lernen, wie Sie mit Vektoren und Faktoren umgehen und diese bearbeiten können.

Um unsere Beispieldaten in R bearbeiten zu können, erfahren Sie wie Sie verschiedene Datenformate als Data Frame in R importieren oder einen Data Frame eigenständig generieren können.

Um die Daten einer Datentabelle in Form eines Data Frame bearbeiten zu können, lernen Sie die wichtigsten Funktionen des package dplyr kennen, mit denen Sie bspw. neue Spalten hinzufügen oder bestehende verändern können.

Um abschliessend einen ersten Überblick über die Beispieldaten zu erhalten, lernen Sie wie man Informationen aus Datentabellen extrahiert und in Form der gängigen Lage- und Streuungsmasse (Mittelwert, Median, Standardabweichung, Maximum, Minimum) zusammenfasst. Dieser letzte Prozess fordert, je nachdem ob Sie theoriegeleitet vorgehen oder nicht, auch Ihre Kreativität und folgt meist keinen konkreten Regeln - ist also explorativ.


Detaillierte Beschreibung unserer Beispieldatensätze

Datensatz zur Optimierung der Verkaufspreise im Einzelhandel

Wir arbeiten in den folgenden Sitzungen mit den Daten eines Cafés, welche zur Optimierung der Preisgestaltung über den Zeitraum von 2012-2015 gesammelt wurden. Sie könnten bspw. dazu genutzt werden, auf der Grundlage der vergangenen Verkäufe die Preiselastizität und die optimalen Preise für die Artikel zu ermitteln.

Der Datensatz bestzeht aus 3 Teildatensätzen:

a) CafeTransactionStore: Informationen über Preis, Absatzmenge und Produkt(kategorie) aller Transaktionen des Cafes. Eine Transaktion entspricht dem Verkauf eines Produktes in bestimmter Menge an einem Tag. Pro Tag kann es mehrere Transaktionen geben, da es verschiedene Produkte gibt (bspw. Coke, Burger, Lemonade, Coke & Burger, etc.).

  • CALENDAR_DATE
  • PRICE
  • QUANTITY
  • SELL_ID
  • SELL_CATEGORY

b) CafeDateInfo: Informationen über den jeweiligen Transaktionstag des Cafes

  • CALENDAR_DATE (Monat/Tag/Jahr)
  • YEAR
  • HOLIDAY (kein Festtag oder einer von 8 Festtagen)
  • IS_WEEKEND (Nein (0),Ja (1))
  • IS_SCHOOLBREAK (Nein (0), Ja (1))
  • AVERAGE_TEMPERATURE (in Grad Fahrenheit)
  • IS_OUTDOOR: Verkauf hat im Cafe oder vor dem Cafe stattgefunden (drinnen (0), draussen (1))

c) CafeSellMeta: Informationen über die Produkte des Cafes

  • SELL_ID - kategoriale Variable, die das verkaufte Produkt identifiziert (4 Singleprodukte (Burger, Cola, Limo, Kaffee), 3 Kombiprodukte (Burger&Cola, Burger&Limo, Burger&Cola&Kaffee)

  • SELL_CATEGORY- kategoriale Variable, die das verkaufte Produkt einer Produktkategorie zuordnet (Produkt einzeln verkauft (0); Produkt in Verbindung mit anderem(n) Produkt(en) verkauft –> als Menü (2) Hinweis: Werden Produkte im Menü angeboten, sind sowohl die Fleischmenge bei Burgern als auch die Füllmenge bei Getränken geringer.)

  • ITEM_ID - ID des Produkts (7821, 3052, 5030, 6249)

  • ITEM_NAME - Name des Produkts (Burger, Cola, Limonade, Kaffee)

Insgesamt gibt es also 13 unterschiedliche Variablen, die eine Mischung aus Faktoren und numerischen Datentypen sind.

Der Datensatz enthält keine fehlenden Werte.

Insgesamt gibt es 5404 Datenzeilen im Transaktionsdatensatz und 1349 Datenzeilen (eigentlich 1348 - wir kommen in Sitzung III darauf zurück) im Datensatz zum Transaktionstag.

Der Unterschied in den Datenzeilen liegt darin begründet, dass an einigen Tagen mehrere Transaktionen hinterlegt sind.


Quiz zum Case der Sitzungen mit RStudio

Quiz

Einführung / Wiederholung von Basisbefehlen in R: Vektoren, Faktoren & Data Frames

(Zeit: ca. 60 min)

Wir werden den importierten CafeTransactionStore.csv Datensatz in einem Data Frame speichern.
Data Frames sind beliebt, da man die Daten der bisher besprochenen Datentypen (doubles, characters, logicals usw.) in einem tabellarischen Format speichern kann (ähnlich einer klassischen Tabelle in proprietären Datenformaten wie bspw. Excel).

Bevor wir nun mit den importierten Daten arbeiten, erhalten Sie Zeit um sich nochmals vertieft mit Vektoren, und, zusätzlich, mit Faktoren und Data Frames in R vertraut zu machen. Wenn Sie bereits Erfahrung damit haben, können Sie die Zeit nutzen um Ihr Wissen aufzufrischen.

Nutzen Sie dazu das Tutorial learn, welches aus einem Lehrfondsprojekt entstanden ist. Es ermöglicht den Studierenden der Studiengänge Betriebsökonomie und International Management R kennenzulernen. Der VPN der FHNW muss zum Absolvieren des Tutorials eingestellt sein. Das Tutorial auf Englisch finden Sie hier: http://learn.fhnw.ch/english.html

Hinweise zum Vorgehen:

  • Bitte studieren Sie nun die learn Tutorials Unit 1.4 Data structures I.
  • Sie finden hier bei RAPP auf der nächsten Seite Übungsaufgaben zu diesem Thema, die Ihnen bei Verständnis und der Festigung Ihres Wissens helfen werden.

Bei Fragen erhalten Sie Unterstützung von den Dozierenden.

Übungen: Vektoren und Faktoren in R

Erstellen Sie mit der “as.integer” “concatenate” Funktion einen Vektor x vom Typ “integer”,
der die Werte 1 bis 4 und den Wert 5.5 enthält.
Prüfen Sie mit der “is.integer” Funktion, ob der Datentyp korrekt ist.
x<-as.integer(c(1,2,3,4,5.5))
is.integer(x)


Erstellen Sie erneut einen Vektor x. Dieser soll folgende Bezeichnung enthalten: “VornameNachname”.
Prüfen Sie mit der typeof() Funktion, um welchen Datentyp es sich handelt.

x<-"VornameNachname"
typeof(x)


Um welchen Datentyp handelt sich bei einem Vektor, der sowohl das Alter von 33 Jahren,
den Nachnamen der Person “Suter” und den Preis des gekauften Produktes von 12.50 CHF enthält?

x<-c(33, "Suter", 12.50)
typeof(x)


Addieren Sie die 2 folgenden Vektoren und speichern Sie das Ergebnis in einem neuen Vektor k.
Welcher Wert ergibt sich für k an letzter Stelle [3]?

a<-c(5,15,20)
b<-c(5,5)
k<-a+b
k[3]


Sie sehen in der folgenden Abbildung 2 Vektoren ungleicher Länge.

x <- c(15, 25, 35)  
y <- c(10, 20, 30, 40)  
Quiz


Ihnen liegt folgender Vektor vor.

Kunden <- c('ID1_"61"_Herzog', 'ID2_"20"_Franzen', 'ID3_"73"_Schneider')
Quiz


Ihnen liegt die folgende Syntaxzeile vor.

k<-substr(Kunden <- c('ID1_"61"_Herzog', 'ID2_"20"_Franzen', 'ID3_"73"_Schneider'), 6, 7)
Quiz


Sie haben einen neuen Vektor mit dem Alter der Kunden erzeugt, der insgesamt 330 Einträge enthält.
Sie wollen sich das Alter der letzten 5 Einträge im Vektor anzeigen lassen (also 326-330).

Quiz


Sie haben einen neuen Vektor mit dem Alter der Kunden erzeugt, der insgesamt 330 Einträge enthält.
Wie sich durch einen Blick in die Daten gezeigt hat, sind auch Fehlwerte - also “NA” Einträge vorhanden.

Quiz


Sie haben einen neuen Vektor mit dem Alter der Kunden erzeugt, der insgesamt 330 Einträge enthält.
Wie sich durch einen Blick in die Daten gezeigt hat, sind auch Fehlwerte - also “NA” Einträge vorhanden.

Quiz


Speichern Sie den Vektor “Alter” in einem neuen Vektor “alter_neu” ohne Fehlwerte ab.
Berechnen Sie die Differenz in der Personenzahl zwischen dem alten und neuen Altersvektor
und speichern Sie diese im Vektor d. Wenden Sie abschliessend die Funktion as.numeric() auf den Vektor d an.

alter_neu<-alter[!is.na(alter)]
d<-length(alter)-length(alter_neu)
as.numeric(d)


Als Auschnitt eines grösseren Datensatzes erhalten Sie die 2 Vektoren einer Person (in 3 Stufen) und das in CHF. Die Daten enthalten keine Fehlwerte.
Sehen Sie sich mit der by()-Funktion die wichtigsten univariaten Statistikkennwerte für das Einkommen, getrennt nach Bildungsgrad an.
Speichern Sie anschliessend in einer separaten Zeile das mittlere Einkommen von Personen mit Bildungsstufe 3 (>10 Bildungsjahren) im Vektor x.

by(einkommen, bildung, summary)
x<-mean(einkommen[(bildung == 3)])
x


Erstellen Sie nun im selben Datensatz einen Faktor aus dem Vektor Bildung. Nutzen Sie die label (<8 Bildungsjahre, 8-10 Bildungsjahre, >10 Bildungsjahre). Überprüfen Sie mit dem table Befehl, ob die Zuweisung der beiden Vektoren funktioniert hat.

bildung_factor <- factor(bildung, levels = c(1, 2, 3), labels = c("<8 Bildungsjahre", "8-10 Bildungsjahre", ">10 Bildungsjahre"))
typeof(bildung_factor)
table(bildung, bildung_factor)

Übungen: Data Frames

Quiz


1

Erstellen Sie einen Data Frame mit dem Namen “df1”. df1 soll aus 5 Zeilen und 2 Spalten bestehen. Spalte 1 ist das Geschlecht (Typ: “character”) mit den Ausprägungen “m” (2x) und “w” (3x). Spalte 2 ist der Lohn, aufsteigend, von 1000 - 5000 CHF in 1000er Schritten.

Prüfen Sie mit der is.character() Funktion, ob der Datentyp des Geschlechts als character in df1 abgespeichert ist.

#DF-Erstellung Option 1:
df1 <- data.frame(
  geschlecht = c('m','m','w','w','w'),
  lohn = c(1000,2000,3000,4000,5000),
  stringsAsFactors = FALSE
)

#DF-Erstellung Option 2:
df1<-data.frame(
  geschlecht=c(rep("m", times=2), rep("w", times=3)),
  lohn=c(seq(from=1000, to=5000, by=1000)),
  stringsAsFactors = FALSE
)

#
str(df1)
is.character(df1$geschlecht)


2

Wir verwenden erneut den Data Frame “df1”, erweitern ihn aber um die Variable “var3”
,die den Bildungsgrad (kodiert von 1 “gering” - 3 “hoch”) wie folgt enthält: c(2,3,3,1,2). Erweitern Sie den untenstehenden Code.

Benennen Sie nun die Variable “var3” in “bildungsgrad” um. Zeigen Sie den Eintrag in der 4. Zeile des “bildungsgrades” an.

#Erstellung df1 mit Erweiterung
df1 <- data.frame(
  geschlecht = c('m','m','w','w','w'),
  lohn = c(1000,2000,3000,4000,5000),
  var3 = c(2,3,3,1,2),
  stringsAsFactors = FALSE
)

#Umbenennung
#Option1
colnames(df1)[3] <- "bildungsgrad"

#Option2 - falls es grössere Datensätze sind und man die Position der neuen Variable nicht kennt
colnames(df1)[which(names(df1) == "var3")] <- "bildungsgrad"

#
df1[4, 3]


3

Wir verwenden den erweiterten Data Frame “df1” aus der letzten Übung.
Erweitern Sie den untenstehenden Code wie folgt:

Zeigen Sie nur Löhne an, die grösser als 4000 CHF sind. Beschränken Sie die Ausgabe auf die Lohnvariable.

#Erstellung df1
df1 <- data.frame(
  geschlecht = c('m','m','w','w','w'),
  lohn = c(1000,2000,3000,4000,5000),
  bildung = c(2,3,3,1,2),
  stringsAsFactors = FALSE
)
df1$lohn[df1$lohn > 4000]


4

Wir verwenden den erweiterten Data Frame “df1” aus der letzten Übung.
Erweitern Sie den untenstehenden Code wie folgt:

Speichern Sie die ersten 4 Zeilen der Variablen “geschlecht” und “lohn” in einem neuen Data Frame df2.
Zeigen Sie den mittleren Lohn der Frauen (geschlecht == “w”) aus dem df2 an.

#Erstellung df1
df1 <- data.frame(
  geschlecht = c('m','m','w','w','w'),
  lohn = c(1000,2000,3000,4000,5000),
  bildung = c(2,3,3,1,2),
  stringsAsFactors = FALSE
)
df2<-data.frame(df1[c(1:4), c("geschlecht", "lohn")])
mean(df2[df2$geschlecht == "w", "lohn"])




df <- read.table("preise.csv", header = TRUE, sep = ",", stringsAsFactors = TRUE)
Quiz


Import des Datensatzes in einen Data Frame

Importieren Sie nun den Datensatz “CafeTransactionStore.csv” und speichern Sie ihn in einem Data Frame.

Die Daten sind Kommasepariert und wurden mit dem read_table() Befehl in den Data Frame “cts” importiert.
Mit dem Befehl colnames() kann man die Kopfzeile inspizieren, mit ncol() die Anzahl der Variablen bzw. Spalten im tibble.
Die (den) Variablen(typ) erhält man mit str() und die Zeilenanzahl mit nrow().

Lassen Sie sich Spaltenanzahl und Spaltennamen, Variablentypen und abschliessend die Zeilanzahl anzeigen.

Abschliessend gibt die Funktion apply() - wir behandeln Funktionen zum Programmieren aufgrund ihrer Komplexität in einer späteren Sitzung - an, ob es in einer Spalte Fehlwerte gibt.

# library(tidyverse)
# 1. Importiere die Daten in einen Data Frame
# cts <- read.table("CafeTransactionStore.csv", header = TRUE, sep = ",")
# is.data.frame(cts)

# 2.  
  
# 3.  
  
# 4. Prüfe Missing Values  
apply(cts, 2, function(x) any(is.na(x)))
# 2. Prüfe Spalten- und Zeilenanzahl und die Spaltennamen
ncol(cts)
nrow(cts)
colnames(cts)

# 3. Prüfe die Datenstruktur
str(cts)

# 4. Prüfe Missing Values
apply(cts, 2, function(x) any(is.na(x)))
  • Speichern Sie das ‘Skript’ für das Einlesen der Daten, und zwar direkt in Ihrem Projekt-Ordner.

  • Wir werden den Code im Skript nun laufend erneuern.

Bearbeiten von Datentabellen I

Sie wissen bereits, wie man Datentabellen händisch oder durch Datenimport erstellt und auf Elemente zugreift bzw. Inhalte abruft oder verändert.

Wir besprechen nun die wichtigsten Möglichkeiten, die man zur Bearbeitung und Änderung von Datentabellen braucht.


Installation des dplyr package

Mithilfe der Funktionen des dplyr-package in RStudio bearbeiten wir Datentabellen.

Wir installieren das package und laden die Bibliothek.

    install.packages('dplyr')  
    library(dplyr)

Weitere Informationen zum dplyr - package finden Sie unter: https://dplyr.tidyverse.org/

Dort können Sie auch das entsprechende cheat sheet herunterladen:

https://raw.githubusercontent.com/rstudio/cheatsheets/main/data-transformation.pdf


Funktionen für die Arbeit mit Datentabellen

1. mutate() - hinzufügen/verändern von Spalten in Datentabellen

  • Mit der Funktion mutate() können Sie Datentabellen verändern, indem Sie eine neue Spalte hinzufügen oder eine bestehende Spalte ändern.

  • An erster Stelle nach mutate() steht dabei der Datensatz. Dieser wird automatisch von R erkannt, gegeben dass er vorab in R importiert worden ist. Dasselbe gilt für die Variablen - hier: price und quantity. Normalerweise müsste man diese nach dem laden des Data Frames mit cts$price bzw. cts$quantity ansprechen. In den Funktionen des dyplr package ist dies nicht notwendig, was die Bedienung vereinfacht.

    Beispiel:

     cts <- read.table("CafeTransactionStore.csv", header = TRUE, sep = ",", stringsAsFactors = TRUE)  
     head(cts)
     cts <- mutate(cts, revenue = price * quantity)
     cts  
    ## 'data.frame':    5404 obs. of  6 variables:
    ##  $ calendar_date: Factor w/ 1348 levels "01/01/12","01/01/13",..: 1 1 1 1 5 5 5 5 9 9 ...
    ##  $ price        : num  15.5 12.7 12.8 12.6 15.5 ...
    ##  $ quantity     : int  46 22 18 30 70 22 16 34 62 26 ...
    ##  $ sell_id      : int  1070 2051 2052 2053 1070 2051 2052 2053 1070 2051 ...
    ##  $ sell_category: int  0 2 2 2 0 2 2 2 0 2 ...
    ##  $ revenue      : num  713 280 230 378 1085 ...


2. filter() - Auswahl bestimmter Zeilen innerhalb der Datentabelle(n)

  • Mit der Funktion filter() können Sie Datentabellen bearbeiten, indem Sie nur bestimmte Zeilen mit bestimmten Attributen auswählen bzw. nach diesen filtern. Die Abfolge der Eingabe - erst Datensatz, dann Variable(n) - und das Unterlassen des $-Zeichens gilt hier gleich der mutate-Funktion. Prüfen können Sie das Ergebnis des Filterns bspw. mit der Funktion “max()”.

    Beispiel:

     cts_m <- mutate(cts, revenue = price * quantity)
     head(cts_m)
     cts_f <- filter(cts_m, revenue <= 1000)
     max(cts_f$revenue)
     head(cts_f)
    ## [1] 992


3. select() - Auswahl bestimmter Spalten innerhalb der Datentabelle(n)

  • Mit der Funktion select() können Sie Datentabellen bearbeiten, indem Sie nur bestimmte Zeilen mit bestimmten Attributen auswählen bzw. nach diesen filtern. Prüfen können Sie Ihr Ergebnis bspw. mit der Funktion str().

    Beispiel:

     head(cts)
     cts_s <- select(cts, price, quantity)  
    ## 'data.frame':    5404 obs. of  2 variables:
    ##  $ price   : num  15.5 12.7 12.8 12.6 15.5 ...
    ##  $ quantity: int  46 22 18 30 70 22 16 34 62 26 ...


4. “pipe-operator”: %>% ODER |> Der “pipe-operator” dient zur Verknüpfung einer Reihe von Operationen

  • Mit dem %>% (Pipe-Operator) können Sie Datentabellen bearbeiten, indem Sie die Ergebnisse einer Funktion mit dem Pipe-Operator (%>%) an eine andere Funktion senden. Der Pipe Operator kann aktuell auch in der Form |> verwendet werden, was jedoch bei einigen packages noch zu Fehlermeldungen führen kann.

    Beispiel:

     head(cts)  
     cts_fin <- cts %>% 
     mutate(revenue = price * quantity) %>% 
     filter(revenue <= 1000) %>% 
     select(price, quantity, revenue)  
    
    
     max(cts_fin$revenue)
     str(cts_fin)
     head(cts_fin)
    ## [1] 992
    ## 'data.frame':    4434 obs. of  3 variables:
    ##  $ price   : num  15.5 12.7 12.8 12.6 12.7 ...
    ##  $ quantity: int  46 22 18 30 22 16 34 62 26 12 ...
    ##  $ revenue : num  713 280 230 378 280 ...


5. pull() - äquivalent zu “$”: Zugriff auf Spalten bei Pipe-Operationen

  • Mit der pull() Funktion kann man bei der Verwendung von Pipes auf in Daten gespeicherte Werte zugreifen: Wenn ein Datenobjekt über eine Pipeline geleitet wird, kann auf dieses Objekt und seine Spalten mit der pull()-Funktion zugegriffen werden. Danach können Sie Funktionen, bspw. die sum() Funktion, darauf anwenden.

    Beispiel:

    head(cts)  
    cts %>% pull(quantity) %>% sum()
    ## [1] 239588

Übung I

Ab jetzt werden Sie in den Übungsteilen, gegebenenfalls mit Unterstützung durch die Dozierenden, die neuen Inhalte selbst an den Übungsdaten ausprobieren. Dabei gehen Sie Schritt für Schritt durch die interaktiven Teile und vervollständigen dann jeweils den Code bzw. die Syntax bei sich lokal auf Ihrem Rechner.

Am Ende der Übung werden die Dozierenden mit Ihnen die Lösungen besprechen.


Nutzen Sie Ihr lokales R-Skript “02_Datenimport.R” und vervollständigen Sie es Schrittweise nach jeder Übungsaufgabe.


1

Fuegen Sie mit dem pipe operator %>% eine neue Spalte “revenue” zum Datensatz “cts” hinzu, die den Umsatz pro Transaktion enthaelt.
Pruefen Sie das Ergebnis mit head().

#cts %>% mutate()
cts %>% mutate(revenue = price * quantity) %>% head()


2

Fügen Sie in der obigen Syntax noch eine weitere Spalte “rel_revenue” zum Datensatz “cts” hinzu, die den Umsatz einer Transaktion ins Verhältnis zum höchsten Umsatz bei einer Transaktion in der Variable “revenue” stellt.
Den höchsten Umsatz erhalten Sie mit der Funktion max().
Berechnen Sie die Variable “rel_revenue” in Prozent und runden Sie auf 2 Nachkommastellen (round()).
Prüfen Sie das Ergebnis mit head().

cts %>% 
  mutate(revenue = price * quantity, rel_revenue = round(revenue/(max(revenue))*100, 2)) %>% 
  head()


3

Lassen Sie sich nun mit %>%, filter() und select() die Variablen rel_revenue, price, quantity und die sell_id relativer Umsätze >= 99 Prozent anzeigen.

Beantworten Sie in einem 2ten Schritt folgende Frage: Wie viele Produkte wurde bei Transaktionen mit relativem Umsatz >=99 Prozent insgesamt verkauft? (pull())(sum())

#cts %>% mutate(revenue = price * quantity, rel_revenue = round(revenue/(max(revenue))*100, 2)) %>% filter()..
cts %>% 
  mutate(revenue = price * quantity, rel_revenue = round(revenue/(max(revenue))*100, 2)) %>% 
  filter(rel_revenue >= 99) %>% 
  select(rel_revenue, price, quantity, sell_id)

cts %>% 
  mutate(revenue = price * quantity, rel_revenue = round(revenue/(max(revenue))*100, 2)) %>% 
  filter(rel_revenue >= 99) %>% 
  select(rel_revenue, price, quantity, sell_id) %>% 
  pull(quantity) %>% 
  sum()


4

Wählen Sie nun mit dem “Pipe Operator” und filter() nur die folgenden Menüverkäufe aus (sell_id: 2052 (BURGER & LEMONADE) und 2053 (BURGER, COKE & COFFEE)).

Bei wie vielen Transaktionen wurden solche Verkäufe getätigt?

#cts %>% mutate(revenue = price * quantity, rel_revenue = round(revenue/(max(revenue))*100, 2)) %>% filter()..
cts %>% mutate(revenue = price * quantity, rel_revenue = round(revenue/(max(revenue))*100, 2)) %>% 
  filter(sell_id == c(2052, 2053)) %>% 
  nrow()


5

Wählen Sie erneut mit dem “Pipe Operator” nur die folgenden Menüverkäufe aus (sell_id: 2052 (BURGER & LEMONADE) und 2053 (BURGER, COKE & COFFEE)).
Was war der mittlere Umsatz, den man mit diesen Produkten erwirtschaftet hat? (mean()) Lassen sie sich den ganzzahligen Wert ausgeben (round()).

#cts %>% mutate(revenue = price * quantity, rel_revenue = round(revenue/(max(revenue))*100, 2)) %>% filter()..
cts %>% mutate(revenue = price * quantity, rel_revenue = round(revenue/(max(revenue))*100, 2)) %>% 
  filter(sell_id == c(2052, 2053)) %>% 
  pull(revenue) %>% 
  mean() %>% 
  round()

6

Wählen Sie erneut mit dem “Pipe Operator” nur die folgenden Menüverkäufe aus (sell_id: 2052 (BURGER & LEMONADE) und 2053 (BURGER, COKE & COFFEE)).

Bei wie vielen Transaktionen, bei denen solche Verkäufe getätigt wurden, wurden Umsätze von unter 100$ oder mind. 755$ erwirtschaftet?

#cts %>% mutate(revenue = price * quantity, rel_revenue = round(revenue/(max(revenue))*100, 2)) %>% filter()..
cts %>% mutate(revenue = price * quantity, rel_revenue = round(revenue/(max(revenue))*100, 2)) %>% 
  filter(sell_id == c(2052, 2053) & (revenue<100 | revenue>=755)) %>% 
  nrow()


Laden Sie nun das aktualisierte R-Skript herunter und speichern Sie es lokal in Ihrem Projektordner.

Bearbeiten von Datentabellen II

Funktionen für die Arbeit mit Datentabellen

6. arrange() - sortieren von bzw. innerhalb von Datentabellen

  • Äquivalent zu den Funktionen order() oder sort() für Vektoren wird die Funktion arrange() benutzt, um ganze Datentabellen nach einer oder mehreren Spalten zu sortieren.

  • Als Grundeinstellung wird aufsteigend sortiert (ascending). Mit desc (descending) kann man absteigend sortieren.

  • Da bei längeren Datentabellen nur der Überblick über das Ergebnis des Sortierens interessant ist, werden oft nur die ersten Zeilen ausgegeben. Dazu können Sie die Funktion head() verwenden, die Sie bereits kennen.

    Beispiel:

     cts <- read.table("CafeTransactionStore.csv", header = TRUE, sep = ",", stringsAsFactors = TRUE)  
    
     cts_m <- mutate(cts, revenue = price * quantity)  
    
     head(cts_m)  


    # sortieren der Transaktionen nach Umsatz - Grundeinstellung: aufsteigend

     cts_m %>% arrange(revenue) %>% head()  


    # sortieren der Transaktionen nach Umsatz - absteigend

     cts_m %>% arrange(desc(revenue)) %>% head()  


    # sortieren (absteigend) der Transaktionen nach Umsatz und nach quantity innerhalb des jeweiligen Umsatzes

     cts_m %>% arrange(desc(revenue), desc(quantity)) %>% head(n=20) 



7. summarize() - Zusammenfassen von Daten

  • Mit der Funktion summarize() können Sie Datentabellen bearbeiten, indem Sie bestimmte Spalten in einem Wert zusammenfassen. Häufig handelt es sich dabei um den Mittelwert, den Median oder die Standardabweichung.

    Beispiel:

     cts_m <- mutate(cts, revenue = price * quantity)  
     head(cts_m)


    # Minimum, Median und Maximum der Umsätze für Produkte, die als Menü verkauft wurden.

     x <- cts_m %>% 
     filter(sell_category == "2") %>% 
     summarize(Minimum = min(revenue), 
           Median = median(revenue), 
           Maximum = max(revenue),
           N = length(revenue))
    
     x


    # Zugang zum zusammengefassten Wert erhält man auch mit dem $ - Zeichen

     x$median
     x$maximum

    # Der mittlere Umsatz wurde nicht gebildet, kann aber auch als Einzelwert mit dem $-Zeichen abgefragt werden.

     mean(cts_m$revenue)
    ## [1] 356.44
    ## [1] 1395
    ## [1] 595.6231


    # Minimum, Median und Maximum der Umsätze für Produkte, die als Menü verkauft wurden.
    Dies kann auch mit der Funktion “quantile(c(0, 0.5, 1))” erreicht werden.

     x <- cts_m %>% 
     filter(sell_category == "2") %>% 
     pull(revenue) %>% 
     quantile(c(0, 0.5, 1))
    
     x
    ##      0%     50%    100% 
    ##   98.08  356.44 1395.00


8. group_by() - Aufteilung der Daten nach Gruppen

  • Mit der Funktion group_by() können Sie Datentabellen bearbeiten, indem Sie nach bestimmten Attributen Gruppen bilden. Häufig gruppiert man, um eine spezifische Zusammenfassung bestimmter Spalten bzw. Variablen (bspw. Mittelwert, Median, Summe etc.) miteinander vergleichen zu können.

    Beispiel:

     cts_m <- mutate(cts, revenue = price * quantity)
     head(cts_m)


     x <- cts_m %>% 
     group_by(sell_category) %>% 
     summarize(minimum = min(revenue), 
             median = median(revenue), 
             maximum = max(revenue))
     x


Übung II

Nutzen Sie Ihr lokales R-Skript “02_Datawrangling_1.R” und vervollständigen Sie es Schrittweise nach jeder Übungsaufgabe.

Am Ende der Übung werden die Dozierenden mit Ihnen die Lösungen besprechen.


1

Erstellen Sie eine neue Spalte “revenue”, die den Umsatz pro Transaktion enthält.
Wählen sie nun nur bestimmte Güter aus, die verkauft wurden: sell_id = 1070 (Burger als Einzelgut verkauft) und sell_id = 2051 (Verkauf Burger und Coke als Menü). Nutzen Sie %>% um die Funktionen zu verbinden. Geben Sie abschliessend die Kopfzeile aus.

#cts %>% mutate()
cts %>% mutate(revenue = price * quantity) %>% filter(sell_id == c(1070, 2051)) %>% head()


2

Treffen Sie die Auswahl wie in der vorhergehenden Aufgabe.
Erstellen Sie 2 Variablen “avg” und “st_dev”, als den Mittelwert (mean())
und die Standardabweichung (sd()) der Variable “price”.
Geben Sie abschliessend nur den gerundeten Wert von “avg” aus (pull()).

#cts %>% mutate(revenue = price * quantity) %>% filter(sell_id == c(1070, 2051))
#cts %>% mutate(revenue = price * quantity) %>% filter(sell_id == c(1070, 2051))
cts %>% mutate(revenue = price * quantity) %>% filter(sell_id == c(1070, 2051)) %>% 
  summarise(avg = mean(price), st_dev = sd(price)) %>% pull(avg) %>% round()


3

Treffen Sie die Auswahl wie in der vorhergehenden Aufgabe. Erstellen Sie für die darin getroffene Auswahl nun zustätzlich das Miminum (min()) und das Maximum (max()) der Variable “price”.
Geben Sie abschliessend den Wert von “max_p” aus (pull()).

#cts %>% mutate(revenue = price * quantity) %>% filter()
#cts %>% mutate(revenue = price * quantity) %>% filter(sell_id == c(1070, 2051))
#cts %>% mutate(revenue = price * quantity) %>% filter(sell_id == c(1070, 2051)) %>% 
#  summarise(avg = mean(price), st_dev = sd(price))
cts %>% mutate(revenue = price * quantity) %>% filter(sell_id == c(1070, 2051)) %>% 
  summarise(avg = mean(price), st_dev = sd(price), min_p = min(price), max_p = max(price)) %>% pull(max_p)


4

Benutzen Sie den df “cts” und den pipe operator “%>%”, die Funktion filter(), group_by() und summarize() um Mittelwert und Standardabweichung von “price” nur für “Menueverkäufe” (filter(sell_category == 2)) und dabei für nur für die Option “Kombiprodukte: Coke mit Burger” (sell_id==2051) zu berechnen.
Speichern Sie Mittelwert und Standardabweichung als neue Variablen “avg” und “st_dev”.
Geben Sie anschliessend den auf 2 Nachkommastellen gerundeten Wert der Standardabweichung für die sell_id “2051” aus (round(.,2).

#cts %>% filter(sell_category == 2) %>%
cts %>% filter(sell_category == 2) %>% group_by(sell_id) %>% 
      summarise(avg = mean(price), st_dev = sd(price))
cts %>% filter(sell_category == 2) %>% group_by(sell_id) %>% 
  summarise(avg = mean(price), st_dev = sd(price)) %>% filter(sell_id == 2051) %>% pull(st_dev) %>% round(.,2)


5

Benutzen Sie den df “cts” und den “pipe-operator” %>% ,die Funktion filter(), group_by() und summarize um Mittelwert und Standardabweichung von “price” nur für “Einzelverkäufe” (sell_category == 0) und dabei gruppiert nach den verschiedenen “Produkten” (sell_ids) separat zu berechnen.
Speichern Sie Mittelwert und Standardabweichung als neue Variablen “avg” und “st_dev”.
Geben Sie anschliessend den auf 1 Nachkommastelle gerundeten Wert des Mittelwerts für die sell_id “1070” aus.

#cts %>% filter(sell_category == 0) %>%
cts %>% filter(sell_category == 0) %>% group_by(sell_id) %>% 
      summarise(avg = mean(price), st_dev = sd(price))
cts %>% filter(sell_category == 0) %>% group_by(sell_id) %>% 
  summarise(avg = mean(price), st_dev = sd(price)) %>% filter(sell_id == 1070) %>% pull(avg) %>% round(.,1)


6

Erstellen sie nun eine Tabelle, die Mittelwert und Standardabweichung des Preises für die Einzel- & Menüprodukte
und die jeweiligen Produkte enthält. Nutzen Sie dafür die Funktion “group_by()”.
Geben Sie abschliessend den auf 2 Nachkommastellen gerundeten Mittelwert für die sell_id: “2052” aus.

#cts %>% group_by()
cts %>% group_by(sell_category, sell_id) %>% 
      summarise(avg = mean(price), st_dev = sd(price))
cts %>% group_by(sell_category, sell_id) %>% 
      summarise(avg = mean(price), st_dev = sd(price)) %>% filter(sell_id == 2052) %>% pull(avg) %>% round(.,2)


7

Erstellen sie erneut eine Tabelle, die Mittelwert und Standardabweichung des Preises enthält - diesmal nur für die jeweiligen Produkte (sell_id).
Nutzen Sie dafür die Funktion “group_by()”.
Geben Sie die Tabelle aus.
Erstellen Sie die Tabelle erneut. Ordnen Sie die Tabelle nun aber aufsteigend nach dem Mittelwert.

#cts %>% group_by()
cts %>% group_by(sell_id) %>% 
  summarise(avg = mean(price), st_dev = sd(price))
cts %>% group_by(sell_id) %>% 
  summarise(avg = mean(price), st_dev = sd(price)) %>% arrange(avg)


Laden Sie nun das aktualisierte R-Skript herunter und speichern Sie es lokal in Ihrem Projektordner.


Was haben wir gelernt:

Wir können verschiedene Datenformate als Data Frame in R importieren oder einen Data Frame eigenständig generieren.

Wir können mit Vektoren (inkl. Faktoren) umgehen und diese bearbeiten.

Wir können Datentabellen in Form eines Data Frame mit den Funktionen des package dplyr bearbeiten, indem wir bspw. neue Spalten hinzufügen oder bestehende verändern.

Wir können Informationen aus Datentabellen extrahieren und in Form der gängigen Lage- und Streuungsmasse (Mittelwert, Median, Standardabweichung, Maximum, Minimum) zusammenfassen.


Homework

Laden Sie das R-Skript herunter und folgen Sie den dort angegebenen Arbeitsschritten.

Data Science für ManagerInnen