3  Variabelen maken, samenvatten en hercoderen

In dit hoofdstuk gebruiken we de onderstaande packages en datasets. We zullen de Democracy Cross-national Data van Pippa Noris en de 2019 Canadian Election Study gebruiken. Zorg ervoor dat je deze packages en datasets laadt voordat je aan de slag gaat met de onderstaande voorbeelden:

# Packages laden
library(tidyverse)  # Werken met data
library(rio)        # Data importeren
library(DescTools)  # Gebruiken we om de mediaan te berekenen

# Datasets laden
dta <- import("Democracy Cross-National Data V4.1 09092015.sav") 
canada <- import("2019 Canadian Election Study.rds")

3.1 Variabelen creëren of wijzigen

We kunnen de functie mutate uit package dplyr gebruiken om nieuwe variabelen aan te maken of bestaande variabelen in een dataframe te wijzigen. Het package dplyr wordt geladen als onderdeel van de tidyverse.

We gebruiken als voorbeeld de variabele Pop2006, die de bevolking van landen in 2006 bevat:

head(dta$Pop2006)
[1]          NA  3137503.17 33347948.22    66900.00 16391381.89    83612.15

Als we een variabele willen maken die de bevolking in miljoenen registreert, kunnen we de nieuwe variabele als volgt maken:

dta <- dta |>
  mutate(Pop2006_million = Pop2006 / 1000000)
dta <- dta |>

Dit deel van de code zegt dat we beginnen met het dataframe dta en het resultaat toewijzen aan een dataframe met dezelfde naam. Eigenlijk betekent het: we gaan het dataframe dta veranderen. Als je met je eigen gegevens werkt, zou je dta vervangen door de naam van je eigen dataframe.

Merk op dat we hier de pipe-operator |> gebruiken, wat betekent dat we het oorspronkelijke dataframe nemen en dit gebruiken in de mutate-functie (zie hieronder).

mutate(...)

De mutate-functie creëert een nieuwe variabele of verandert een bestaande. Tussen haakjes geven we aan wat voor soort mutatie we willen.

Pop2006_million

Dit is de naam van de variabele die we aanmaken. Als je niet de naam van een nieuwe variabele schrijft, maar in plaats daarvan de naam van een bestaande variabele gebruikt, zou dit de waarden van die variabele veranderen. Vervang in je eigen gegevens Pop2006_million door de naam van de variabele die je wilt aanmaken.

Pop2006 / 1000000

Zo willen we deze nieuwe variabele maken, in dit geval door de bestaande variabele Pop2006 te delen door één miljoen. Je kunt elke soort functie of operator toepassen, zolang het maar werkt op een vector (in dit geval: een hele kolom van een dataset).

We kunnen de eerste vijf casussen vergelijken om na te gaan of de transformatie heeft gewerkt zoals bedoeld:

dta |>
  select(Pop2006, Pop2006_million) |>   # Selecteer de oorspronkelijke en getransformeerde variabele
  head()                                # Geef de eerste paar rijen weer
      Pop2006 Pop2006_million
1          NA              NA
2  3137503.17      3.13750317
3 33347948.22     33.34794822
4    66900.00      0.06690000
5 16391381.89     16.39138189
6    83612.15      0.08361215

Andere voorbeelden van mutaties zijn:

# Bereken het verschil tussen de bevolking in 2006 en die in 2000
dta <- dta |>
  mutate(Pop2006_difference = Pop2006 - Pop2000)

# Neem de vierkantswortel van de bevolking
dta <- dta |>
  mutate(Pop2006_squared = sqrt(Pop2006))

# Neem het natuurlijke logaritme van de bevolking
dta <- dta |>
  mutate(Pop2006_log = log(Pop2006))  

# Creëer een nieuwe variabele met dezelfde waarde (1) voor alle casussen
dta <- dta |>
  mutate(Country = 1)

Belangrijke dingen over mutate:

  • Gebruik niet de $ operator om variabelen uit een dataframe te selecteren. Gebruik gewoon de naam van de variabele.

  • Vergeet niet het resultaat toe te wijzen, d.w.z. begin de code met dta <- dta |> (waarbij je dta vervangt door de naam van je dataset). Als je het resultaat niet toewijst, zal R het gemuteerde dataframe wel afdrukken, maar niet opslaan.

  • Als je een mutatie toepast op een dataframe en het resultaat toewijst, zal dit geen uitvoer genereren. Als het succesvol werkt, verandert het gewoon het bestaande dataframe of maakt het een nieuw dataframe. Je kunt vervolgens de gegevens inspecteren om te zien of de transformatie heeft gewerkt.

3.2 Gegevens samenvatten

We kunnen gegevens samenvatten met de functie summarise van pacakge dplyr. Package dplyr wordt geladen als onderdeel van de tidyverse.

dta |>
  summarise(mean_population = mean(Pop2006, na.rm=TRUE))
  mean_population
1        34502734

Dit geeft ons simpelweg de gemiddelde waarde van Pop2006 voor alle landen in de wereld. Het krachtigste gebruik van summarise is in combinatie met group_by. De onderstaande code groepeert bijvoorbeeld landen per continent (DD_un_continent_name) en berekent vervolgens de gemiddelde bevolkingsomvang voor elk continent:

dta |>
  group_by(DD_un_continent_name) |>
  summarise(mean_population = mean(Pop2006, na.rm=TRUE))
# A tibble: 6 × 2
  DD_un_continent_name mean_population
  <chr>                          <dbl>
1 ""                            32600 
2 "Africa"                   17475659.
3 "Americas"                 25412866.
4 "Asia"                     87338061.
5 "Europe"                   17711125.
6 "Oceania"                   2732066.

We kunnen ook groeperen op basis van meer dan één groeperingsvariabele. Hier berekenen we bijvoorbeeld de gemiddelde bevolking voor democratieën (Cheibub2Type = 0) en dictaturen (Cheibub2Type = 1) in elk continent:

dta |>
  group_by(DD_un_continent_name, Cheibub2Type) |>
  summarise(mean_population = mean(Pop2006, na.rm=TRUE))
# A tibble: 15 × 3
# Groups:   DD_un_continent_name [6]
   DD_un_continent_name Cheibub2Type mean_population
   <chr>                       <dbl>           <dbl>
 1 ""                              0            NaN 
 2 ""                             NA          32600 
 3 "Africa"                        0       18924251.
 4 "Africa"                        1       16597725.
 5 "Americas"                      0       26786031.
 6 "Americas"                      1       14770838.
 7 "Asia"                          0      138303981.
 8 "Asia"                          1       63553966.
 9 "Asia"                         NA            NaN 
10 "Europe"                        0       18538856.
11 "Europe"                        1        7226530.
12 "Europe"                       NA            NaN 
13 "Oceania"                       0        3515919.
14 "Oceania"                       1         380506.
15 "Oceania"                      NA            NaN 

U kunt ook meerdere statistieken laten berekenen:

dta |>
  group_by(DD_un_continent_name) |>
  summarise(mean_population = mean(Pop2006, na.rm=TRUE),
            median_poplation = Median(Pop2006, na.rm=TRUE),  # Mediaan van pacakge DescTools
            sd_population = sd(Pop2006, na.rm=TRUE))
# A tibble: 6 × 4
  DD_un_continent_name mean_population median_poplation sd_population
  <chr>                          <dbl>            <dbl>         <dbl>
1 ""                            32600            32600            NA 
2 "Africa"                   17475659.         9244288.     25102665.
3 "Americas"                 25412866.         6016000      59575769.
4 "Asia"                     87338061.        14829470.    253704497.
5 "Europe"                   17711125.         7441475.     28476042.
6 "Oceania"                   2732066.          200462.      5920588.

Als je het resultaat wilt opslaan in een nieuw dataframe in plaats van het te printen, kun je het resultaat toewijzen. Merk op dat er geen uitvoer is van de onderstaande code chunk omdat het resultaat wordt opgeslagen in het dataframe summary_data:

summary_data <- dta |>
  group_by(DD_un_continent_name) |>
  summarise(mean_population = mean(Pop2006, na.rm=TRUE),
            median_poplation = Median(Pop2006, na.rm=TRUE), # Mediaan van pacakge DescTools
            sd_population = sd(Pop2006, na.rm=TRUE))
Opmerking

Het verschil tussen mutate en summarise is dat mutate een nieuwe waarde creëert voor elke casus in de dataset, terwijl summarise de gegevens samenvat per categorie van de groeperingsvariabele.

3.3 Hercodering van variabelen

Hercodering van variabelen betekent dat we de codering van waarden veranderen. Dit geldt vaak voor nominale of ordinale variabelen (factors), bijvoorbeeld wanneer we bepaalde categorieën willen groeperen.

3.3.1 Hercodering van nominale variabelen

We illustreren dit aan de hand van de variabele religion (“Meerderheidsreligie”) die we maken uit Pippa Noris’ Democracy Cross-national Data. Aan het begin van dit hoofdstuk hebben we de dataset al geïmporteerd (dta) en de relevante packages geladen (tidyverse, rio).

Eerst maken we de variabele religion aan met de functie factorize uit rio. Dit creëert een factorversie van de oorspronkelijke (gelabelde numerieke) variabele Fox_emajrel.

dta <- dta |>
  mutate(religion = factorize(Fox_emajrel))

De variabele religion kan de volgende waarden aannemen:

table(dta$religion)

            Catholic   Orthodox Christian Protestant Christian 
                  43                   12                   16 
     Other Christian         Islam, Sunni         Islam, Shi'i 
                   0                   33                    3 
        Islam, Other             Buddhist                Hindu 
                   1                    8                    2 
              Jewish              Animist                Other 
                   1                    4                    5 
     Islam (general)                Mixed  Christian (general) 
                   8                   12                   25 

We zien dat we verschillende grote categorieën hebben en verschillende kleinere categorieën. We zien ook dat verschillende islamitische denominaties en christelijke denominaties zijn opgesplitst. Stel dat wij, met het oog op verdere analyse, de indeling willen vereenvoudigen tot vijf categorieën: Christelijk, Islamitisch, Hindoeïstisch, Boeddhistisch en Overig.

We kunnen de functie recode van dplyr gebruiken om de categorieën te hercoderen. Het package dplyr wordt geladen als onderdeel van de tidyverse.

dta <- dta |>
  mutate(religion_recoded = recode(religion, 
                                   "Animist" = "Other",
                                   "Catholic" = "Christian",
                                   "Islam (general)" = "Islam",
                                   "Islam, Other" = "Islam",
                                   "Islam, Shi'i" = "Islam",
                                   "Islam, Sunni" = "Islam",
                                   "Jewish" = "Other",
                                   "Mixed" = "Other",
                                   "Orthodox Christian" = "Christian",
                                   "Protestant Christian" = "Christian",
                                   "Other Christian" = "Christian",
                                   "Christian (general)" = "Christian"
                                   )
         )
mutate(religion_recoded =

Dit deel van de code geeft aan dat we een nieuwe variabele religion_recoded willen aanmaken. Als je met je eigen gegevens werkt, kies je natuurlijk een passende naam.

recode(religion,

Dit deel van de code geeft aan dat we de bestaande variabele religion willen hercoderen. Als je met je eigen gegevens werkt, geef dan de naam op van de bestaande variabele die je wilt hercoderen.

"Animist" = "Other"

Dit zijn de hercodeerstatements, waarbij we de oude naam links en de nieuwe naam rechts tussen dubbele aanhalingstekens (“) schrijven.

We kunnen zoveel van deze statements opnemen als we willen. Als we een waarde niet opnemen, blijft deze (standaard) ongewijzigd. We nemen bijvoorbeeld geen statement op voor Other, dus deze waarde zal hetzelfde zijn in de gehercodeerde variabele.

De hercodering heeft de gewenste vijf categorieën opgeleverd:

table(dta$religion_recoded)

Christian     Islam  Buddhist     Hindu     Other 
       96        45         8         2        22 

Wij kunnen ook nagaan of de oude waarden correct zijn gehercodeerd in de nieuwe waarden:

table(dta$religion, dta$religion_recoded)
                      
                       Christian Islam Buddhist Hindu Other
  Catholic                    43     0        0     0     0
  Orthodox Christian          12     0        0     0     0
  Protestant Christian        16     0        0     0     0
  Other Christian              0     0        0     0     0
  Islam, Sunni                 0    33        0     0     0
  Islam, Shi'i                 0     3        0     0     0
  Islam, Other                 0     1        0     0     0
  Buddhist                     0     0        8     0     0
  Hindu                        0     0        0     2     0
  Jewish                       0     0        0     0     1
  Animist                      0     0        0     0     4
  Other                        0     0        0     0     5
  Islam (general)              0     8        0     0     0
  Mixed                        0     0        0     0    12
  Christian (general)         25     0        0     0     0

(Zo zijn alle vier de landen met een Animistische meerderheid correct gehercodeerd naar “Other”).

3.3.2 Hercodering van ordinale variabelen

Als je een ordinale variabele hebt die je wilt hercoderen, wil je waarschijnlijk dat de volgorde van de variabele behouden blijft.

We hebben bijvoorbeeld de variabele economy die we maken op basis van de Norris-dataset. Het is een classificatie van landen op basis van hun BBP per hoofd van de bevolking. We hebben de dataset al geïmporteerd (dta) en de relevante packages geladen (tidyverse, rio) aan het begin van dit overzicht.

Eerst maken we de variabele economy aan met de functie factorize uit rio. Dit creëert een factorversie van de oorspronkelijke (gelabelde numerieke) variabele TypeEcon2006.

dta <- dta |>
  mutate(economy = factorize(TypeEcon2006))

De variabele economy kan de volgende waarden aannemen:

table(dta$economy)

       High ($15,000+) Medium ($2,000-14,999)    Low ($2000 or less) 
                    36                     68                     87 

Soms wil men bepaalde categorieën samenvoegen, bijvoorbeeld om de landen van hoog en gemiddeld niveau samen te nemen, maar de volgorde van laag naar hoog behouden. We kunnen dit bereiken met recode_factor:

dta <- dta |>
  mutate(economy_recoded = recode_factor(economy,
                                         "Low ($2000 or less)" = "Lower",
                                         "High ($15,000+)" = "Higher",
                                         "Medium ($2,000-14,999)" = "Higher",
                                         .ordered = TRUE)
         )
mutate(economy_recoded

Dit deel van de code geeft aan dat we een nieuwe variabele economy_recoded willen aanmaken. Als je met je eigen gegevens werkt, kies je een passende naam voor de hergecodeerde variabele.

recode_factor(economy,

Dit deel van de code geeft aan dat we de bestaande variabele economy willen hercoderen. Als je met je eigen gegevens werkt, geef dan de naam op van de bestaande variabele die je wilt hercoderen.

"Low ($2000 or less)"="Lower"

Dit zijn de hercodeerstatements, waarbij we de oude naam links en de nieuwe naam rechts tussen dubbele aanhalingstekens (“) schrijven.

We kunnen zoveel van deze verklaringen opnemen als we willen. Merk op dat de spelling van de oorspronkelijke categorie precies moet kloppen.

.ordered = TRUE

Dit geeft aan dat we een geordende factor willen maken. Let op de punt voor ordered.

Als we de eerste paar waarden bekijken, zien we dat de factor geordend is. De volgorde van de factor wordt bepaald door de volgorde waarin je de hercodeerstatements hebt opgegeven (d.w.z. van laag naar hoog):

head(dta$economy_recoded)
[1] Lower  Lower  Higher Higher Lower  Higher
Levels: Lower < Higher

3.3.3 Hercodering van numerieke variabelen

Het hercoderen van numerieke variabelen werkt op dezelfde manier als het hercoderen van norminale of ordinale variabelen.

Neem als voorbeeld de Freedom House Democracy Ratings voor 2014 (fhrate14), die worden uitgedrukt op een schaal van 1 tot 7. Freedom House gebruikt ook een driepuntsscore: Free (1,0 tot 2,5), Partly Free (3,0 tot 5,0) en Not Free (5,5 tot 7). We hebben de dataset (dta) al geïmporteerd en de relevante packages (tidyverse, rio) geladen aan het begin van dit overzicht.

We kunnen de variabele fhrate14 als volgt hercoderen:

dta <- dta |>
  mutate(fhrate14_recoded = recode(fhrate14,
                                   "1" = 1,
                                   "1.5" = 1,
                                   "2.0" = 1,
                                   "2.5" = 1,
                                   "3" = 2,
                                   "3.5" = 2,
                                   "4" = 2,
                                   "4.5" = 2,
                                   "5" = 2,
                                   "5.5" = 3,
                                   "6" = 3,
                                   "6.5" = 3,
                                   "7" = 3)
         )
table(dta$fhrate14_recoded)

 1  2  3 
89 55 51 
Opmerking

Als je veel unieke waarden hebt, is dit misschien niet de meest efficiënte manier om een numerieke variabele te hercoderen. In zulke gevallen zal het gebruik van ifelse of case_when efficiënter werken, zie Hoofdstuk 5.1 Er zijn ook andere packages die hercodeerfuncties bieden (zoals recode uit package car of rec uit pacakge sjmisc), maar die zullen we hier niet bespreken.


  1. In ons voorbeeld zouden we kunnen gebruiken:

    dta <- dta |>
           mutate(fhrate14_recoded2 = case_when(fhrate14 <= 2.5 ~ 1,
                                                fhrate14 <= 5 ~ 2,
                                                fhrate14 <= 7 ~ 3,
                                                TRUE ~ NA_real_))
    table(dta$fhrate14_recoded2)
    
     1  2  3 
    89 55 51 
    ↩︎