De CDNOW-dataset importeren

We importeren de CDNOW dataset. Als de dataset is gedownload, kunnen we de Import Dataset knop van RStudio gebruiken.

Import CDNOW

Merk op dat de dataset geen kolomnamen heeft. In dit geval kiezen we daarom voor No bij Headings. De kolomnamen moet we later dus handmatig toevoegen. De volgende code wordt door het importeren automatisch door RStudio gegenereerd.

De CDNOW dataset is nu een data frame in R. Het is een slim idee om deze dataset te kopiëren door een nieuw object te maken met dezelfde dataset. Hierdoor hebben we altijd nog de originele dataset voor het geval we het verpesten tijdens onze analyse. We noemen het object waar we mee verder gaan werken CDNOW.df.

CDNOW.df <- CDNOW

De eigenschappen van de dataset bekijken

Als volgende stap bekijken we de eigenschappen van de dataset zodat we weten met welke datatypes we te maken hebben. Hiervoor kunnen we de str() functie gebruiken.

# de str() functie gebruiken om de structuur van de dataset te bekijken
str(CDNOW.df)
## 'data.frame':    69659 obs. of  4 variables:
##  $ V1: int  1 2 2 3 3 3 3 3 3 4 ...
##  $ V2: int  19970101 19970112 19970112 19970102 19970330 19970402 19971115 19971125 19980528 19970101 ...
##  $ V3: int  1 1 5 2 2 2 5 4 1 2 ...
##  $ V4: num  11.8 12 77 20.8 20.8 ...

We zien dat de dataset bestaat uit 69659 rijen (observaties/transacties) en 4 variabelen (kolommen). Daarvan zijn alle variabelen integer (hele getallen) en numeric (getallen met decimalen).

De dataset de juiste vorm geven

Er is dus werk aan de winkel. Als eerst geven kolomnamen aan de dataset converteren we de kolom met de datum (Datum) naar het Date datatype.

Kolomnamen geven aan de kolomnaam-loze dataset

Met de names() functie kunnen we namen geven aan de CDNOW.df data frame.

# namen toevoegen aan de CDNOW-dataset
names(CDNOW.df) <- c("Klant", "Datum", "Aantal", "Bedrag")

# opnieuw de dataset bekijken
str(CDNOW.df)
## 'data.frame':    69659 obs. of  4 variables:
##  $ Klant : int  1 2 2 3 3 3 3 3 3 4 ...
##  $ Datum : int  19970101 19970112 19970112 19970102 19970330 19970402 19971115 19971125 19980528 19970101 ...
##  $ Aantal: int  1 1 5 2 2 2 5 4 1 2 ...
##  $ Bedrag: num  11.8 12 77 20.8 20.8 ...

Een kolom converteren naar het date (datum) datatype

Met de as.Date functie kunnen we een waarde omzetten naar het date datatype. Hiervoor moeten met twee dingen rekening houden:

  • De as.Date functie accepteert een character datatype;

  • We moeten de structuur van de waarde aangeven die als datum geconverteerd moet worden.

Dit doen we op de volgende manier:

# om eerst proef te draaien, dus te voorkomen dat we onze goeie kolommen
# overschrijven

x <- as.Date(as.character(CDNOW.df$Datum), '%Y%m%d')
head(x)
## [1] "1997-01-01" "1997-01-12" "1997-01-12" "1997-01-02" "1997-03-30"
## [6] "1997-04-02"
class(x)
## [1] "Date"

We hebben het gewenste resultaat, we kunnen de kolom Datum uit de CDNOW.df data frame overschrijven met onze nieuwe kolom:

CDNOW.df$Datum <- as.Date(as.character(CDNOW.df$Datum), '%Y%m%d')

Gebruik maken van het Date datatype

Het Date datatype is anders dan het character datatype, al lijkt deze er erg veel op. Met het Date datatype kun je namelijk informatie halen uit de datum, en deze datum bewerken. Aan de hand van een aantal voorbeelden wordt dit gedemonstreerd.

Deze demonstratie past eigenlijk niet helemaal bij een case, maar ook in een echte situatie dwaal je af en toe af door met de functionaliteit te spelen.

# de head functie wordt gebruikt om steeds slechts een kleine sample 
#van de data uit de variabele te laten zien

head(CDNOW.df$Datum)
## [1] "1997-01-01" "1997-01-12" "1997-01-12" "1997-01-02" "1997-03-30"
## [6] "1997-04-02"
head(CDNOW.df$Datum) + 31
## [1] "1997-02-01" "1997-02-12" "1997-02-12" "1997-02-02" "1997-04-30"
## [6] "1997-05-03"
head(CDNOW.df$Datum) + 31
## [1] "1997-02-01" "1997-02-12" "1997-02-12" "1997-02-02" "1997-04-30"
## [6] "1997-05-03"
head(months(CDNOW.df$Datum))
## [1] "januari" "januari" "januari" "januari" "maart"   "april"
head(weekdays(CDNOW.df$Datum))
## [1] "woensdag"  "zondag"    "zondag"    "donderdag" "zondag"    "woensdag"
head(quarters((CDNOW.df$Datum)))
## [1] "Q1" "Q1" "Q1" "Q1" "Q1" "Q2"
head(as.numeric(format(CDNOW.df$Datum,'%Y')))
## [1] 1997 1997 1997 1997 1997 1997
(CDNOW.df$Datum[6] - CDNOW.df$Datum[1])
## Time difference of 91 days

Je kunt zien dat het in R mogelijk is om berekeningen te maken met datums.

Spelenderwijs de data verkennen

Om wat meer gevoel te krijgen met de data, is het goed om een aantal functies uit te proberen om de data te verkennen. Doe dit vooral op een manier die jou het beste lijkt. Hier volgen een aantal suggesties:

# de dataset

attach(CDNOW.df)
## The following objects are masked from CDNOW.df (pos = 7):
## 
##     Aantal, Bedrag, Datum, Klant
summary(CDNOW.df)
##      Klant           Datum                Aantal          Bedrag       
##  Min.   :    1   Min.   :1997-01-01   Min.   : 1.00   Min.   :   0.00  
##  1st Qu.: 5506   1st Qu.:1997-02-22   1st Qu.: 1.00   1st Qu.:  14.49  
##  Median :11410   Median :1997-04-24   Median : 2.00   Median :  25.98  
##  Mean   :11471   Mean   :1997-07-02   Mean   : 2.41   Mean   :  35.89  
##  3rd Qu.:17273   3rd Qu.:1997-11-07   3rd Qu.: 3.00   3rd Qu.:  43.70  
##  Max.   :23570   Max.   :1998-06-30   Max.   :99.00   Max.   :1286.01
# aantallen

mean(Aantal)
## [1] 2.41004
boxplot(Aantal)

plot of chunk unnamed-chunk-8

table(Aantal)
## Aantal
##     1     2     3     4     5     6     7     8     9    10    11    12 
## 31454 16070  9444  5015  2792  1627  1057   684   403   293   180   136 
##    13    14    15    16    17    18    19    20    21    22    23    24 
##   108    70    59    39    34    48    26    22    12    15     8     8 
##    25    26    27    28    29    30    32    34    36    37    38    39 
##     9     7     6     3     2     3     3     1     1     3     3     3 
##    40    41    42    43    47    56    63    70    99 
##     2     1     1     1     1     2     1     1     1
hist(Aantal, breaks = length(unique(Aantal)))

plot of chunk unnamed-chunk-8

plot(Aantal,Bedrag)

plot of chunk unnamed-chunk-8

# bedragen

sum(Bedrag)
## [1] 2500316
hist(Bedrag, breaks = length(unique(Bedrag)))

plot of chunk unnamed-chunk-8

boxplot(Bedrag)

plot of chunk unnamed-chunk-8

plot(density(Bedrag))

plot of chunk unnamed-chunk-8

# datums

CDNOW.df$Maand  <- months(Datum)
CDNOW.df$Kwartaal <- quarters(CDNOW.df$Datum)

detach(CDNOW.df)
attach(CDNOW.df)
## The following object is masked from Projecten2 (pos = 5):
## 
##     Maand
## The following objects are masked from CDNOW.df (pos = 7):
## 
##     Aantal, Bedrag, Datum, Klant, Kwartaal, Maand
## The following object is masked from Projecten2 (pos = 9):
## 
##     Maand
by(CDNOW.df[, 3:4], Maand, colMeans)
## Maand: april
##    Aantal    Bedrag 
##  2.549214 36.942218 
## -------------------------------------------------------- 
## Maand: augustus
##    Aantal    Bedrag 
##  2.521983 38.089522 
## -------------------------------------------------------- 
## Maand: december
##    Aantal    Bedrag 
##  2.563099 38.169868 
## -------------------------------------------------------- 
## Maand: februari
##    Aantal    Bedrag 
##  2.275605 34.342532 
## -------------------------------------------------------- 
## Maand: januari
##    Aantal    Bedrag 
##  2.253102 34.289868 
## -------------------------------------------------------- 
## Maand: juli
##    Aantal    Bedrag 
##  2.763766 41.495201 
## -------------------------------------------------------- 
## Maand: juni
##    Aantal    Bedrag 
##  2.469688 36.198778 
## -------------------------------------------------------- 
## Maand: maart
##    Aantal    Bedrag 
##  2.334098 34.891628 
## -------------------------------------------------------- 
## Maand: mei
##    Aantal    Bedrag 
##  2.495492 36.664541 
## -------------------------------------------------------- 
## Maand: november
##    Aantal    Bedrag 
##  2.840727 41.981324 
## -------------------------------------------------------- 
## Maand: oktober
##    Aantal    Bedrag 
##  2.421155 35.043236 
## -------------------------------------------------------- 
## Maand: september
##    Aantal    Bedrag 
##  2.495209 35.691986
by(CDNOW.df[, 3:4], Kwartaal, colMeans)
## Kwartaal: Q1
##    Aantal    Bedrag 
##  2.291004 34.532054 
## -------------------------------------------------------- 
## Kwartaal: Q2
##    Aantal    Bedrag 
##  2.506523 36.613209 
## -------------------------------------------------------- 
## Kwartaal: Q3
##    Aantal    Bedrag 
##  2.607965 38.686871 
## -------------------------------------------------------- 
## Kwartaal: Q4
##    Aantal    Bedrag 
##  2.614253 38.486024

Data verkennen zonder outliers

In de vorige voorbeelden heb je kunnen zien dat er veel outliers (extreme waarden) in de data zitten. Hierdoor zien de visualisaties er een beetje raar uit. Op verschillende manieren kun met outliers omgaan, bijvoorbeeld door ze weg te laten.

CDNOW.df$outlier <- ifelse(CDNOW.df$Bedrag 
                    > mean(CDNOW.df$Bedrag)+(3*(sd(CDNOW.df$Bedrag))) 
                    | CDNOW.df$Bedrag < mean(CDNOW.df$Bedrag)-(3*(sd(CDNOW.df$Bedrag))),
                    "outlier",
                    "geen_outlier")

CDNOW.df.zo <- subset(CDNOW.df, CDNOW.df$outlier != "outlier")


summary(CDNOW.df.zo)
##      Klant           Datum                Aantal           Bedrag      
##  Min.   :    1   Min.   :1997-01-01   Min.   : 1.000   Min.   :  0.00  
##  1st Qu.: 5497   1st Qu.:1997-02-22   1st Qu.: 1.000   1st Qu.: 14.42  
##  Median :11402   Median :1997-04-23   Median : 2.000   Median : 25.74  
##  Mean   :11465   Mean   :1997-07-02   Mean   : 2.238   Mean   : 32.84  
##  3rd Qu.:17263   3rd Qu.:1997-11-07   3rd Qu.: 3.000   3rd Qu.: 42.50  
##  Max.   :23570   Max.   :1998-06-30   Max.   :18.000   Max.   :144.72  
##     Maand             Kwartaal           outlier         
##  Length:68493       Length:68493       Length:68493      
##  Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character  
##                                                          
##                                                          
##
# aantallen

mean(CDNOW.df.zo$Aantal)
## [1] 2.23782
boxplot(CDNOW.df.zo$Aantal)

plot of chunk unnamed-chunk-9

table(CDNOW.df.zo$Aantal)
## 
##     1     2     3     4     5     6     7     8     9    10    11    12 
## 31422 16047  9419  4989  2761  1586  1016   627   337   187    60    27 
##    13    14    15    16    18 
##     8     3     2     1     1
hist(CDNOW.df.zo$Aantal, breaks = length(unique(Aantal)))

plot of chunk unnamed-chunk-9

plot(CDNOW.df.zo$Aantal,CDNOW.df.zo$Bedrag)

plot of chunk unnamed-chunk-9

# bedragen

sum(CDNOW.df.zo$Bedrag)
## [1] 2249614
hist(CDNOW.df.zo$Bedrag, breaks = length(unique(CDNOW.df.zo$Bedrag)))

plot of chunk unnamed-chunk-9

boxplot(CDNOW.df.zo$Bedrag)

plot of chunk unnamed-chunk-9

hist(CDNOW.df.zo$Bedrag, breaks = length(unique(CDNOW.df.zo$Bedrag)))

plot of chunk unnamed-chunk-9

plot(density(CDNOW.df.zo$Bedrag))

plot of chunk unnamed-chunk-9

Totale uitgave per klant berekenen

De dataset bestaat uit aparte transacties. Hierbij dus ook voor dezelfde klant op verschillende koopmomenten. Als we de totale klantwaarde willen weten, moeten we per Klant alle Bedrag-waarden bij elkaar optellen. Dit doen we als volgt.

# een object aanmaken "TKB" dat staat voor "Totaal Klant Bedrag"
TKB <- aggregate(CDNOW.df$Bedrag ~ CDNOW.df$Klant, CDNOW.df, sum)

# checken hoe de waarden er uit zien
head(TKB)
##   CDNOW.df$Klant CDNOW.df$Bedrag
## 1              1           11.77
## 2              2           89.00
## 3              3          156.46
## 4              4          100.50
## 5              5          385.61
## 6              6           20.99

We hebben nu dus berekend welk totaalbedrag iedere klant heeft besteed.

Klanten Segmenteren

We willen klantgroepen segmenteren op basis van het totale bedrag dat ze hebben uitgegeven. Als we een samenvatting geven van de variabele die we aangemaakt hebben met de totale klantwaarden, zien we de algemene statistieken: We veranderen de namen van de variabelen in de dataset TKB:

  • CDNOW.df$Klant wordt TBKant;

  • CDNOW.df$Bedrag wordt TBedrag.

# de namen van TKB veranderen
names(TKB) <- c("TKlant","TBedrag")

We definiëren de klantgroepen Kleine Klanten, Midden Klanten en Grote Klanten op basis van hun waarde. Met behulp van de samenvatting kunnen we een goede groepering maken.

summary(TKB$TBedrag)
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##     0.00    19.97    43.40   106.08   106.47 13990.93
boxplot(TKB$TBedrag, outline = FALSE)

plot of chunk unnamed-chunk-12

hist(TKB$TBedrag, breaks = nrow(TKB))

plot of chunk unnamed-chunk-12

  • Maak een aparte groep met Kleine klanten, klanten die minder dan 43.40 uitgegeven hebben;
  • Midden klanten, tussen de 43.40 en 106.08 hebben uitgegeven;
  • Grote klanten, meer dan 106,08 hebben uitgegeven.
# subsets maken voor de verschillende klantgroepen
KlKl <- subset(TKB, TKB$TBedrag < 43.40)

MiKl <- subset(TKB, TKB$TBedrag >= 43.40 & TKB$TBedrag <= 106.08)

GrKl <- subset(TKB, TKB$TBedrag > 106.08)

Een samenvatting geven van alle klantsegmenten

summary(KlKl)
##      TKlant         TBedrag     
##  Min.   :    1   Min.   : 0.00  
##  1st Qu.: 6188   1st Qu.:13.97  
##  Median :12064   Median :19.97  
##  Mean   :11986   Mean   :22.08  
##  3rd Qu.:17867   3rd Qu.:29.74  
##  Max.   :23569   Max.   :43.38
summary(MiKl)
##      TKlant         TBedrag      
##  Min.   :    2   Min.   : 43.41  
##  1st Qu.: 5786   1st Qu.: 53.30  
##  Median :11718   Median : 65.72  
##  Mean   :11703   Mean   : 68.48  
##  3rd Qu.:17569   3rd Qu.: 82.21  
##  Max.   :23570   Max.   :106.07
summary(GrKl)
##      TKlant         TBedrag       
##  Min.   :    3   Min.   :  106.1  
##  1st Qu.: 5405   1st Qu.:  141.9  
##  Median :11425   Median :  202.9  
##  Mean   :11468   Mean   :  310.8  
##  3rd Qu.:17272   3rd Qu.:  333.0  
##  Max.   :23568   Max.   :13990.9

Klantnummers verzamelen per klantgroep

Om de eigenschappen van de klanten per klantgroep later goed te kunnen bekijken, worden de nummers van de klanten per klantgroep verzameld.

KKN <- KlKl$TKlant
MKN <- MiKl$TKlant
GKN <- GrKl$TKlant

Ten slotte willen we alle data verzamelen per klantgroep. Dus de hele dataset onderverdeeld in 3 groepen.

KKD <- subset(CDNOW.df, CDNOW.df$Klant %in% KKN)
MKD <- subset(CDNOW.df, CDNOW.df$Klant %in% MKN)
GKD <- subset(CDNOW.df, CDNOW.df$Klant %in% GKN)

Informatie uit transactiedata presenteren

We vatten de informatie samen in een nette tabel die qua formaat direct in een rapport past. In de onderstaande demonstratie kun je zien hoeveel vrijheid je hebt in het combineren van functies. Er worden bijvoorbeeld combinaties gebruikt van de paste(), length(), nrow(), round(), en mean() functies.

aantalKlanten <- c(length(KKN), length(MKN), length(GKN))

gemiddeldTransactieBedrag <- c(paste('€ ',
                                     round(mean(KKD$Bedrag), 2)), 
                              paste('€ ', round(mean(MKD$Bedrag),2)) , 
                              paste('€ ', round(mean(GKD$Bedrag),2)))

gemiddeldAantal <- c(round(mean(KKD$Aantal), 1), 
                     round(mean(MKD$Aantal), 1), 
                     round(mean(GKD$Aantal),1 ))

aantalTransacties <- c(nrow(KKD), nrow(MKD), nrow(GKD))

klantgroepen <- c("Kleine klanten", "Midden klanten", "Grote klanten")

TransactieTabel <- data.frame(aantalKlanten, 
                              gemiddeldTransactieBedrag,  
                              gemiddeldAantal, 
                              aantalTransacties, 
                              row.names = klantgroepen)

names(TransactieTabel) <- c("Aantal_klanten", 
                            "Gemiddeld_transactiebedrag", 
                            "Gemiddeld_aantal", 
                            "Aantal_transacties")

TransactieTabel
##                Aantal_klanten Gemiddeld_transactiebedrag Gemiddeld_aantal
## Kleine klanten          11785                   €  18.45              1.3
## Midden klanten           5872                   €  29.36              2.0
## Grote klanten            5913                   €  43.91              2.9
##                Aantal_transacties
## Kleine klanten              14109
## Midden klanten              13697
## Grote klanten               41853

Buiten deze analyse zijn er nog veel meer analyses mogelijk. Denk bijvoorbeeld aan het uitzoeken voor welk bepaald percentage omzet welke klantgroep verantwoordelijk is.

Merk op dat het een vrij ongebalanceerde segmentatie is. Normaal gesproken is de middengroep het grootst en de groep met grote klanten veel kleiner.

Informatie presenteren over de perioden

We sluiten deze case af met een presentatie van de data over perioden. Hiervoor werken we voornamelijk met de Datum kolom.

De totale omzet per dag berekenen

totaleOmzet <- aggregate(CDNOW.df$Bedrag ~ CDNOW.df$Datum, CDNOW.df, sum)
head(totaleOmzet)
##   CDNOW.df$Datum CDNOW.df$Bedrag
## 1     1997-01-01         7515.35
## 2     1997-01-02         8025.95
## 3     1997-01-03         7475.04
## 4     1997-01-04         6722.93
## 5     1997-01-05         9274.80
## 6     1997-01-06         9680.55
names(totaleOmzet) <- c("Datum", "Bedrag")

barplot(totaleOmzet$Bedrag)

plot of chunk unnamed-chunk-18

De totale aantallen per dag

totaalAantal <- aggregate(CDNOW.df$Aantal ~ CDNOW.df$Datum, CDNOW.df, sum)

head(totaalAantal)
##   CDNOW.df$Datum CDNOW.df$Aantal
## 1     1997-01-01             494
## 2     1997-01-02             530
## 3     1997-01-03             495
## 4     1997-01-04             404
## 5     1997-01-05             590
## 6     1997-01-06             620
names(totaalAantal) <- c("Datum", "Aantal")

results matching ""

    No results matching ""