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.
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.
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 NO
på Country
-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)
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 bruketable()
-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)
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)
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_grupper
som 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 datasettNO8_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 vit.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)
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.
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
.
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.
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")