In dit blogartikel gaan we in op hoe je datasets kunt opschonen in R. We gebruiken een dataset met KNMI meetgegevens die je hier kunt downloaden zodat je - als je dat leuk vindt - mee kunt doen.
Dit blog is een onderdeel van een blogserie over R waarin we o.a. ingaan op hoe je R installeert, hoe je in RStudio werkt, data manipuleert met bijvoorbeeld dplyr of data.table, of data visualiseert met ggplot2 in bijvoorbeeld een histogram of boxplot.
We gaan in dit blog in op:
1. Missende waarden
Het komt vaak voor dat een dataset missende waarden bevat.
Je kunt hier bijvoorbeeld als volgt mee omgaan:
- Rijen met missende waarden verwijderen
- Missende waarden vervangen door een andere waarde
In onderstaande cel openen we de KNMI dataset:
library(readxl)
df_knmi <- read_excel("data/knmi_measurements.xlsx", guess_max = 10000)
df_knmi
## # A tibble: 273,954 × 4
## station_id date temperature rainfall
## <dbl> <dbl> <dbl> <dbl>
## 1 260 19010101 -49 NA
## 2 260 19010102 -18 NA
## 3 260 19010103 -26 NA
## 4 260 19010104 -65 NA
## 5 260 19010105 -60 NA
## 6 260 19010106 -100 NA
## 7 260 19010107 -92 NA
## 8 260 19010108 -49 NA
## 9 260 19010109 11 NA
## 10 260 19010110 15 NA
## # ℹ 273,944 more rows
df_knmi$station_id[df_knmi$station_id == 260] <- "peer"
df_knmi
## # A tibble: 273,954 × 4
## station_id date temperature rainfall
## <chr> <dbl> <dbl> <dbl>
## 1 peer 19010101 -49 NA
## 2 peer 19010102 -18 NA
## 3 peer 19010103 -26 NA
## 4 peer 19010104 -65 NA
## 5 peer 19010105 -60 NA
## 6 peer 19010106 -100 NA
## 7 peer 19010107 -92 NA
## 8 peer 19010108 -49 NA
## 9 peer 19010109 11 NA
## 10 peer 19010110 15 NA
## # ℹ 273,944 more rows
- Met de
summary()
functie krijgen we een statistische samenvatting:
summary(df_knmi)
## station_id date temperature rainfall
## Length:273954 Min. :19010101 Min. :-166.00 Min. : -1.00
## Class :character 1st Qu.:19600108 1st Qu.: 54.00 1st Qu.: 0.00
## Mode :character Median :19901002 Median : 100.00 Median : 1.00
## Mean :19805469 Mean : 99.35 Mean : 21.38
## 3rd Qu.:20061015 3rd Qu.: 149.00 3rd Qu.: 24.00
## Max. :20220531 Max. : 309.00 Max. :1423.00
## NA's :72715
- Hierin zien we dat kolom
rainfall
missende waarden (NA's
) bevat.
Aan de slag met Data Governance? Bekijk de website van Data Kitchen
Voorkomendheid van missende waarden
Met de any()
en is.na()
functies kun je gemakkelijk zien of een kolom missende waarden bevat:
any(is.na(df_knmi$rainfall))
## [1] TRUE
Rijen met missende waarden verwijderen
- In de originele dataset bevinden zich het volgende aantal rijen en kolommen:
dim(df_knmi)
## [1] 273954 4
- Met de functie
na.omit()
(omit = weglaten) verwijderen we alle rijen waarin een lege waarde voorkomt:
df_knmi_cleaned <- na.omit(df_knmi)
df_knmi_cleaned
## # A tibble: 201,239 × 4
## station_id date temperature rainfall
## <chr> <dbl> <dbl> <dbl>
## 1 peer 19060101 -32 0
## 2 peer 19060102 -23 0
## 3 peer 19060103 7 0
## 4 peer 19060104 65 36
## 5 peer 19060105 71 134
## 6 peer 19060106 73 136
## 7 peer 19060107 53 32
## 8 peer 19060108 29 104
## 9 peer 19060109 46 29
## 10 peer 19060110 58 1
## # ℹ 201,229 more rows
- We zien dat het aantal rijen is afgenomen.
- We testen nogmaals op missende waarden:
any(is.na(df_knmi_cleaned))
## [1] FALSE
- Er zijn geen missende waarden meer.
Missende waarden vervangen
We gaan missende waarden in kolom temperature
vervangen door de gemiddelde temperatuur van alle overige metingen.
In onderstaande cel doen we het volgende:
- Berekenen de gemiddelde temperatuur in cellen met metingen:
mean_temperature <- mean(df_knmi_cleaned$temperature, na.rm = TRUE)
mean_temperature
## [1] 100.6928
In onderstaande cel doen we het volgende:
- Maken
df_knmi_cleaned
aan, een kopie vandf_knmi
- We maken een selectie van de waarden in kolom temperatuur die missend zijn met functie
is.na()
- Vullen deze waarden met
mean_temperature
- Bekijken of er nu nog missende waarden in de kolom voorkomen
df_knmi_cleaned <- df_knmi
df_knmi_cleaned$temperature[
is.na(df_knmi_cleaned$temperature)
] <- mean_temperature
any(is.na(df_knmi_cleaned$temperature))
## [1] FALSE
- Er zijn geen missende waarden meer in de kolom
2. Aanpassen van een kolomnaam
Met de colnames()
functie kunnen we de namen van kolommen ophalen:
colnames(df_knmi_cleaned)
## [1] "station_id" "date" "temperature" "rainfall"
In onderstaande cel doen we het volgende:
- Maken een kopie
- Gebruiken de
colnames()
functie om een kolom te hernoemen - Ophalen van namen
- Selectie op naam
"date"
- Aanpassen naar
"measurement_date"
- Bekijken het resultaat
df_knmi_rename <- df_knmi
colnames(df_knmi_rename)[colnames(df_knmi_rename) == "date"] <- "measurement_date"
df_knmi_rename
## # A tibble: 273,954 × 4
## station_id measurement_date temperature rainfall
## <chr> <dbl> <dbl> <dbl>
## 1 peer 19010101 -49 NA
## 2 peer 19010102 -18 NA
## 3 peer 19010103 -26 NA
## 4 peer 19010104 -65 NA
## 5 peer 19010105 -60 NA
## 6 peer 19010106 -100 NA
## 7 peer 19010107 -92 NA
## 8 peer 19010108 -49 NA
## 9 peer 19010109 11 NA
## 10 peer 19010110 15 NA
## # ℹ 273,944 more rows
- De naam is aangepast
3. Kolommen aanpassen
Het volgende komt regelmatig voor:
- Waarden in een bestaande kolom aanpassen
- Datatype in een kolom wilt aanpassen
- Een nieuwe kolom toevoegen
Bestaande kolom aanpassen
In de KNMI documentatie lezen we het volgende over kolom temperature
:
Maximum temperatuur (in 0.1 graden Celsius)
Maximum temperature (in 0.1 degrees Celsius)
Om de temperaturen makkelijk te gebruiken moeten we deze dus delen door 10.
Dit doen we in onderstaande cel:
df_knmi$temperature <- df_knmi$temperature / 10
df_knmi
## # A tibble: 273,954 × 4
## station_id date temperature rainfall
## <chr> <dbl> <dbl> <dbl>
## 1 peer 19010101 -4.9 NA
## 2 peer 19010102 -1.8 NA
## 3 peer 19010103 -2.6 NA
## 4 peer 19010104 -6.5 NA
## 5 peer 19010105 -6 NA
## 6 peer 19010106 -10 NA
## 7 peer 19010107 -9.2 NA
## 8 peer 19010108 -4.9 NA
## 9 peer 19010109 1.1 NA
## 10 peer 19010110 1.5 NA
## # ℹ 273,944 more rows
- Je benoemt de te veranderen kolom, en benoemt de aanpassing
Datatype in een kolom aanpassen
We gaan het datatype van kolom date
instellen als datum.
- Bij het uitlezen van een dataset bepaalt R zelf de datatypes van de kolommen.
- Dit gaat niet altijd goed.
library(readxl)
df_knmi <- read_excel("data/knmi_measurements.xlsx", guess_max = 10000)
str(df_knmi)
## tibble [273,954 × 4] (S3: tbl_df/tbl/data.frame)
## $ station_id : num [1:273954] 260 260 260 260 260 260 260 260 260 260 ...
## $ date : num [1:273954] 1.9e+07 1.9e+07 1.9e+07 1.9e+07 1.9e+07 ...
## $ temperature: num [1:273954] -49 -18 -26 -65 -60 -100 -92 -49 11 15 ...
## $ rainfall : num [1:273954] NA NA NA NA NA NA NA NA NA NA ...
- De kolom
date
wordt gezien als getal, niet als datum.
In onderstaande cel doen we het volgende:
- We gebruiken de
as.Date()
functie om een kolom om te zetten naar datatype date. - Daarvoor moet de kolom eerst datatype tekst hebben.
- Hiervoor zetten we de kolom eerst om naar tekst met functie
as.character()
. - Met argument
format
specificeren we het huidige formaat van de datumnotatie. - Dat is hier 19991220 -> YYYYmmdd ->
"%Y%m%d"
- Kijk voor alle opties in de documentatie.
df_knmi$date <- as.Date(as.character(df_knmi$date), format = "%Y%m%d")
str(df_knmi)
## tibble [273,954 × 4] (S3: tbl_df/tbl/data.frame)
## $ station_id : num [1:273954] 260 260 260 260 260 260 260 260 260 260 ...
## $ date : Date[1:273954], format: "1901-01-01" "1901-01-02" ...
## $ temperature: num [1:273954] -49 -18 -26 -65 -60 -100 -92 -49 11 15 ...
## $ rainfall : num [1:273954] NA NA NA NA NA NA NA NA NA NA ...
- Het datatype van kolom
date
is nuDate
.
Een nieuwe kolom toevoegen
In een R dataframe kun je gemakkelijk een nieuwe kolom toevoegen.
Je doet dit door de naam van de nieuwe kolom te benoemen, en de waarden te specificeren.
We gaan gebaseerd op de kolom date, een kolom met de maand van de datum toevoegen.
In onderstaande cel doen we het volgende:
- Importeren package lubridate: handige functies voor datums en tijd.
- Met functie
month()
vanuit lubridate verkrijgen we de maand van de datum. - De maand bewaren we in een nieuwe kolom die we
"month"
noemen.
library(lubridate)
df_knmi$month <- month(df_knmi$date)
df_knmi
## # A tibble: 273,954 × 5
## station_id date temperature rainfall month
## <dbl> <date> <dbl> <dbl> <dbl>
## 1 260 1901-01-01 -49 NA 1
## 2 260 1901-01-02 -18 NA 1
## 3 260 1901-01-03 -26 NA 1
## 4 260 1901-01-04 -65 NA 1
## 5 260 1901-01-05 -60 NA 1
## 6 260 1901-01-06 -100 NA 1
## 7 260 1901-01-07 -92 NA 1
## 8 260 1901-01-08 -49 NA 1
## 9 260 1901-01-09 11 NA 1
## 10 260 1901-01-10 15 NA 1
## # ℹ 273,944 more rows
- De kolom
"month"
is toegevoegd. - Hetzelfde kunnen we bijvoorbeeld doen voor jaar met functie
year()
:
df_knmi$year <- year(df_knmi$date)
df_knmi
## # A tibble: 273,954 × 6
## station_id date temperature rainfall month year
## <dbl> <date> <dbl> <dbl> <dbl> <dbl>
## 1 260 1901-01-01 -49 NA 1 1901
## 2 260 1901-01-02 -18 NA 1 1901
## 3 260 1901-01-03 -26 NA 1 1901
## 4 260 1901-01-04 -65 NA 1 1901
## 5 260 1901-01-05 -60 NA 1 1901
## 6 260 1901-01-06 -100 NA 1 1901
## 7 260 1901-01-07 -92 NA 1 1901
## 8 260 1901-01-08 -49 NA 1 1901
## 9 260 1901-01-09 11 NA 1 1901
## 10 260 1901-01-10 15 NA 1 1901
## # ℹ 273,944 more rows
summary(df_knmi$year)
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 1901 1960 1990 1980 2006 2022
- De kolom
"year"
is toegevoegd.
Expert worden in R?
Wil jij goed leren werken in R? Tijdens onze Opleiding R leer je alles wat je nodig hebt om zelfstandig analyses uit te voeren in R.
Rik is data scientist en marketeer bij Data Science Partners. Vanuit zijn achtergrond op de Technische Universiteit Eindhoven heeft hij veel affiniteit met data. Na zijn studie heeft hij als consultant altijd met data gewerkt en tevens ervaring opgedaan in het geven van trainingen.