De CDNOW-dataset importeren
We importeren de CDNOW
dataset. Als de dataset is gedownload, kunnen we de Import Dataset knop van RStudio gebruiken.
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 eencharacter
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)
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(Aantal,Bedrag)
# bedragen
sum(Bedrag)
## [1] 2500316
hist(Bedrag, breaks = length(unique(Bedrag)))
boxplot(Bedrag)
plot(density(Bedrag))
# 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)
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(CDNOW.df.zo$Aantal,CDNOW.df.zo$Bedrag)
# bedragen
sum(CDNOW.df.zo$Bedrag)
## [1] 2249614
hist(CDNOW.df.zo$Bedrag, breaks = length(unique(CDNOW.df.zo$Bedrag)))
boxplot(CDNOW.df.zo$Bedrag)
hist(CDNOW.df.zo$Bedrag, breaks = length(unique(CDNOW.df.zo$Bedrag)))
plot(density(CDNOW.df.zo$Bedrag))
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
wordtTBKant
;CDNOW.df$Bedrag
wordtTBedrag
.
# 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)
hist(TKB$TBedrag, breaks = nrow(TKB))
- 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)
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")