Skip to Tutorial Content

Mål og forberedelser

Denne arbeidsboken inneholder elementer som er viktig for grunnleggende statistiske analyser.

I denne arbeidsboken skal du lære:

  • Hvordan man behandler missing data.
  • Å gjennomføre og visualisere univariate analyser.
  • Å gjennomføre og visualisere bivariate analyser.

Hente inn data

Som vi husker fra de forrige arbeidsbøkene må vi laste inn dataene og pakkene vi skal bruke når vi starter å jobbe. Det finnes mange filformater som data kan komme i, og for de fleste finnes det en egen funksjon. For noen typer, f.eks. excel-filer, så må man ha en pakke som gjør at vi kan laste de inn. I denne arbeidsboken kommer vi til å bruke et format som heter .csv. Dette er et vanlig format for å lagre data i.

#For å laste inn store .csv filer kan vi bruke vroom funksjonen. 
ESS <- vroom::vroom("www/ess.csv", show_col_types = FALSE)

Når vi har lastet inn datasettet er det lurte å undersøke hva objektet inneholder. Disse dataene er utvalg av variabler fra the European Social Survey, en spørreundersøkelse som har gått i flere europeiske land siden 2002. Det er flere måter vi kan undersøke hvordan datasettet ser ut. Her kan dere prøve str() ogsummary().

Hint: Husk at navnet på datasettet må være inni parantesene.

Datasett

Manglende verdier og missing data

Datasettet vårt består altså av 24 variabler med 3 504 observasjoner. Dette er 24 spørsmål fra Danmark og Norge i ESS. Spørsmålene stiller forskjellige spørsmål om politiske oppfatninger, og informasjon om individet. Definisjonene kan dere se her.

Kodebok

Navn Beskrivelse Skala
Time_News Minutter brukt på nyheter pr. dag numerisk
Trust_People Stoler du på andre? 1:10, 10 = Høy tillit
People_Fair Er de fleste mennesker rettferdige? 1:10, 10 = De fleste kan stoles på
Pol_Interest Er du innteresert i politikk? 1:4, 1 = Høy interesse
Trust_Police Stoler du på politiet? 1:10, 10 = Høy Tilitt
Trust_Politicans Stoler du på politikere? , 1:10, 10 = Høy Tillit
Vote Stemte du ved sist valg? 1 = ja, 2 = nei, 3 = Ikke stemmerett
Party_Voted_NO Hva stempte du på? Kun for norske respondenter
Left_Right Høyre-Venstre skala 0 = venstre, 10 = høyre
Satisfied_Gov Hvor fornøyd er du med regjeringen? 1:10, 10 = Veldig Fornøyd
Gov_Reduce_IncomDif Burde regjeringen jobbe for å redusere inntektsforskjeller? 1:5, 1 = Agree
LGBT_Free LGBT mennesker bør få leve det live de selv ønsker 1:5, 1 = Agree
Religous Hvor religiøs er du? 0:10, 10 = Svært religiøs
Climate_Human klimaforandringene er menneskeskapt 1:5, 5 = Svært Enig

Det finnes mange grunner til at data kan være manglende, eller missing som en ofte sier. Ofte er det slik at respondenter ikke vil svare på enkelte spørsmål, eller data er ikke samlet inn et gitt år eller sted. Her skal vi se på hvordan vi kan finne ut om det er missing i dataene våre, og evt. hvor mye det er. Dette datasettet inneholder to typer missing. De fleste respondenter vil ha spørsmål de ikke svarer på av forskjellige årsaker, f.eks. er det mange som ikke vil si hva de stemmer på. Den andre er land som ikke er med i visse runder, f.eks. er ikke Danmark med i runde 8 og 9. Det er flere måter vi kan se på antall NA. Fra summary() som vi så på istad ser dere at antall NA står nederst i tabellen for hver variabel. Vi kan også sjekke om en verdi (celle/observasjon/value) er NA med funksjonen is.na(). Denne kan du bruke både på en enkelt variabel, eller hele datasettet. Prøv å bruke denne til å finne ut hvor mye NA det er i datasettet, og i variabelen Time_News

Hint: For å få antall lønner det seg å bruke sum()-funksjonen.

Datasett

Prøv å se om du forstår hva som står på hjelpefilen for NA. Vanligvis må vi beskrive hvordan NA er. Vi må også velge hva vi skal gjøre med dem. Veldig vanlig er å fjerne NA hvis de er ’missing at random’ eller missing completely at random.’ Du kan velge å fjerne alle missing verdier eller bare missing verdier på spesifikke variable. Når vi begynner med analyser så vil R ta høyde for de tomme cellene, R fjerner dem automatisk. Det er som når vi bruker gjennomsnittet – man kan ikke regne gjennomsnittet av missing, derfor må vi si til R hvordan R skal håndtere missing.

ESS dataene er ment å brukes som land-runder. Det meste av missing kan vi dermed fjerned gjennom å bruke filter() for å hente ut ett spesifikt land og en spesifikk runde. Resten av teksten kommer vi til å se på Norge i runde 8. Prøv å bruk filter for å lage et nytt datasett NO8 som kun har de radene som har verdien NOCountry-variabelen og 8 på essround-variabelen.

NO8 <- ESS %>%
  filter(Country == "NO" & essround == 8)
NO8<- ESS %>%
#Husk å start med dette, og inkluder & mellom Country og essround i filter

Nå som vi har valgt ut Norge i runde 8 har vi mye færre missing-verdier. Dette er jo for de vi har fjernet de fleste land-rundene. Vi kan også fjerne alle NA som er igjen med drop_na() funksjonenen. Dette gjør vi vanligvis i en pipe, altså %>%.

Som oftest er det greit å bare beholde NA og fjerne dem når vi trenger det (f.eks. i en regresjonsmodell, som vi skal se på senere). Prøv å lage et nytt datasett, NO8NA, hvor du har fjernet alleNA. Om du ikke skriver noe i parantesene fjerner du alle rader med minst en NA. Hvor mange har du igjen?

NO8NA <- NO8 %>%
  drop_na()
nrow(NO8NA)
Fjerne NA

Manglende verdier og funksjoner

Vi har kort vært inne på at man noen ganger må spesifiserer na.rm = TRUE når man bruker funksjoner til å gjøre utregninger, f.eks. mean()-funksjonen. Grunnen til dette er at man må fortelle funksjonen hvordan man ønsker at den skal håndtere manglende verdier. Funksjoner som har argumentet na.rm ofte ha default som na.rm = FALSE, og da vil ikke funksjonen klare å gjøre utregninger dersom et objekt har manglende verdier.

# Prøver å regne ut gjennomsnittet av variabelen vote i datasettet NO8: 
mean(NO8$vote)
## [1] NA

Her får vi beskjed om at svaret er NA. Da vet vi at det er manglende verdier i variabelen vote og at vi må ta med argumentet na.rm = TRUE for å fortelle funksjonen at den skal ignorere manglende verdier og gjøre utregningen på observasjonene vi har informasjon på.

# Regner ut gjennomsnittet av variabelen vote i datasettet NO8 etter å ha tatt med argumentet na.rm = TRUE
mean(NO8$vote, na.rm = TRUE)
## [1] 1.334848

Univariat analyse

Statistiske mål forteller oss noe om fordelingen til ulike variabler, som foreksempel gjennomsnitt, median og standardavvik, men også minimum- ogmaksimumverdier, typetall og frekvens. Statistiske mål på sentraltendens ergjennomsnitt, median og modus. Statistiske mål på spredning i dataene er standardavviket og varians.

Fra tidligere har vi sett på summary(),og funksjoner som mean() og sd() for å finne frem f.eks. gjennomsnitt, minimums- og maksimumsverdier, og standardavvik. Her skal vi begynne med å se litt videre på univariat statistikk.

Når vi kun har en variabel vi vil beskrive, har vi å gjøre med univariate fordelinger. Da blir vi kjent med variablene hver for seg. En univariat fordeling gir oss informasjon om hvordan observasjonene fordeler seg på en variabels ulike verdier. Igjen gir summary()-funksjonen en rask oversikt over statistiske mål og deskriptiv statistikk. Det er her nyttig å gjøre seg godt kjent med de ulike statistiske målene. Men den univariate analysen kan ta ting et skritt videre, med for eksempel tabeller og histogrammer.

Kategoriske variabler

For kategoriske variabler, på nominalnivå eller ordinalnivå, kan vi bruke frekvenstabeller for å beskrive dataene med tall, og kake- og søylediagram for å beskrive dataene grafisk. For å lage en frekevenstabell kan vi bruke table()-funksjonen. Se om du kan bruke denne på vote-variabelen.
table(NO8$vote)

Disse viser den absolutte fordelingen, altså totalt antall observasjoner for hver verdi. Vi kan også få den relative fordelingen mellom kategoriene, som viser prosentvis fordeling. Vi bruker prop.table()-funksjonen.

prop.table(table(NO8$vote))

Det er alltid et poeng å lage grafer og figurer for å beskrive dataen. Det gir nemlig et godt visuelt og mer intutitvt inntrykk av dataene. For kategoriske variabler kan vi lage kake- og søylediagram for å beskrive frekvensfordelingene til variablene.

For å få søylediagram bruker vi ggplot-funksjonen som er i pakken tidyverse. Oppsettet for hvordan å lage et plot har vi sett på før, se om du kan få denne koden til å vise et søylediagram.

ggplot(NO8, aes(vote)) 
ggplot(NO8, aes(vote)) +
  geom_bar()

Kontinuerlige variabler

For kontinuerlige variabler, på intervall- og forholdstallsnivå, kan vi også bruke frekvenstabeller. Dersom vi lager en frekvenstabell for alder, må vi omkode den til kategorier ved hjelp av cut()-funksjonen. Her setter vi inn ved hvilke verdier vi ønsker å skape en ny kategori, f.eks. kan vi ha alle under 20 i en gruppe, så alle mellom 20 og 30, etc. Da ville vi kjørt denne koden:

NO8 <- NO8 %>%
  mutate(alder_grupper = cut(Age, breaks = c(0,20, 30, 40, 50, 60, 70,100)) )
Kan du bruke table() for å se hvor mange som er mellom 30 og 40 år?
table(NO8$alder_grupper)
Alder i grupper

Grafiske fremstillinger er også nyttig med kontinuerlige variabler. Da kan vi blant annet bruke histogrammer. Også her må vi dele opp i kategorier. Vi bruker ggplot, men endrer geom. Legg merke til argumentet bins – dette bestemmer hvor mange søyler vi ønsker. Prøv å endre argumentet å se hva som skjer.

ggplot(NO8, aes(Age)) +
  geom_histogram(bins = 20,
                 fill = "#F256F4",
                 colour = "white") +
  theme_classic()

Bivariat analyse

Bivariat analyse brukes når man analyserer to variabler. Bivariat analyse er nyttig for å få oversikt over sammenhengen mellom to variabler, i tillegg til at det forteller oss noe om hvor mye to variabler korrelerer, altså hvor mye de henger sammen. Bivariat statistikk er også nyttig for å teste korrelasjonens statistiske signifikans

Dersom vi har to kategoriske variabler vi ønsker å sammenlikne, kan vi presentere dem i en krysstabell. Ta bruker vi funksjonen table(). Prøv å lage en krysstabell mellom alder_grupper, og vote.

Hint: Du kan ha begge variablene i samme table() funksjon

table(NO8$alder_grupper, NO8$vote)

Kjikvadrattest

Kjikvadrattesten tester sammenhengen mellom to kategoriske variabler. Den sammenlikner krysstabellen vi har, men en hypotetisk tabell fra et annet utvalg der det ikke er noen sammeheng mellom variablene. Så tester den sannsynligheten for at tabellen vår er generert ved en tilfeldighet. Vi bruker funksjonen chisq.test(). For å gjøre dette må vi først lagre tabellen vår som et objekt, her er det gjort for dere med navnet AlderStemme. Prøv å kjøre en kjikvadrattest på denne.

chisq.test(AlderStemme)
Kjikvadrattest

Vi kan lage søylediagrammer for å presentere sammenhengen grafisk. Igjen, det er alltid lurt, også for deg selv. Det er mer intuitivt å tolke, og lettere å se sammenhenger raskt. For å gjøre dette må du finne en måte å vise frem aldersgruppene på i grafen. Dette kan du gjøre ved å sette fill = alder_gruppersom et nytt argument i aes() I koden vil du også se at det står position = "dodge", dette gjør vi for at søylene skal komme opp ved siden av hverandre.

ggplot(NO8, aes(vote)) +
  geom_bar(position = "dodge",
                 colour = "white") +
  theme_classic()
ggplot(NO8, aes(vote, fill = alder_grupper)) +
  geom_bar(position = "dodge",
                 colour = "white") +
  theme_classic()

T-test

Om vi har variabler på interval- eller forholdstallsnivå kan vi bruke en t-test for å se om det er en forskjell i gjennomsnittet av de to variablene. Denne testen vil dermed kunne si noe om hvorvidt de to utvalgene kommer fra den samme populasjonen, eller om det er en signifikant forskjell mellom dem.

Her skal vi se hvorvidt det er en signifikant forskjell i tilliten til politiet avhengig av hvor mye tid en bruker på nyheter hver dag. Vi starter med å lage to nye datasett; ett for de som bruker mer tid på nyheter enn gjennomsnittet, og ett for de som bruker mindre.

Først kan du lage et datasett NO8_High for de som bruker mer tid på nyheter enn gjennomsnittet.
NO8_High <- NO8 %>% 
NO8_High <- NO8 %>% 
  filter()
NO8_High <- NO8 %>% 
  filter(Time_News > mean())
NO8_High <- NO8 %>% 
  filter(Time_News > mean(Time_News, na.rm = TRUE))

Nå som vi har dette må vi lage et nytt datasett som er det motsatte, altså de som bruker mindre tid på nyheter enn gjennomsnittet. Det kan du kalle NO8_Low.

NO8_Low <- NO8 %>% 
  filter(Time_News < mean(Time_News, na.rm = TRUE))

Nå har vi (endelig) alt vi trenger for å gjennomføre en t-test. Det vi vil vite her er altså hvorvidt det er en forskjell i tillit til politiet avhengig av om respondenten bruker mer eller mindre tid på nyheter enn gjennomsnittet. Vår nullhypotese er at det ikke er en forskjell, og om vi velger å forkaste denne betyr det at vi tror at en av gruppene har et signifikant annerledes gjennomsnitt fra den andre.

For å gjøre dette bruker vi t.test() funksjonen. Her må du skrive inn de to variablene. Variabelen for tillit til politiet heter Trust_Police.
t.test()
t.test(NO8_High$Trust_Police,)
t.test(NO8_High$Trust_Police, NO8_Low$Trust_Police)
T-test

Korrelasjon

Vi avslutter med bivariat analyse med to kontinuerlige variabler. (Dette er en forsmak på bivariat regresjonsanalyse.) Hensikten med dette er å beskrive korrelasjonen mellom variablene. Vi kan beskrive denne sammenhengen med Pearsons r og teste om korrelasjonen er statistisk signifikant.

Pearsons r beskriver styrken og retningen til korrelasjonen mellom to variabler. Den varierer fra -1 (negativ sammenheng) til 1 (positiv sammenheng). 0 indikerer ingen sammenheng.

La oss teste med alder og tid brukt på nyheter (Time_News) . Sistnevnte viser minutter pr døgn. Her må vi ha kontinuerlige variabler, så vi må bruke Age variabelen for alder. For å gjøre dette kan du bruke cor(). Når vi bruker denne kommer vi derimot til å få et problem vi nevnte istad med NA. Om vi bare kjører cor()funksjonen vil vi bare få NA som svar om det er minst en NA i variablene. Etter å ha skrevet inn variablene vi skal bruke må vi derfor legge til et use = argument.

Her kan du prøve å legge til use = "complete.obs" etter navnet på de to variablene i funksjonen cor. Da bruker du det som kalles “list-wise deletion”, og bare fjerner alt som er NA fra analysen.
cor(NO8$Age, NO8$Time_News, use = "complete.obs")

Punktdiagrammer egner seg godt for å grafisk fremstille sammenhengen mellom to kontinuerlige variabler. Den viser hvor hver respondent (observasjonsenhet) plasserer seg på x-aksen og y-aksen. For å gjøre dette må du bruke geom_point.

Prøv å lage et punktdiagram for variablene Age og Time_News.
ggplot(NO8, aes(Age,Time_News))
ggplot(NO8, aes(Age,Time_News)) +
  geom_point()

Nå som vi har et punktdiagramm er det ofte lurt å legge til en linje som viser korellasjonen mellom variablene. Denne kan vi legge til gjennom geom_smooth(method = "lm"). Metodeargumentet legger vi til for å si at vi ønsker å se en linær sammenheng.

Prøv å legg til argumentet geom_smooth(method = "lm") på punktdiagrammet, vi lagde over. Ser du sammenhengen mellom linjen og Pearsons r som vi regnet ut istad?
ggplot(NO8, aes(Age,Time_News)) +
  geom_point()
ggplot(NO8, aes(Age,Time_News)) +
  geom_point() +
  geom_smooth(method = "lm")

Arbeidsbok 4: Statistisk analyse

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

30/01/2024