Skip to Tutorial Content

Mål og forberedelser

I denne delen skal vi jobbe videre med data i R. Vi skal også utføre regneoperasjoner, lære mer om klasser og målenivå. Videre skal vi lære å laste inn datasett og laste opp flere funksjoner (pakker). Vi skal også bli kjent med hvordan vi kan hente ut informasjon fra datasettet (som for eksempel skalaen på en variabel/vektor). Det blir også demonstrert hvordan du kan opprette én ny variabel i et datasett, samtidig som du lærer hvordan du kan velge variable fra et datasett, gi dem nye navn og lagre dem i et annet datasett. Til slutt skal du lære hvordan du visualiserer data.

Mål for arbeidsboken

I denne arbeidsboken skal du lære:

  • Å laste inn data og pakker.

  • Om pakken tidyverse.

  • Hvordan bruke pipe %>% og sette sammen funksjoner vha av denne.

  • Hvordan velge variable select() og endre navn med variable rename().

  • Å subsette data.

  • Om klasser og hvordan sjekke skalaen (svaralternativene) på en variabel vha koden levels().

  • Å utforske data vha følgende koder: summary(), str(), head() og tail().

  • Å lage tabeller vha table() og prop.table().

  • Hvordan filtrere ut data vha av filter().

Klasser og målenivå

R operer med seks grunnleggende typer data: numeric, integer, logical, complex og character. (I tillegg finnes det raw data og complex tall, men disse er for det meste ikke nødvendig å bruke, så vi går ikke inn på disse typene her.)

  • Numeric: tall som inneholder et desimal, men de kan også være heltall.
  • Integer: hele tall uten desimaler.
  • Logical: data som enten tar verdien TRUE eller FALSE, i tillegg er representerer NA missingverdier.
  • Character: data som representerer string-verdier. Factor er en spesiell type character string som har tilleggsegenskaper (som nivåer elle en rekkefølge).

Undersøke klasse

Vanligvis kan R differensiere mellom forskjellige klasser av data basert på egenskapene til dataene eller konteksten de er i. Det er allikevel viktig å huske på at R ikke kan lese tankene dine. Derfor er det viktig å sjekke at hvilke klasse R leser data som og om dette stemmer overens med hvilken klasse du tenker at dataene burde bli behandlet som. Dette er spesielt viktig å huske på hvis man vil vite en variabels målenivå, ettersom målenivået ikke nødvendigvis stemmer overens med klassen variabelen har i R.

For å undersøke hvilken klasse et objekt har kan man bruke class()-funksjonen. Outputen forteller deg hvilken klasse R leser dataene objektet inneholder som.

num <- 5.6
class(num)
## [1] "numeric"
char <- "tekst"
class(char)
## [1] "character"
logi <- TRUE 
class(logi)
## [1] "logical"

Alternativt kan man bruke en logisk test for å sjekke om et objekt er en bestemt klasse med is.[klasse]()-funksjonene. Denne funksjonen returnerer enten TRUE eller FALSE, som svar på den logiske testen.

is.numeric(num)
## [1] TRUE
is.numeric(char)
## [1] FALSE
is.character(char)
## [1] TRUE
is.logical(logi)
## [1] TRUE

Nominal

Når variabler er nominale så kan egenskapen deles i to eller flere gjensidig utelukkende kategorier. I ESS datasettet vårt er variabelen vote nominal: man har enten stemt, ikke stemt eller så er man ikke berettiget til å stemme.

Vi kan sjekke hvilken klasse variabelen har ved hjelp av class(). Denne koden tar samme argument som summary() hvor du skriver navnet på datasettet, dollartegn og variabel navn. Er du usikker på hvordan dette gjøres så gå tilbake til det vi gikk gjennom i første arbeidsbok.

Finn klassen på variabelen vote i datasettet datasett.
class(datasett$vote)

Her får vi opp klassen “factor”. Klassen i R samsvarer altså med variabelens målenivå. Vi kan bruke levels() til å sjekke hvilke nivåer eller kategorier som er registrert. Koden tar samme argument som class(), altså levels(datasett$variabel)

Bruk levels() til å finne kategoriene til variabelen vote. Datasettet heter fortsatt datasett.

levels(datasett$vote)

Her ser du at du får opp “skalaen” på variabelen, eller svar alternativene. Det betyr at respondenter har blitt kategorisert etter om de har stemt (“Yes”), ikke stemt (“No”) eller om de ikke har rett til å stemme pga alder eller statsborgerskapsstatus (“Not eligible to vote”).

Ordinalnivå

Når variabler er på ordinalnivå kan de deles i to eller flere gjensidig utelukkende kategorier som kan rangeres, men vi kan ikke si noe om avstanden mellom verdiene og en enhets økning har ikke samme betydning. I ESS datasettet vårt så er variabelen interest et eksempel på en variabel på ordinalnivå.

Bruk koden class() for å finne klassen til variabelen interest. Datasettet heter fortsatt datasett.

class(datasett$interest)
Bruk koden levels() for å se hvilke kategorier variabelen har i R.
levels(datasett$interest)

Her ser du at vi har kategorier fra: “Hardly interested”, “Not at all interested”, “Quite interested” til “Very interested”. Vi kan ikke si hva avstanden mellom for eksempel “Quite interested” og “Very interested” er, men vi kan si at “Very interested” er ‘mer interesse’ for politikk enn “Not at all interested”.

Numerisk

Numeriske variabler kan rangeres, har samme avstand mellom alle verdier og en enhets økning betyr alltid det samme. Her er det altså snakk om variabler med faktiske tallverdier. I ESS datasettet vårt så er variabelen news numerisk.

Bruk koden class() for å finne klassen til variabelen news. Datasettet heter fortsatt datasett.

class(datasett$news)

Her får vi klassen integer. Om en variabel er integer eller numeric betyr ofte i praksis det samme. Forskjellen er at integer-variabler er heltall og numeric-variabler kan ha desimaler.

Når du skal gjøre dine egne analyser så må du være obs og alltid sjekke at klassen på en variabel du skal bruke stemmer overens med målenivået. I mange datasett får kategoriske og ordinale variabler ofte tall istedenfor kategorinavn som verdier og lastes inn som klassen numeric. Dette gjør at kategoriske variabler kan fremstå som at de har et høyere målenivå enn de faktisk har i R. Derfor er det alltid viktig å også sjekke kodeboken for å se hvilket målenivå variabelen faktisk har. Det kommer ikke til å stå “denne variabelen har kategorisk målenivå” så dere må gjøre en selvstendig vurdering basert på hvilke verdier variabelen har.

Base R og pakker

R-pakker er utvidelser til programmeringsspråket R. De inneholder kode, data, og dokumentasjon som gir oss tilgang til funksjoner som løser ulike problemer og gjør koding enklere. Første gang man skal bruke en pakke må man installere den med install.packages(). Etter at vi har installert pakken så må vi “hente den fra biblioteket” med library() for å fortelle R at vi ønsker å bruke pakken. Vi installerer bare pakken en gang, men vi må laste den inn fra biblioteket hver gang vi åpner R på nytt og ønsker å bruke pakken.

tidyverse

tidyverse er et sett med pakker som gjør databehandling mye enklere, som bl.a. inneholder pakkene dplyr og ggplot2:

  • dplyr inneholder mange funksjoner som er veldig nyttige når vi skal jobbe med data.
  • ggplot2 er en pakke vi bruker mye når vi skal visualisere data.

Når man starter et nytt script er det som regel nødvendig å hente tidyverse, ettersom de fleste regelmessig bruker veldig mange funksjoner fra denne gruppen med pakker.

# Installerer tidyverse
install.packages("tidyverse")

# Henter tidyverse fra bibliotekt
library(tidyverse)

Merk at pakkenavnet ikke står i anførselstegn når vi bruker library(). Anførselstegn rundt pakkenavnet er bare nødvendig når vi bruker install.packages().

tidyverse, dplyr og base R

For mange av operasjonen man kan gjøre med funksjonene som ligger i tidyverse, finnes det tilsvarende måter å gjøre det samme med det som kalles base R. Base R er den generiske programvaren som inneholder kodespråket til R. Hvilke funksjoner man bruker i scriptene sine er for det meste opp til egen preferanse, og mange bruker funksjoner fra både tidyverse og base R i samme script.

I arbeidsbøkene “Visualisering av data med ggplot” og “Visualisering av data med base R” viser vi hvordan man kan lage tilsvarende grafer med henholdvis ggplot og base R. En av de andre pakken man bruker mye fra tidyverse er dplyr. Tabellen under viser noen vanlige operasjoner og hvordan man kan gjøre det samme med dplyr og base R. For å lese mer om dette kan dere se på denne siden.

dplyr base R
filter(df, x) df[which(x), , drop = FALSE], subset()
mutate(df, z = x + y) df$z <- df$x + df$y, transform()
rename(df, y = x) names(df)[names(df) == "x"] <- "y"
select(df, x, y) df[c("x", "y")], subset()

Laste inn data

Når du skal gjennomføre en statistisk analyse så er som regel det første steget import og forberedelse av data. En styrke ved R er at det er mulig å importere mange ulike filformat, både fra en mappe på pcen din og fra en url på internett. Det er også mulig å ha flere datasett oppe i R samtidig. Dette dokumentet går gjennom import av csv-filer, men vit at det finnes mange andre muligheter. Hvis du lurer på hvordan man skal laste inn en bestemt filtype og har glemt hvordan du gjør det så er dette veldig lett å finne svaret på internett.

I denne arbeidsboken skal vi jobbe med et datasett som er det man kaller en csv-fil. Datasettet er fra European Social Survey Round 9 (2018). European Social Survey er en spørreundersøkelse og datasettet du skal jobbe med i denne arbeidsboken inneholder svarene fra norske respondenter. For å laste inn datasettet bruker vi koden read.csv(). Argumentet du putter i parantesen er enten et filnavn eller en URL. Mange datasett er fra internett og kan derfor lastes inn ved hjelp av en URL. Det ser slik ut:

ess <- read.csv("https://raw.githubusercontent.com/louisabo/Data-For-Teaching/main/utvalg_NO_ESS_2018.csv") 

I kodesnutten over så oppretter vi først et objekt som heter ess. Deretter kommer koden read.csv() og inne i parentesen følger enten en filbane som viser hvor på maskinen din csv-filen er lokalisert eller URL-en dersom du laster det inn direkte fra internett. Merk at du må ha anførselstegn rundt filbanen/URL-en.

Vi skal jobbe med et utvalg av variablene i datasettet ess som vi skal plukke ut under. Datasettet ess består av 1406 observasjoner og 9 variable. Hver observasjonsenhet er en person i Norge. Utvalget er trukket vha sannsynlighetsutvelging og utvalget er derfor representativt for den norske befolkning. Dataene ble utgitt i 2018. Datasettet består av følgende variabler:

  • nwspol: viser hvor mange minutter en respondent bruker på nyheter om dagen. Verdiene går fra 0-1109 minutter.

  • polintr: sier noe om hvor politisk interessert hver respondent er. Verdiene er på ordinalnivå med fire kategorier.

  • vote: denne variabelen oppgir om respondenten stemte ved forrige stortingsvalg.

  • yrbrn: sier hvilket årstall respondenten er født i.

  • trstlgl: sier hvorhvidt respondenter har tillit til det juridiske systemet i Norge (0 ingen tillit, 10 høy tillit). -trstplc: sier hvorhvidt respondenten har tillit til landents politikere (0 ingen tillit, 10 høy tillit).

  • trstprt: sier hvorhvidt respondenten har tillit til landets politiske partier.

  • trstep: sier hvorhvidt respondenter har tillit til Europaparlamentet.

Organisering av data: indeksering og subsetting

Indeksering av data

For å få ut bestemte verdier i et datasett kan vi indeksere med klammeparanteser [ ]. I klammeparantesene spesifiserer vi posisjonen(e) til verdien(e) vi ønsker å få ut. Hvis objektet vi jobber med er en en-dimensjonal vektor trenger vi bare å spesifisere hvilken nummer verdien er i rekken. Dersom vi jobber med et datasett, må vi spesifisere kolonne og rad.

# Henter ut den andre verdien i den tredje kolonnen: 

datasett[2,3]
## [1] Yes
## Levels: No Not eligible to vote Yes
# Får samme outputen som over med følgende kode: 
datasett$vote[3]
## [1] Yes
## Levels: No Not eligible to vote Yes

Vi kan også hente ut verdier fra flere rader eller kolonner ved hjelp av klammeparanteser. Vi kan gjøre dette for sekvensere ved å spesifere disse som vektorer:

# Henter ut de verdiene for rader 5-10 for kolonner 1-3: 

datasett[5:10, 1:3]

Eller vi for ikke-sekvensielle rader og kolonner, kan vi bruke c()-funksjonen:

# Henter ut de verdiene for rader 5, 10 og 12 for kolonner 1 og 3: 

datasett[c(5,10,12), c(1,3)]

Det kan også hende at vi ønsker å hente ut enten alle radene for spesifikke kolonner eller alle kolonnene for spesifikke rader i et datasett.

# Henter ut alle radene for kolonner 1-3: 

datasett[, 1:3]
# Henter ut alle kolonnene for rader 5, 7, 13, 21: 

datasett[c(5, 7, 13, 21), ]

Dersom vi ønsker å utelukke spesifikke rader eller kolonner, kan vi gjøre dette ved å bruke samme framgangsmåte som vi har brukt så langt, men bare legge til negative fortegn.

# Henter ut alle radene bortsett fra 5-20 og alle kolonnene bortsett fra kolonner 2 og 4: 

datasett[-5:-20, -c(2, 4)]

Logiske indekser

Vi kan også bruke indeksering til å velge ut data basert på ulike logiske tester. Vanlige logiske tester å bruke er bl.a. følgende:

# Lik eller større enn 60
datasett[datasett$age >= 60] 

# Større enn 60
datasett[datasett$age > 60] 
  
# Lik eller mindre enn 60 
datasett[datasett$age <= 60] 

# Mindre enn 60 
datasett[datasett$age < 60] 

# Lik 60
datasett[datasett$age == 60] 

# Ulik 
datasett[datasett$age != 60] 

Å indeksere ved hjelp av logiske tester er nyttig hvis vi bare vil ha med oss observasjoner som møter spesifikke kriterier, f.eks. at vi indekserer basert på minutter brukt på nyheter hver dag.

# Henter ut alle respondenter som bruker mer enn 60 minutter daglig på nyheter: 

datasett[datasett$news > 60, ]

Vi kan også bruke logiske tester til å indeksere basert på verdien til en character string eller et factor level. Under vil vi hente ut alle respondenter som oppgir at de har stemt ved forrige valg.

# Henter ut alle respondenter som oppgir å ha stemt ved forrige valg ("Yes"): 

datasett[datasett$vote == "Yes", ]

For mer komplekse logiske tester, kan vi kombinere de logiske testene med Boolske uttrykk. Her kan vi bruke & (OG) for å si at vi vil hente verdier som møter kriterier. Hvis vi verdier bare må møte et av flere kriterier, kan vi bruke | (ELLER).

# Henter ut alle respondenter som oppgir å ha stemt ved forrige valg ("Yes") OG som bruker mer enn 60 minutter dalig på nyheter : 

datasett[datasett$vote == "Yes" & datasett$news > 60, ]

Hent ut alle respondenter som ENTEN oppgir å ha stemt ved forrige valg (“Yes”) ELLER som bruker mer enn 60 minutter dalig på nyheter.

datasett[datasett$vote == "Yes" | datasett$news > 60, ]

Subsetting av data

Å subsette betyr å bruke det som ligger inne i et datasett til å opprette et nytt et. Når vi skal subsette så kan vi bruke funksjoner i pakken dplyr. Med dplyr bruker vi %>%for å binde sammen ulike operasjoner vi vil utføre på et datasett. %>% kalles ofte for en pipe og når man bruker %>% kalles det piping. Det er en effektiv og ryddig måte å kode på.

Vi har installert dplyr tidligere, men vi må hente den inn fra biblioteket for å kunne bruke funksjonene.

Bruk library til å laste inn pakken dplyr.

library(dplyr)

select()-funksjonen

Den første funksjonen vi skal bruke er select(). Denne brukes til å velge hvilke variabler du vil ha med i det nye datasettet ditt. Her velger jeg å ta med variablene alder og valg i det nye datasettet df_ny.

NB! Se også Arbeidsbok 2 for mer informasjon om hvordan man bruker select()-funksjonen.

# Subsetter datasett med select()
df_ny <- df %>% select(alder, valg)
# Sjekker hvilke variabler som ligger i det nye datasettet med summary()-funksjonen
summary(df_ny)
##      alder           valg          
##  Min.   :15.00   Length:1300       
##  1st Qu.:32.00   Class :character  
##  Median :47.00   Mode  :character  
##  Mean   :45.99                     
##  3rd Qu.:60.00                     
##  Max.   :90.00

Bruk select() og %>% til å lage et datasett som heter df_ny. df_ny skal inneholde variablene internett og valg fra datasettet df.

df_ny <- df %>% select(internett, valg)
# Husk å skrive navnet på den nye datasettet før <-, og det gamle datasettet etterfulgt av en pipe (\%\>\%) før du skriver inn spesifiseringen av det nye datasettet vha select() etter.
# I select() må variablene være i riktig rekkefølge for å få riktig svar, altså (internett, valg).

filter()-funksjonen

Du kan også bruke filter()-funksjonen til å sette krav som enhetene i datasettet må møte for å bli tatt med i det nye datasettet. Under har jeg brukt funksjonen til å bare ta med respondenter som har stemt og som er eldre enn gjennomsnittet.

NB! Se også Arbeidsbok 2 for mer informasjon om hvordan man bruker filter()-funksjonen.

# Subsetter datasettet med filter()
df_ny <- df %>% filter(valg == "Stemt", 
                       alder > mean(alder))
# Sjekker det nye datasettet med summary()-funksjonen
summary(df_ny)
##      alder           valg             internett     
##  Min.   :46.00   Length:623         Min.   :   4.0  
##  1st Qu.:53.00   Class :character   1st Qu.:  90.0  
##  Median :59.00   Mode  :character   Median : 120.0  
##  Mean   :60.55                      Mean   : 192.4  
##  3rd Qu.:68.00                      3rd Qu.: 240.0  
##  Max.   :90.00                      Max.   :1440.0

Filtrere ut data

Her skal vi bruke koden filter() til å filtrere ut observasjoner med spesifikke verdier. filter() brukes med spesifikke logiske symboler og tar minst to argumenter, et data-argument og et variabel-argument, eventuelt flere variabel-argument dersom du ønsker å filtrere ut observasjoner på flere variabler.

Oversikt over logiske operatorer:

Operator Betydning
== er lik
< mindre enn
> større enn
<= mindre eller lik
>= større eller lik
!= ikke lik
!x ikke x
| eller
& og

Et eksempel er at vi spør R om å filtrer ut respondenter som er født etter år 2000 med filter(>). Det som er viktig å huske på her er at vi må passe på at variabelene vi filtrer på er numeriske dersom vi oppgir f.eks tallverdier.

Et eksempel på hvordan bruke filter er som følger:

filter(datasett, year_born > 2000)

R vil her vise alle respondenter som er født etter år 2000. Vi kan for eksempel også filtrere ut alle som har svar at de stemte på følgende måte:

filter(datasett, vote == "Yes")

Koden følger argumentet data først som heter datasett og deretter variabelen vi ønsker å filtrere på. Vi kan også skrive koden på følgende måte:

datasett %>% 
filter(vote == "Yes")

Begge kodene gjør akkurat det samme. Jeg anbefaler alle til å jobbe med den nederste måten hvor man bruker %>% (eller en pipe som det heter). Koden gir en pipe inn i datasettet datasett og sier at inni dette datasettet så vil jeg filtrere ut alle respondenter som har stemt.

Bruk filter til å finne alle respondenter som er 20 år. (age == 20).
datasett %>%
  filter(age == 20)
# Husk å skrive navnet på datasettet også skriv `%>%` deretter bruker du filter(). Inni filter skriver du variabel og det du ønsker å filtrere ut.  

Ofte når vi bruker filter() vil vi telle observasjonene. I dette datasettet er det mange observasjoner. I R kan du bygge opp kode på følgende måte vha av %>% (eller piper).

datasett %>% 
  filter(age < 50) %>% 
  count()

Når vi bruker count() etter filter vil R telle hvor mange observasjoner som blir filtrert ut på den variabelen du filtrer på.

Bruk filter til å finne alle respondenter som er 20 år. Legg til count() for å telle hvor mange respondenter som er 20 år.
datasett %>%
  filter(age == 20) %>% 
  count()
# Husk å skrive navnet på datasettet også skriv `%>%` deretter bruker du filter(). Inni filter skriver du variabel og det du ønsker å filtrere ut. Husk at oppgaver spør etter ALLE repondenter som er 20 år, da må du bruke to erlik-tegn. Deretter skriver du en `%>%` hvor legger til argumentet count().
Hvor mange av respondentene i datasettet er over 25 år?
datasett %>% 
  filter(age > 25) %>%
  count()
# Det som er vanskelig med denne oppgaven er å huske hvilken vei de logiske operatorene skal gå. Mer enn er > og mindre enn er <. Her er det lurt å videre også bare prøve seg frem, så sitter det til slutt. 

Subsetting med flere funksjoner samtidig

Subsetting kan også gjøres med flere funksjoner samtidig. Når du skal legge til en til funksjon legger du til en pipe og skriver funksjonen etter den. Det som er viktig å huske på her, er at R vil kjøre gjennom koden i den rekkefølgen du har skrevet den. Derfor er det viktig at du skriver funksjonene i riktig rekkefølge.

Her filtrerer vi først på respondenter som har stemt og som er eldre enn gjennomsnittet i datasettet df, før vi velger å bare ta med variablene internett og valg i det nye datasettet df_ny. Dersom vi hadde startet å velge internett og valg ville vi fått en feilmelding. Da ville ikke R kunne filtrere på alder, ettersom vi allerede ville ha fjernet denne variabelen fra datasetet.

# Subsetter datasettet med filter() og select()
df_ny <- df %>% filter(valg == "Stemt", 
                       alder > mean(alder)) %>% 
                select(internett, valg)

Lag et nytt datasett som heter df_ny. Bruk filter() kombinert med mean() for lage et datasett som bare inneholder observasjoner av respondenter som ikke har stemt (“Ikke stemt”) som bruker mindre internett enn gjennomsnittet. Til slutt skal du bruke select() til å velge variablene alder og valg

df_ny <- df %>% filter(valg == "Ikke stemt", 
                       internett < mean(internett)) %>% 
                       select(alder, valg)
# Husk å skrive navnet på den nye datasettet før <-, og det gamle datasettet med spesifiseringen av det nye datasettet vha filter() og select() etter.
# Alle funksjonene og variablene må være i riktig rekkefølge for å få riktig svar.

Omkoding av variabler

Når vi omkoder variabler i et datasett, bør vi opprette en ny variabel. Dersom vi ikke gjør dette, erstatter vi informasjonen i den opprinnelige variabelen. Vi trenger informasjonen i den opprinnelige for å teste at omkodingen har fungert som vi ønsker. Det kan også skje at vi gjør en feil som vi ikke kan rette opp uten den opprinnelige variabelen (dette hender).

Først er det greit å få en oversikt over variabelene i datasettet og spesielt den vi ønske å kode om. Nyttige funksjoner å bruke til dette kan være summary(), head() og tail().

Bruk summary()-funksjonen for å få en bedre oversikt over datasettet df.

summary(df)

Matematisk omkoding

Først skal vi lære å kode om variablene ved å bruke matematiske omkoding. For å vise dette bruker vi variabelen alder. Her kan vi lage en variabel som viser når respondentene ble født. Hvis respondentenes alder ble registrert i 2021, kan vi finne ut når de ble født ved å trekke alderen deres fra 2021.

Lag en ny variabel i datasettet df som heter fodselsar ved å trekke variabelen alder fra 2021.

df$fodselsar <- 2021-df$alder
#  Husk å skrive navnet på den nye variabelen før <-, og så den matematiske omkodingen etter. 
# Matematisk omkoding 
2021-df$alder

I den forrige oppgaven får du beskjed om at omkodingen er blitt gjort riktig, men du ser dette ikke selv. For å sjekke dette på egenhånd kan vi bruke table()-funksjonen. Her sjekker vi om det stemmer at alder i 2021 (alder) pluss året man ble født (fodselsar) er lik 2021. Dette er sant for alle 1572 respondenter, som indikeres ved at det står TRUE.

# Omkodingen fra forrige oppgave
df$fodselsar <- 2021-df$alder
# Sjekker med table() at omkodingen har blitt gjort riktig
table((df$alder + df$fodselsar) == 2021)
## 
## TRUE 
## 1300

Vi kan også lage et plott med en linje som viser sammenhengen mellom variablene alder og fodselsar.

# Plotter en linje med ggplot() og geom_smoot()
ggplot(df, aes(x = alder, y = fodselsar)) + geom_smooth()
## `geom_smooth()` using method = 'gam' and formula = 'y ~ s(x, bs = "cs")'

Husk at du kan bruke alle matematiske funksjoner når du lager variabler. Du kan dele (/), gange (*), plusse (+) og trekke fra (-).

Omkoding med ifelse()

Man kan også omkode variabler ved hjelp av funksjoner. En nyttig funksjon til omkoding er ifelse(). Med ifelse() så forteller du R hva du vil at de gamle verdiene i en variabel skal byttes ut med. Argumentene i funksjonen fungerer slik: ifelse(test, yes, no). Med andre ord, så lager man en test som verdier i variabelen enten oppfyller eller ikke. Verdiene som møter kravet til testen får en verdi (yes), og de som ikke møter kravet til testen får en annen verdi (no).

Her kan vi lage en variabel som skiller mellom respondentene som er 50 år eller eldre og de som er yngre enn 50 år. De som er 50 år og oppover skal få verdien 1 og de som er under 50 år skal få verdien 0.

# Omkoding med ifelse()
df$nyalder <- ifelse(df$alder >= 50, 1, 0)

Her sjekker vi om vi har gjort omkodingen riktig med table(). Tabellen under er ganske uoversiktlig, men vi ser at alle under 50 år har fått verdien 0, og de 50 år og over har fått verdien 1.

# Sjekk av omkoding med table()
table(df$nyalder, df$alder)
##    
##     15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
##   0  8 21 23 18 26 10 21 25 18 21 19 23 19 16 23 22 11 23 23 17 25 20 16 21 23
##   1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
##    
##     40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
##   0 28 18 24 20 18 23 23 31 29 33  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
##   1  0  0  0  0  0  0  0  0  0  0 24 21 18 31 23 30 23 18 32 15 26 14 22 18 15
##    
##     65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 84 85 86 87 88 90
##   0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
##   1 17 27 14 16 17 16 13 19 10 12 22  6  9  5  9  3  4  3  1  1  1  2  2  2

Bruk ifelse til å lage en ny variabel som heter omkodetalderi datasettet df, hvor alle som er 40 år og eldre får verdien 2 og alle som er under 40 år får verdien 1.

df$omkodetalder <- ifelse(df$alder >= 40, 2, 1)
# Husk å skrive navnet på den nye variabelen før <-, og så omkodingen med ifelse() etter.  
# Husk at rekkfølgen i ifelse()-funksjonen er ifelse(logisk test, verdi hvis testen er sann, verdi hvis testen ikke er sann).
# Logisk test: 
ifelse(df$alder >= 40, 2, 1)

I de forrige kodesnuttene har vi brukt verdiene fra variabelen i test-argumentet, men man kan også bruke andre funksjoner, f.eks. mean()-funksjonen. Her sier vi at vi vil at alle som er yngre enn gjennomsnittsalderen får verdien 0 og alle som er eldre enn gjennomsnittet får verdien 1.

# Omkoding med ifelse
df$meanalder <- ifelse(df$alder < mean(df$alder), 0, 1)

Bruk ifelse() til å legge til en ny variabel som heter medianalder i datasettet df, hvor alle som er yngre enn median-alderen får verdien 0 og alle som er eldre får verdien 1.

df$medianalder <- ifelse(df$alder < median(df$alder), 0, 1)
# Husk å skrive navnet på den nye variabelen før <-, og så omkodingen med ifelse() etter.  
# Husk at rekkfølgen i ifelse()-funksjonen er ifelse(logisk test, verdi hvis testen er sann, verdi hvis testen ikke er sann).
# Logisk test: 
ifelse(df$alder < median(df$alder), 0, 1)

Omkoding med ifelse() - dummyvariabel

Vi kan også bruke ifelse() til å kode om en variabel til en dummyvariabel. En dummyvariabel er en kategorisk variabel hvor alle enhetene får en av to mulige verdier. Som oftest bruker man verdiene 0 og 1 når man lager en dummyvariabel. Dummyvariabler indikerer at en bestemt ting stemmer eller ikke om en enhet, f.eks. om en respondent stemte (1) eller ikke ved stortingsvalget i 2021 (0).

Bruk ifelse() til å lage en ny variabel i datasettet df som heter dummy. Variabelen dummy skal ta veridien 1 om observasjonen har verdien “Stemt” på variabelen valgog 0 ellers.

df$dummy <- ifelse(df$valg == "Stemt", 1, 0)
# Husk å skrive navnet på den nye variabelen før <-, og så omkodingen med ifelse() etter.  
# Husk at rekkfølgen i ifelse()-funksjonen er ifelse(logisk test, verdi hvis testen er sann, verdi hvis testen ikke er sann).
# Husk å skrive "Stemt" i hermetegn. 
# logisk test: 
ifelse(df$valg == "Stemt", 1, 0)

Vi har lastet inn datasettet vi skal jobbe med fra ESS. Nå skal vi forberede dataene. Ofte følger det med en kodebok når man laster ned data. Kodeboken inneholder informasjon om variablenes navn, hvilket målenivå de har og hva observasjonsenheten er. Kodeboken til ESS finner dere her. ESS inneholder mange landspesifikke variabler og kodeboken er derfor veldig lang. Du trenger ikke å slå opp i kodeboken for å løse oppgavene i denne arbeidsboken, men når du skal kjøre dine egne analyser er det viktig å se nøye på kodeboken før du begynner å jobbe med dataene.

Større datasett som ESS inneholder ofte mange flere variabler enn de vi ønsker å bruke i våre analyser. Variablene kan også ha navn som er vanskelig å tolke og huske. For å finne ut hvilken informasjon variablene inneholder så kan vi slå opp i kodeboken. Vi har allerede valgt noen variabler fra datasettet som du skal jobbe med og slått opp hva variabelnavnene betyr, så du trenger ikke å åpne kodeboken for å løse oppgavene i denne arbeidsboken.

Nå skal vi fjerne de variablene vi ikke skal bruke og gi variablene navn som er lette å forstå og huske. For å gjøre dette skal vi benytte oss av funksjoner i pakken dplyr. Først bruker vi select() til å velge de variablene vi vil beholde og så bruker vi rename() til å endre navnene. Vi bruker en pipe %>% mellom funksjonene, som tar outputen til et utsagn og gjør det til inputen til det neste utsagnet. Pipen kan sees på som ordet “så”. Vi fyller inn navnene på de variablene vi vil beholde i select() og skiller variabelnavnene med et komma så vi får select(variabel1, variabel2). rename() lar oss forandre navnet til variabler og bruker syntaksen rename(nytt_navn = gammelt_navn).

Før vi fjerner de variablene vi ikke skal bruke må vi laste inn pakken.

Bruk koden library() for å last inn pakken dplyr.

library(dplyr)

I neste kodebit ser du et eksempel på hvordan du kan lage et nytt datasett som bare inneholder variablene nwspol, polintr, vote og yrbrn, samt endre navnene på variablene. På linje to velger jeg de variablene jeg skal ha med meg fra datsettet som ble lastet inn over og på de siste linjene endrer jeg navn. Merk at jeg bruker rename og endrer navnet til news fra nwspol osv.

mitt_datasett <- ess %>% # Oppretter et nytt objekt som heter mitt_datasett 
  select(nwspol, polintr, vote, yrbrn) %>%  # Sier at vi bare vil beholde variablene nwspol, polintr, vote og yrbrn
  rename(news = nwspol, # Endrer navn på nwspol til new
        interest = polintr, # Endrer navn på polintr til interest
        year_born = yrbrn) # Endrer navn på yrbrn til year_born

Nå er det din tur.

Opprett ett nytt objekt som heter datasett. Dette datasettet skal inneholde variablene news, interest, year_born og vote. Du skal hente variablene fra mitt_datasett. Du må bruke select() og %>%. Du skal ikke endre navnene på variablene i dette steget.

datasett <- mitt_datasett %>% 
  select(news, interest, year_born, vote)

I forrige arbeidsbok så brukte vi koden summary().

Bruk summary() til å få oversikt over datasettet du nettopp opprettet med navn datasett

summary(datasett)

Ved hjelp av funksjonen summary() får vi oversikt over variablene i datasettet. Vi kan også bruke summary(datasett$variabel) for å hente ut informasjon om en variabel.

Bruk summary til å hente ut spesifikk informasjon om variabelen year_born

summary(datasett$year_born)

Her ser du at R printer informasjon som minimums- og maksimumsverdi på variabelen. Samtidig printer den medianen og gjennomsnittet. Den sier også hvor mange av observasjonene i datasettet som ikke har besvart spørsmålet i spørreundersøkelsen. Disse er NA eller missing. Som du kanskje forstår så er 1928 den minste verdien, det betyr at ingen av respondentene er født før 1928 i datasettet. Den høyeste verdien i denne variabelen er 2003.

Ettersom vi vet at undersøkelsen ble gjennomført i 2018, kan vi regne oss frem til alderen til alle respondentene ved hjelp av variabelen year_born. I neste kodebit legger vi til en ny variabel i datasettet. Dette gjøres ved å bruke opprette-objekt-pilen (<-). Deretter skriver du datasett etterfulgt av $ og hva du vil kalle den nye variabelen: datasett$variabel_navn. Vi skal kalle den nye variabelen age og legge den til i datasettet vårt som heter datasett. Det er det som koden på venstre side av pilen betyr. Det jeg putter på høyreside av pilen er det variabelen består av. I R kan man utføre vanskelige regneoperasjoner med et par kodestrenger. Her skal jeg trekke fra 2018 fra variabelen year_born (altså minus 2018 på hver rad i datasettet) så får jeg alderen til alle respondentene. Det ser slik ut:

datasett$age <- 2018 - datasett$year_born

Nå har jeg opprettet en ny variabel i datasettet datasett som heter age. Vi skal lære mer om å opprette variable i senere arbeidsbøker.

Bruk koden summary() for å få en oversikt over den nye variabelen age.

summary(datasett$age)

Her får du igjen oversikt over den yngste respondenten og den eldste respondenten i antall år – altså alder og ikke basert på det året de ble født.

Utforske data

Vi skal nå bli litt bedre kjent med dataene våre. Det er mange ulike måter å utforske datasett og variabler på. Vi har allerede sett på funksjonen summary(), men vi skal jobbe videre med str(), head() og tail().

Oversikt

For å få et deskriptivt sammendrag av et objekt kan vi bruke summary() eller str(). Begge disse kodene tar argumenter i form av et objekt (str(datasett)) eller et objekt og noe annet fra objektet (str(datasett$variabel)).

Bruk koden str() for å få en oversikt over datasettet vi jobber med. Datasettet heter fortsatt datasett.

str(datasett)

str() gjør at R printer litt informasjon om datasettet (antall observasjoner og variabler), sier hvilken klasse variablene har og viser noen av kategoriene til variablene.

Hvis man vil se de første eller siste radene i et datasett så kan man bruke henholdsvis head() og tail(). Disse tar samme argumenter som summary() og str().

Bruk koden head() til å se de første radene i datasettet.
head(datasett)
Bruk koden tail() til å se de siste radene i datasettet som heter datasett.
tail(datasett)

Som nevnt over kan alle disse funksjonene også brukes på enkeltvariabler. Da er argumentet f.eks tail(datanavn$variabelnavn).

Deskriptiv statistikk

Det er variabelens målenivå som avgjør hvilken deskriptiv statistikk som er fornuftig.

Kategoriske variabler

R har ingen innebygd funksjon for å finne modusverdien/typetall. Ved å søke på internett så finner du fort mange ulike funksjoner du kan bruke, men for å gjøre det enkelt bruker vi bare table(). Funksjonen table() gir oss en frekvenstabell, mens prop.table gjør om frekvenstabellen til andeler. ESS datasettet mangler data for noen observasjoner. Ved å ta med useNA = "always" i table() så får vi også denne informasjonen i tabellen:

# Her printer jeg en vanlig tabell som inkluderer NA
table(datasett$vote, useNA = "always")
## 
##                   No Not eligible to vote                  Yes 
##                  124                  125                 1156 
##                 <NA> 
##                    1
# Her printer jeg en tabell som er gjort om til andeler
prop.table(table(datasett$vote))
## 
##                   No Not eligible to vote                  Yes 
##           0.08825623           0.08896797           0.82277580
# Her printer jeg en tabell som er gjort om til andeler, men som inkluderer NA
prop.table(table(datasett$vote, useNA = "always"))
## 
##                   No Not eligible to vote                  Yes 
##         0.0881934566         0.0889046942         0.8221906117 
##                 <NA> 
##         0.0007112376

Funksjonen table() og prop.table() gir også en god oversikt over variablene som sådan. Legg merke til at når vi bruker prop.table() så er neste argument table() og deretter datasett$variebelnavn.

Legg merke til at du kan legge til gange 100 på slutten av parantesen så får du andelen i prosent.

prop.table(table(datasett$vote))*100
## 
##                   No Not eligible to vote                  Yes 
##             8.825623             8.896797            82.277580

Her ser vi at ca 82% av respondentene stemte ved forrige valg og at 8.9% av respondentene ikke har stemmerett, mens 8.8% av respondentene ikke stemte ved forrige valg.

Bruk table() for å få oversikt over fordelingen på variablen interest i datasettet datasett. Ikke legg til useNA argumentet.

table(datasett$interest)

Bruk prop.table() til å få en oversikt over variabelen interest i datasettet datasett. prop.table() gjør om frekvenstabellen fra table() til andeler.

prop.table(table(datasett$interest))
Gjør om frekvenstabellen med andeler til prosent.
prop.table(table(datasett$interest))*100
# Her må du gange med 100 på slutten av tabellen

Numeriske variabler

For å få oversikt over kontiuerlige variable kan du bruke funksjonen summary() som tidligere vist. Andre relevante er blant annet sd() som gir deg standardavviket til en variabel. Her er noen eksempler:

  • min() finner minimumsverdien (det laveste antall minutter brukt på nyheter). na.rm = TRUE forteller R at missing skal droppes i beregningen:
min(datasett$news, na.rm = TRUE)
## [1] 0
  • max() finner maksimumsverdien (det høyeste antall minutter brukt på nyheter). na.rm = TRUE forteller R at missing skal droppes i beregningen:
max(datasett$news, na.rm = TRUE)
## [1] 1109
  • mean() finner gjennomsnittlig antall minutter brukt på nyheter. na.rm = TRUE forteller R at missing skal droppes i beregningen:
mean(datasett$news, na.rm = TRUE)
## [1] 104.1006
  • median() finner median. na.rm = TRUE forteller R at missing skal droppes i beregningen:
median(datasett$news, na.rm = TRUE)
## [1] 60
  • sd() finner standardavviket. na.rm = TRUE forteller R at missing skal droppes i beregningen:
sd(datasett$news, na.rm = TRUE)
## [1] 155.5571
  • var finner varians. na.rm = TRUE forteller R at missing skal droppes i beregningen:
var(datasett$news, na.rm = TRUE)
## [1] 24198.01
  • quantile finner kvantilverdiene. na.rm = TRUE forteller R at missing skal droppes i beregningen:
quantile(datasett$news, na.rm = TRUE)
##   0%  25%  50%  75% 100% 
##    0   30   60  120 1109
  • summary finner forskjellig deskriptiv statistikk for en variabel:
summary(datasett$news)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max.    NA's 
##     0.0    30.0    60.0   104.1   120.0  1109.0      34

Legg merke til at hvert argument har et tilleggsarguement som fjerner missing-verdier (NA). Hvis en variabel har missing-verdier og ber R om å finne gjennomsnittet på variabelen, så vil ikke R kunne regne gjennomsnittet på denne variabelen med mindre du spesifiserer dette argumentet.

Bruk mean() til å finne gjennomsnittet til variabelen age i datasettet datasett. Husk at du må legge til et argument som sier hvordan du skal håndtere missingverdier (NA).
mean(datasett$age, na.rm=TRUE)
# Husk at du må legge til datasett$variabel, etterfulgt av komma og deretter na.rm=TRUE

Bruk sd() til å finne standardavviket til variabelen age i datasettet datasett. Husk at du må legge til et argument som sier hvordan du skal håndtere missingverdier (NA).

sd(datasett$age, na.rm=TRUE)
# Husk at du må legge til datasett$variabel, etterfulgt av komma og deretter na.rm=TRUE

Neste arbeidsbok

Data i R

Master i statsvitenskap — R-forberedelse

Eli Sofie Baltzersen, Louisa Boulaziz, Bjørn Høyland, Eric Nilsen, Lise Rødland

8/9/2021