Het cursuspakket

Tijdens onderstaande uitleg wordt gebruikt gemaakt van een aantal databestanden. Download nu het cursuspakket en plaats de data bestanden in de working directory.


Data Cleanup

Deze fase van het stappenplan is bedoeld om om het databestand te voorzien van de correcte labeling en classificatie. Datum en tijden worden getransformeerd naar een vorm die R kan interpreteren en missing values worden correct gelabeld.

Object Names

Names zijn de namen van de variabelen (kolommen) in een data.frame. Het wordt gebruikt ter indexering van het databestand. Daarom is het van belang om alle variabelen te voorzien van een correct label. Lees meer over name index.

## Data importeren ##
# importeer altijd een versie om mee te werken en een versie om mee te vergelijken
olddata <- read.csv("medicijn.csv", header=TRUE, sep=";", dec=",", na.strings = "#LEEG!")
mydata <- read.csv("medicijn.csv", header=TRUE, sep=";", dec=",", na.strings = "#LEEG!")

# Oproepen van de namen van de variabelen
names(mydata)
## [1] "age"         "na"          "k"           "sex"         "bp"         
## [6] "cholesterol" "drug"
## Variabelen hernoemen ##
# Handmatig: 1 per keer
names(mydata)[2] <- "leeftijd"
# interactief
fix(mydata) # veranderingen vinden plaats bij sluiten van het venster
# Hernoem met reshape
library(reshape)
mydata <- rename(mydata, c(sex="geslacht",na="natrium"))
names(mydata)
## [1] "age"         "leeftijd"    "k"           "geslacht"    "bp"         
## [6] "cholesterol" "drug"
#Alles in 1 keer: Dan MOET je ALLE variabelen hernoemen
names(mydata) <- c("age","na","k", "sex", "bp", "chol", "drug") # nu met alle variabelen 
names(mydata)
## [1] "age"  "na"   "k"    "sex"  "bp"   "chol" "drug"

Lees meer over variabelen hernoemen


Object Class

Vaak is het nodig de class van de variabelen te veranderen. Meestal is dat van tekst of numeriek naar factor (van een continue variabele naar een categoriale variabele). Uiteraard is het ook mogelijk om data classes te veranderen van factor naar numeriek of naar character.

Type Conversion

Om object types to converteren zijn de volgende functies beschikbaar:

  • as.numeric()
  • as.factor()
  • as.character()

Lees meer over Type conversion op Quick-R

Factors

Categoriale data heeft in R de object class: factor. Gebruik hiervoor: as.factor() en ordered(). Gebruik levels() om de onderdelen van een factor variabele op te roepen.

# controleer factor variabele levels
sapply(mydata, class)
##       age        na         k       sex        bp      chol      drug 
## "numeric" "numeric" "numeric" "numeric" "numeric" "numeric" "numeric"
## Van numemiric naar categoriaal (nominaal) met as.factor()
# Converteer variabelen
mydata$chol <- as.factor(mydata$chol)
mydata$bp <- as.factor(mydata$bp)
mydata$drug <- as.factor(mydata$drug)

# controleer factor variabele levels
sapply(mydata, class)
##       age        na         k       sex        bp      chol      drug 
## "numeric" "numeric" "numeric" "numeric"  "factor"  "factor"  "factor"

Factor levels aanpassen

Factor levels zijn te veranderen. Hierbij verander je niet alleen het level maar ook de inhoud van elk corresponderende variabele. Gebruik hiervoor de functies uit de plyr package: revalue() en mapvalues().

# eerste 6 waarden van de variabele $sex
head(mydata$sex)
## [1] 1 2 2 1 1 1
## Recoderen van de variabele 
# Tussenstap 1
geslacht <- as.character(mydata$sex)
man <- mydata$sex == 1
vrouw <- mydata$sex == 2

# Tussenstap 2: defineer nieuwe namen
geslacht[man] <- "man"
geslacht[vrouw] <- "vrouw"

# voeg nieuwe namen in bestaande data.frame, vervang huidige variabele $sex
mydata$sex <- geslacht

# controleer nieuwe class
class(mydata$sex)
## [1] "character"
head(mydata$sex)
## [1] "man"   "vrouw" "vrouw" "man"   "man"   "man"
# Maak er nu een factor van en check de class en levels
mydata$sex <- as.factor(mydata$sex)
class(mydata$sex)
## [1] "factor"
levels(mydata$sex)
## [1] "11"    "man"   "vrouw"

Conclusie: er zit een “technische fout” in het databestand. Om dit verhelpen moet je de fout recoderen. Gebruik hiervoor de functie revalue of mapvalue.

## Voorbeeld van recoderen met plyr ##
# Laad de package plyr
library(plyr)

# Eerste 6 rijen van de variabele $bp
head(mydata$bp)
## [1] 1 2 2 3 2 3
## Levels: 1 2 3
# recodeer de variabele $bloeddruk met de functie revalue()
mydata$bp <- revalue(mydata$bp, c("3"="hoog", "2"="normaal", "1"="laag"))
levels(mydata$bp)
## [1] "laag"    "normaal" "hoog"
# recodeer de variabele $drug met de functie mapvalues()
mydata$drug <- mapvalues(mydata$drug, from = c("1", "2", "3", "4", "5"), to = c("drugsA", "drugsB", "drugsC", "drugsX", "drugsY"))
levels(mydata$drug) 
## [1] "drugsA" "drugsB" "drugsC" "drugsX" "drugsY"
# controleer
head(mydata)
##   age   na    k   sex      bp chol   drug
## 1  23 0.79 0.03   man    laag    1 drugsY
## 2  47 0.74 0.06 vrouw normaal    1 drugsC
## 3  47 0.70 0.07 vrouw normaal    1 drugsC
## 4  28 0.56 0.07   man    hoog    1 drugsX
## 5  61 0.56   NA   man normaal    1 drugsY
## 6  22 0.68   NA   man    hoog    1 drugsX

Nominaal naar ordinaal

In het geval de variabele ordinaal is kan dit in R worden gespecificeerd met de functie ordered().

# Maak nieuwe levels op basis van de oude levels
lvl = levels(mydata$bp)
lvl
## [1] "laag"    "normaal" "hoog"
# tussenstap
een <- lvl[1]     
twee <- lvl[2]    
drie <- levels(mydata$bp)[3]    # voorbeeld zonder tussenstap

# zet de nieuwe levels in de nieuwe volgorde, gebruik de c() functie
mydata$bp = ordered(mydata$bp, levels = c(drie, twee, een))            # plaats de levels in een nieuwe volgorde
levels(mydata$bp)
## [1] "hoog"    "normaal" "laag"
# recodeer de variabele $chol zonder tussenstap met de functie mapvalues
levels(mydata$chol)
## [1] "1" "2"
mydata$chol <- ordered(mapvalues(mydata$chol, from = c("1", "2"), to = c("laag", "hoog")), levels = c("laag", "hoog"))
levels(mydata$chol)
## [1] "laag" "hoog"

Lees meer over level manipulatie of leer het automatisch veranderen van alle factor kollomen in een data.frame op R CookBook

Lees meer over labels: Quick-R Value Labels

Lees meer over label transformatie: Cookbook-R Renaming levels


Missing Values

Missing values zijn variabelen waarvoor geen ‘datapunt’ beschikbaar is. In R hebben missing values het class type special character. Voor het werken met missing values zijn een aantal functies beschikbaar, waaronder:

  • na.omit(): verwijder alle NA’s
  • na.fail(): Stop bij NA’s. (handig voor functies)
  • na.omit(): verwijder rijen met NA’s voorgoed.
  • na.exclude(): Negeer rijen met NA’s maar onthoudt de positie: nieuwe vector behoudt lengte oude vector.

Detecteren

Het detecteren van missing values kan op verschillende manieren. Het visualiseren van missing values komt aan bod bij de inferentiële statistiek.

# overzicht met NA's
summary(mydata)
##       age               na               k              sex     
##  Min.   : 15.00   Min.   :0.0100   Min.   :0.00000   11   :  1  
##  1st Qu.: 31.00   1st Qu.:0.5400   1st Qu.:0.03000   man  : 92  
##  Median : 45.00   Median :0.6600   Median :0.05000   vrouw:104  
##  Mean   : 44.76   Mean   :0.6044   Mean   :0.04553   NA's :  3  
##  3rd Qu.: 58.00   3rd Qu.:0.7700   3rd Qu.:0.06000              
##  Max.   :174.00   Max.   :0.9000   Max.   :0.08000              
##  NA's   :2        NA's   :5        NA's   :3                    
##        bp       chol         drug   
##  hoog   :57   laag:102   drugsA:23  
##  normaal:63   hoog: 94   drugsB:16  
##  laag   :76   NA's:  4   drugsC:15  
##  NA's   : 4              drugsX:54  
##                          drugsY:89  
##                          NA's  : 3  
## 
### TIP: CHECK SNEL OF ER NA'S ZIJN:
sapply(mydata, function(x) sum(is.na(x)))
##  age   na    k  sex   bp chol drug 
##    2    5    3    3    4    4    3
# De functie describe() uit de Package 'Hmisc' doet hetzelfde met meer informatie
library(Hmisc)
describe(mydata)
##       vars   n  mean    sd median trimmed   mad   min    max  range  skew
## age      1 198 44.76 18.80  45.00   44.16 20.02 15.00 174.00 159.00  1.58
## na       2 195  0.60  0.24   0.66    0.64  0.18  0.01   0.90   0.89 -1.29
## k        3 197  0.05  0.02   0.05    0.05  0.03  0.00   0.08   0.08 -0.30
## sex*     4 197   NaN    NA     NA     NaN    NA   Inf   -Inf   -Inf    NA
## bp*      5 196   NaN    NA     NA     NaN    NA   Inf   -Inf   -Inf    NA
## chol*    6 196   NaN    NA     NA     NaN    NA   Inf   -Inf   -Inf    NA
## drug*    7 197   NaN    NA     NA     NaN    NA   Inf   -Inf   -Inf    NA
##       kurtosis   se
## age       9.37 1.34
## na        0.69 0.02
## k        -0.81 0.00
## sex*        NA   NA
## bp*         NA   NA
## chol*       NA   NA
## drug*       NA   NA
# Gebruik complete.cases() voor het excluderen van NA's
# gebruik head() om alleen de eerste 6 rijen te geven.
head(complete.cases(mydata))
## [1]  TRUE  TRUE  TRUE  TRUE FALSE FALSE
# TRUE als de rij geen missing values bevat
# FALSE als er ergens in de rij minstens één missing value is

# Gebruik het ! symbool op rijen te geven MET ALLEEN NA'S
head(!complete.cases(mydata))
## [1] FALSE FALSE FALSE FALSE  TRUE  TRUE

Excluderen

Indien je alle missing values wilt excluderen kan dit met de functies complete.cases() en na.omit().

## maak een nieuw databestand zonder NA's:

# De functie na.omit() verwijdert elke rij waarin een NA voorkomt
newdata <- na.omit(mydata)

# complete.cases() geeft een logical vector voor elke rij zonder NA's
newdata <- mydata[!complete.cases(mydata),]
# newdata is een versie van mydata met alleen rijen met NA's

# laat de eerste 6 rijen zien van newdata
head(newdata)
##    age   na    k   sex      bp chol   drug
## 5   61 0.56   NA   man normaal laag drugsY
## 6   22 0.68   NA   man    hoog laag drugsX
## 10  43 0.53 0.03 vrouw    <NA> hoog drugsY
## 12  34 0.67 0.03   man    laag hoog   <NA>
## 16  16 0.83 0.05   man    laag <NA> drugsY
## 17  69 0.85 0.07 vrouw normaal <NA> drugsX

Recoderen

Missing values zijn mogelijk in het ruwe databestand gecodeerd als een getal (bv: 999). Neem bijvoorbeeld de variabele $drug waarvan het getal 5 staat voor “missing value”. Dan is het nodig om dit eerst te recoderen naar een NA.

## Voorbeeld van recoderen met plyr ##
# Laad de package plyr
library(plyr)

# huidige levels van variabele drug
levels(as.factor(mydata$drug))
## [1] "drugsA" "drugsB" "drugsC" "drugsX" "drugsY"
# recodeer het getal 5 in variabele $drug met de functie mapvalue()
drugNA <- mapvalues(mydata$drug, from = c("drugsY"), to = NA )

# Nieuwe levels van variabele drug
levels(as.factor(drugNA))
## [1] "drugsA" "drugsB" "drugsC" "drugsX"

Meer informatie over het recoderen van NA’s komt aan bod bij de data Manipulatie. Het imputeren van NA’s wordt besproken bij de inferentiële statistiek


Error’s

Er zijn twee type outliers: technisch incorrect en statistisch onwaarschijnlijk. De eerste type outlier is bijvoorbeeld een leeftijd van 1900. Dit is hoogstwaarschijnlijk een typefout en er had 19 moeten staan. Dit type outlier is te vinden met de functie which() en any(). Deze is vervolgens te corrigeren met fix() en mapvalues().

# Gebruik any() om te controleren of een bepaalde typefout voorkomt
any(mydata$sex == 11)
## [1] TRUE
# Gebruik which() om de correcte rij te vinden die correspondeert met de typefout
which(mydata$sex == 11)
## [1] 77
# Gebruik fix() om in een apart venster de typefout te vinden en te corrigeren. Het gaat pas in effect bij het sluiten van het venster.

Let op: met fix() kun je je stappen niet reproduceren. het is dus aanbevolen om de correctie met een recode te doen om je stappen te kunnen traceren.

# Gebruik mapvalue() om de typefout te corrigeren
library(plyr)

# huidige levels van variabele $sex
mydata$sex <- as.factor(mydata$sex)
levels(mydata$sex)
## [1] "11"    "man"   "vrouw"
# recodeer het getal 11 naar man
mydata$sex <- mapvalues(mydata$sex, from = c("11"), to = c("man") )
levels(mydata$sex)
## [1] "man"   "vrouw"

De andere type outlier: statistisch onwaarschijnlijk zijn niet bedoeld om te veranderen. Deze worden meegenomen in de analyse en interpretatie ervan.


Opslaan

Aan het eind van de cleanup moet het nieuw dataset worden opgeslagen om vanuit daar verder te werken. Dit kan het beste door een nieuwe databestand (.csv of .sav, etc.) te maken en een bijbehorend data cleanup script.

write.csv

Bij het opslaan als .csv bestand gaat de factor ordering verloren want factor variabelen worden als characters bewaard. Bij het herimporteren van het schone databestand maakt R er automatisch (nominale) factors van maar niet automatisch ordinaal. Maak hiervoor een nieuw en kort datacleanup script.

Voorbeeld opslaan als csv:

# Controleer altijd eerst het nieuwe databestand en vergelijk dit met het oude databestand
head(olddata); head(mydata)
##   age   na    k sex bp cholesterol drug
## 1  23 0.79 0.03   1  1           1    5
## 2  47 0.74 0.06   2  2           1    3
## 3  47 0.70 0.07   2  2           1    3
## 4  28 0.56 0.07   1  3           1    4
## 5  61 0.56   NA   1  2           1    5
## 6  22 0.68   NA   1  3           1    4
##   age   na    k   sex      bp chol   drug
## 1  23 0.79 0.03   man    laag laag drugsY
## 2  47 0.74 0.06 vrouw normaal laag drugsC
## 3  47 0.70 0.07 vrouw normaal laag drugsC
## 4  28 0.56 0.07   man    hoog laag drugsX
## 5  61 0.56   NA   man normaal laag drugsY
## 6  22 0.68   NA   man    hoog laag drugsX
# OPTIONEEL: verwijder alle NA's
mydata_clean <- na.omit(mydata)


# opslaag van het schone databestand in een .csv bestand
write.csv(mydata_clean, "medicijn_schoon.csv", row.names = FALSE)

Bewaren script

Voorbeeld van een kort Data Cleanup script:

## data importeren ##
mydata <- read.csv("medicijn_schoon.csv", header=TRUE)

## Supersnelle Cleanup ##
# check de classes
sapply(mydata, class)

# Order Cholesterol
levels = levels(mydata$chol)
een <- levels[1]; twee <- levels[2]
mydata$chol = ordered(mydata$chol, levels = c(twee, een))

# Order bloeddruk
levels = levels(mydata$bp)
een <- levels[1]; twee <- levels[2]; drie <- levels(mydata$bp)[3]
mydata$bp = ordered(mydata$bp, levels = c(twee, drie, een))

# doe een check
sapply(mydata, class)

Creative Commons-Licentie Dit werk valt onder een Creative Commons Naamsvermelding - Gelijk Delen 3.0 Internationaal-licentie .