#install.packages("openxlsx") # Kommentera bort denna rad om du redan har openxlsx installerat från Lab 1
#install.packages("mosaic") # Kommentera bort denna rad efter att du kört Quarto-filen första gången
library(openxlsx)
library(mosaic)
Introduktion
I den här datorlabben kommer vi att titta på hur fördelningar för olika typer av variabler kan beskrivas numeriskt och grafiskt.
💪 Uppgift 0.1
Skapa en mapp Lab2
i din kursmapp SDA1 (från Lab 1). Ladda ner Quarto-filen för denna lab genom att högerklicka här och välj ‘Spara länk’ eller något likande från menyn som dyker upp. Spara filen i din nya Lab2
mapp. Öppna Quarto-filen i RStudio. Du kan nu fortsätta med denna laboration direkt i Quarto-dokumentet, där du också fyller i svaren på dina laborationsövningar. Du kan alltså lämna den här webbsidan nu och fortsätta arbetet i RStudio.
Väl inne i RStudio med öppnat Quarto-dokument i ‘Editor’ kan ni gå över till ‘Source mode’ genom att klicka på ‘Source’ i det vänstra hörnet av din ‘Editor’. Source mode är detaljerat och bra att skriva kod i eftersom man har full kontroll på dokumentet, men det är svårt att få en översikt av dokumentet. Prova nu att gå över till ‘Visual mode’ genom att klicka på ‘Visual’ i det vänstra hörnet av din ‘Editor’. Vi rekommenderar att ni mestadels arbetar i Visual mode, men att gå över till Source mode när man verkligen få till någon detalj som är svår att ändra i Visual mode. ´
💪 Uppgift 0.2
Klicka på knappen Render i Editor-fönstret för att kompilera filen till en webbsida (html). Webbsidan kommer antingen att visas i Viewer-fönstret i RStudio eller i webbläsaren på din dator. Om din webbsida visas i webbläsaren rekommenderar vi att du ändrar inställningarna i RStudio så webbsidan visas i Viewer-fönstret. Du ställer in detta på menyn Tools/Global Options… och sen väljer du Viewer Pane vid Show output preview in:
💪 Uppgift 0.3
Quarto säkerställer att man befinner sig i korrekt arbetsmapp när koden i dokumentet exekveras. Med korrekt arbetsmapp menas den mappen ni sparade .qmd
filen i. Vill du komma åt dataseten via load()
kommandot måste dataseten vara sparade i samma mapp.
Ett vanligt arbetssätt är att man jobbar i RStudio i en separat .R
fil, där man kan testa att köra kod innan den kopieras över till Quarto dokumentet. Den .R
filen kommer inte att ha samma ‘working directory’ som Quarto filen. Du måste då använda setwd()
funktionen i .R
filen för att ställa in ‘working directory’. Notera att man också välja att skriva kod i Console
som finns längst ner i RStudio. Där måste du också ställa in rätt ‘working directory’. Det är inte rekommenderat att använda Console
eftersom koden inte sparas där. Du kanske kommer på något jättesmart som du glömmer att kopiera över till Quarto dokumentet och kan senare inte hitta det du skrev.
Skapa en ny .R
som du döper till Lab2_test_code.R
och sparar i din Lab 2
mapp. Ställ in ‘working directory’ till den nya mappen genom att följa anvisningarna från Lab 1.
💪 Uppgift 0.4
Många intressanta dataset finns tillgängliga på webben. Kursboken har gjort ca 500 av dataseten tillgängliga här. Ni kommer att jobba med titanic
datasetet som finns i Chapter 3. Ladda ner den zip-filen samt packa upp/extrahera filen genom att klicka på den och välj ‘Extrahera’ eller något liknande. Du kan extrahera filerna på datorns Skrivbord eller annan mapp. Om du går in i den extraherade mappen Ch3
så finns där filen Chapter_3.xlsx
. Kopiera den filen till din Lab2
mapp. Vi kommer snart att läsa in datasetet.
1. Skapa tabeller för kategoriska variabler
En kategorisk variabel är en variabel vars utfall är kategorier. En kategorisk variabel kan antingen vara på nominalskala eller ordinalskala. Den vanligaste typen är nominalskala, vilket innebär att utfallen saknar en naturlig rangordning. Ett exempel är kön, där man inte kan rangordna utfallen på ett meningsfullt sätt. För en kategorisk variabel på ordinalskala så gäller det att utfallen har en naturlig rangordning. Ett exempel är betyg, där till exempel betyg A är bättre än betyg C. Än så länge behöver vi inte oroa oss för om en kategorisk variabel är på ordinalskala eller nominalskala. Vi använder en tabell för att representera dess fördelning i bägge fallen.
Först ska vi installera och ladda paketen openxlsx
för att läsa in data från Excelfil och mosaic
för dataanalys.
Vi kan nu läsa in datamaterialet som finns i fliken Titanic
i den Excelfil Chapter_3.xls
ni laddade ner ovan:
= read.xlsx("https://github.com/StatisticsSU/SDA1/raw/main/datorlab/lab2/Chapter_3.xlsx", sheet = "Titanic") titanic
💪 Uppgift 1.1
Ändra koden ovan så read.xlsx()
istället läser in filen ‘Chapter_3.xlsx’ från din dator.
Vi kan ta titt på de första observationerna genom att använda funktionen head()
. Vi kan också lista de första observationerna för varje variabel i datasetet genom att använda funktionen str()
:
head(titanic)
Name Survived Boarded Class MWC Age
1 ABBING, Mr Anthony Dead Southampton 3 Man 42
2 ABBOTT, Mr Ernest Owen Dead Southampton Crew Man 21
3 ABBOTT, Mr Eugene Joseph Dead Southampton 3 Child 14
4 ABBOTT, Mr Rossmore Edward Dead Southampton 3 Man 16
5 ABBOTT, Mrs Rhoda Mary 'Rosa' Alive Southampton 3 Woman 39
6 ABELSETH, Miss Karen Marie Alive Southampton 3 Woman 16
Adut_or_Chld Sex Paid Ticket_No Boat_or_Body Job
1 Adult Male 7.55 5547 <NA> Blacksmith
2 Adult Male NA <NA> <NA> Lounge Pantry Steward
3 Child Male 20.25 CA2673 <NA> Scholar
4 Adult Male 20.25 CA2673 [190] Jeweller
5 Adult Female 20.25 CA2673 A <NA>
6 Adult Female 7.65 348125 16 <NA>
Class_Dept Class_Full
1 3rd Class Passenger 3
2 Victualling Crew V
3 3rd Class Passenger 3
4 3rd Class Passenger 3
5 3rd Class Passenger 3
6 3rd Class Passenger 3
str(titanic)
'data.frame': 2208 obs. of 14 variables:
$ Name : chr "ABBING, Mr Anthony" "ABBOTT, Mr Ernest Owen" "ABBOTT, Mr Eugene Joseph" "ABBOTT, Mr Rossmore Edward" ...
$ Survived : chr "Dead" "Dead" "Dead" "Dead" ...
$ Boarded : chr "Southampton" "Southampton" "Southampton" "Southampton" ...
$ Class : chr "3" "Crew" "3" "3" ...
$ MWC : chr "Man" "Man" "Child" "Man" ...
$ Age : num 42 21 14 16 39 16 25 30 28 20 ...
$ Adut_or_Chld: chr "Adult" "Adult" "Child" "Adult" ...
$ Sex : chr "Male" "Male" "Male" "Male" ...
$ Paid : num 7.55 NA 20.25 20.25 20.25 ...
$ Ticket_No : chr "5547" NA "CA2673" "CA2673" ...
$ Boat_or_Body: chr NA NA NA "[190]" ...
$ Job : chr "Blacksmith" "Lounge Pantry Steward" "Scholar" "Jeweller" ...
$ Class_Dept : chr "3rd Class Passenger" "Victualling Crew" "3rd Class Passenger" "3rd Class Passenger" ...
$ Class_Full : chr "3" "V" "3" "3" ...
Verkar variablerna vara definierade som de ska?
Låt oss undersöka variabeln Survived
i datasetet. Detta är en kategorisk variabel med två kategorier Dead
och Alive
. När en variabel bara har två kategorier brukar man också säga binär variabel. Man kan räkna antalet observationer som tillfaller varje kategori och på så sätt skapa en frekvenstabell med funktionen tally()
i mosaic
-paketet enligt nedan.
tally(~ Survived, data = titanic)
Survived
Alive Dead
712 1496
Tilde-tecknet ~
används i mosaic
-paketet och är en del av formula-syntax dialekten i R som omnämndes i Lab 1. I det här fallet talar tecknet ~
om för R att variabeln Survived
ska hämtas från datamaterialet titanic. Annars skulle vi ju vara tvungna att skriva titanic$Survived (kom ihåg från Lab 1 att $-tecknet säger åt R att ‘plocka ut variabeln Survived från datamaterialet titanic’). Så blir man t ex tvungen att skriva i dialekten base-R (klicka i marginalen om du är intresserad). Fördelen med mosaic’s formula-syntax kommer bli ännu tydligare när vi har många fler variabler att jobba med.
Lägg märke till att frekvenstabellen inte är sparad. Detta är bara ett kommando som ofta också duger gott och väl. Men ibland vill man också spara en tabell under sin session. Det kan göras genom att skapa ett passande variabelnamn och tilldela den nya variabeln värdet vi fick ovan (namnet på variabeln kan man välja som man vill):
<- tally(~ Survived, data = titanic) tab_survived
Ibland kan det vara svårt att titta på antalet inom varje kategori och jämföra siffrorna sinsemellan. Att titta på relativa frekvenser istället gör ofta jämförelserna mycket enklare att uppfatta. Genom att lägga till argumentet format = proportion
i tally()
räknas de relativa frekvenserna istället.
tally(~ Survived, data = titanic, format = "proportion")
Survived
Alive Dead
0.3224638 0.6775362
Vill man ha detta presenterat i procent kan man enkelt skriva format = percent
istället för proportion
tally(~ Survived, data = titanic, format = "percent")
Survived
Alive Dead
32.24638 67.75362
Alltså överlevde endast 32.2% av de som befann sig på Titanic, medan 67.8% dog.
💪 Uppgift 1.1
Variabeln Class
talar om biljettklass passageraren reste med (1:a, 2:a, 3:e eller Crew (besättning)). Presentera det totala antalet inom varje biljettklass. Vilken kategori är störst?
# Write your code here
💪 Uppgift 1.2
Beräkna den relativa frekvensen (i procent) inom varje biljettklass.
# Write your code here
2. Grafisk illustration av kategoriska variabler
För att presentera kategoriska variabler grafiskt används oftast pajdiagram (pie charts) eller stapeldiagram (bar charts). Oftast räcker det med att använda sig av ett av dessa diagram i sin presentation. I R kan man använda sig av funktionerna pie()
och bargraph()
för respektive diagram. Det går då smidigt att använda sig av en sparad tabell som argument i funktionen.
= tally(~ Survived, data = titanic, format = "proportion")
table_rel_freq pie(x = table_rel_freq)
Ovan ser vi att vi först har sparat de relativa frekvenserna bland de som överlevde och de som dog i en tabell table_rel_freq
. Detta är inte nödvändigt för att skapa ett pajdiagram. Men eftersom siffrorna redan finns i tabellen så kan man lika gärna använda sig av dem. Ett annat alternativ hade varit att skapa en vektor och manuellt skriva in värden för de olika kategorierna exempelvis likt: relative_frequencies = c(0.32, 0.68)
Grafen ovan är dock inte så informativ. Det finns generellt många argument man kan använda sig av i R för att göra sina grafer så informativa som möjligt. Koden nedan är ett exempel på hur man kan gå tillväga
= round(table_rel_freq, 2) # round the numbers to two decimals
rel_frequencies rel_frequencies
Survived
Alive Dead
0.32 0.68
= names(table_rel_freq)
category_names category_names
[1] "Alive" "Dead"
= c("lightblue", "purple")
colors pie(x = table_rel_freq, labels = rel_frequencies, col = colors)
legend("topright", legend = category_names, fill = colors)
Funktionen round()
används för att avrunda till önskat antal decimaler, i detta fall två så att grafen blir mer lättläslig.
Funktionen names()
som användes i Datorlaboration 1 för att få ut kolumnnamn från dataframes kan även här används för att få ut kolumnnamn från tabeller. Återigen är denna funktion inte nödvändig för att bilda ett pajdiagram, men den kan utnyttjas för att ge passande etiketter för olika kategorier.
Man kan även specificera färgerna på pajbitarna. Det finns väldigt många färger i R och man kan specificera dem antingen med text eller med siffror. Använder man sig av text är stavningen viktig. Generellt används då endast gemener (små bokstäver).
I funktionen pie()
läggs de olika argumenten in för att bilda ett pajdiagram. Det första argumentet kommer att avgöra hur stora pajbitarna blir. Det andra argumentet markerar endast etiketterna bredvid varje pajbit (i detta fall hur stora andelar det finns i varje kategori) och det tredje argumentet col
bestämmer färgen i själva grafen.
Nedanför det används även funktionen legend()
som flitigt kan användas då man vill rita flera olika variabler eller flera olika kategorier. Det första argumentet säger var man vill placera etiketterna för de olika kategorierna (i detta fall högst upp till höger). Det andra argumentet säger vilka namn man vill ha på dessa etiketter (category_names
används här) och det tredje argumentet säger till vilka färger man vill ha. Det är då viktigt att man använder sig av samma färger som man använde sig av i pie()
funktionen ovan och att färgerna också kommer i samma ordning som ovan.
💪 Uppgift 2.1
Skapa ett pajdiagram av variabeln Class
i titanic. Använd dig gärna av uträkningarna från Uppgift 1.2 för att skapa grafen. Välj själv om du vill illustrera det som andelar eller i procent.
# Write your code here
💪 Uppgift 2.2
Vad är det för fel på denna graf?
= c(0.1, 0.9)
rel_frequencies = names(table_rel_freq)
category_names = c("lightblue", "purple")
colors pie(x = table_rel_freq, labels = rel_frequencies, col = colors)
legend("topright", legend = category_names, fill = colors)
Nedan syns ett exempel på hur man kan använda sig av stapeldiagram. Detta görs enklast med funktionen bargraph()
, som liknar tally()
funktionen i och med att den börjar med ett ~
tecken följt av variabeln som vi vill rita och sedan datasetet det kommer ifrån. Lägg dock märke till att istället för att skriva format = proportion
skriver man type = proportion
om man vill visa staplarna som relativa frekvenser.
bargraph(~ Survived, data = titanic, type = "proportion")
# bargraph(~ titanic$Survived, type = "proportion") # without dataframe format
Men detta diagram säger kanske inte allt om det vi tittar på. I vilket sammanhang är “Alive” och “Dead” tagit ifrån? Det finns ingen rubrik! Man skulle kanske även vilja justera sin y-axel, antingen så att den blir lite kortare eller lite längre.
Först kan man börja med att skapa en rubrik för sin graf. Detta görs nedan genom att skapa en ny variabel my_title
som är en textsträng. Sedan kan man även definiera passande namn för både x-axeln och y-axeln, dessa är också textsträngar.
För att justera längden på y-axeln kan man skapa en vektor med passande värden. Här används en vektor med namnet length_y_axis
som börjar på 0 och slutar på 0.75. Man kan även justera så att staplarna får valfria färger.
Sedan kan man enkelt sätta in argumenten i bargraph()
funktionen till dessa värden:
= "Figur 1: Relative frequency of Survival on the Titanic"
my_title = "Survival"
x_axis_title = "Frequency"
y_axis_title = c(0, 0.80)
length_y_axis = c("lightblue", "purple")
colors
bargraph(~ Survived, data = titanic, type = "proportion", main = my_title,
xlab = x_axis_title, ylab = y_axis_title, ylim = length_y_axis, col = colors)
När man skriver en Quarto-rapport är det inte så bra att skriva in figur-numret i själva grafen, dvs Figur 1, som vi skrev ovan. Problemet med det är att om man sen lägger in en graf mellan två grafer så måste man gå in och ändra alla figurers numrering. Om vi sen även har hänvisat till en figur i texten (t ex, se Figur 1 för en trevlig plott) så måste vi också ändra numret där. Men vi kan lösa detta genom att låta Quarto hålla koll på figurernas numrering. Så här:
= "Survival"
x_axis_title = "Frequency"
y_axis_title = c(0, 0.80)
length_y_axis = c("lightblue", "purple")
colors
bargraph(~ Survived, data = titanic, type = "proportion",
xlab = x_axis_title, ylab = y_axis_title, ylim = length_y_axis, col = colors)
Man kan nämligen ge lite extra kommandon i varje code-chunk genom att använda tecknet #|
(uttalas hash-pipe, du kommer ihåg det genom denna Weezer-video). I det här fallet använde vi nyckelordet label
för att ge figuren namnet fig-andelar och nyckelordet fig-cap för att ange texten till figuren. Notera att vi också tog bort argumentet main = my_title
eftersom titel inte längre behövs i själva grafen. Vi kan nu hänvisa till figuren i texten med hjälp av @-tecknet (notera att du också kan klicka för transportera dig till figuren!): Se Figur 1 för en trevlig plott.
💪 Uppgift 2.3
Justera diagrammet nedan så att allt stämmer och så att det ser mer presentabelt ut. Byt också ut färgerna mot två andra bland R’s standardfärger.
= "Survival"
x_axis_title = "Frequency"
y_axis_title = c(0, 0.1)
length_y_axis
bargraph(~ Survived, data = titanic, type = "proportion",
xlab = x_axis_title, ylab = y_axis_title, ylim = length_y_axis, col = colors)
💪 Uppgift 2.4
Kan du se något ovanligt med stapeldiagrammet nedan? Rätta till det.
= "Survival"
x_axis_title = "Relative frequency"
y_axis_title
bargraph(~ Survived, data = titanic, type = "count",
xlab = x_axis_title, ylab = y_axis_title, col = colors)
💪 Uppgift 2.5
Skapa ett stapeldiagram med funktionen bargraph()
för variabeln Class
i titanic. Använd relativa frekvenser denna gång.
# Write your code here
3. Dataset som består av saknade värden
Låt oss titta närmare på variabeln Age
(ålder) i datasetet titanic
. Denna variabel har en del saknade värden och vissa standard-funktioner i R är känsliga för sådana. Man kan enkelt se om en variabel har saknade värden genom att använda summary()
funktionen, som räknar ute lite sammanfattningsmått (mer om det senare) för variablerna i datamaterialet. R skriver NA (Not Available) eller (NaN) (Not A Number) för saknade värden, och vi kan se att variabeln Age
har 3 st saknade värden (NA's :3
):
summary(titanic)
Name Survived Boarded Class
Length:2208 Length:2208 Length:2208 Length:2208
Class :character Class :character Class :character Class :character
Mode :character Mode :character Mode :character Mode :character
MWC Age Adut_or_Chld Sex
Length:2208 Min. : 0.08 Length:2208 Length:2208
Class :character 1st Qu.:22.00 Class :character Class :character
Mode :character Median :29.00 Mode :character Mode :character
Mean :30.15
3rd Qu.:37.00
Max. :74.00
NA's :3
Paid Ticket_No Boat_or_Body Job
Min. : 0.000 Length:2208 Length:2208 Length:2208
1st Qu.: 7.896 Class :character Class :character Class :character
Median : 14.400 Mode :character Mode :character Mode :character
Mean : 33.010
3rd Qu.: 31.000
Max. :512.329
NA's :890
Class_Dept Class_Full
Length:2208 Length:2208
Class :character Class :character
Mode :character Mode :character
Det finns olika sätt att hantera saknade värden. Många funktioner kan hantera uträkningar för variabler med saknade värden om man specificerar det i funktionen. I detta fall är vi bara intresserade av en variabel och inte hela datasetet så vi kommer att ta bort de observationer som har saknade värden. Men i vanliga fall måste man tänka efter innan man tar bort sådana observationer, speciellt om man tittar på flera variabler samtidigt. Det finns mer att säga om att bara ta bort saknade värden när vi kommer till den statistiska analysen.
Funktionen na.omit()
tar bort alla observationer som har NA
eller NaN
, dvs saknade värden.
length(titanic$Age) # number of observations originally
[1] 2208
= na.omit(titanic$Age)
Age length(Age) # the number of observations when missing values are removed
[1] 2205
💪 Uppgift 3.1
Definiera en ny variabel Paid
från kolumnen Paid
i datasetet titanic
på liknande sätt som ovan. Rensa bort eventuella saknade värden med funktionen na.omit()
.
# Write your code here
4. Grafisk presentation av numeriska variabler
Numeriska variabler är sådana som naturligt består av numeriska värden. Numeriska variabler kan ha olika skaltyper. Numeriska variabler innehåller rikare information än kategoriska variabler, där man kan få ut mer information både numeriskt och grafiskt. En numerisk variabel kan alltid kodas om till en kategorisk variabel (en variabel på en lägre skalnivå) men det omvända gäller inte.
Att illustrera numeriska variabler grafiskt är betydelsefullt för att upptäcka ifall en fördelning har avvikande värden (så kallade outliers), eller om fördelningen ser symmetrisk eller skev ut, men också för att upptäcka om det är en unimodal eller multimodal fördelning. Vid de två senare fallen är histogram och täthetsplot särskilt användbara.
De vanligaste graferna för numeriska variabler är histogram och låddiagram, s.k. boxplots. Ni kommer lära er att plotta låddiagram i Datorlaboration 3 efter att ni gått igenom dom på Föreläsning 5. En täthetsplot är en utjämnad version av ett histogram.
Histogram kan ritas med hjälp av funktionen histogram()
som finns i mosaic
paketet, eller med funktionen hist()
som inte kräver något paket. Båda har sina fördelar, där histogram
är mer smidig när man vill rita flera histogram samtidigt (mer om detta i Datorlaboration 3). Här är ett exempel med funktionen histogram()
:
histogram(~ Age, data = titanic, col = "navyblue")
Fördelningen är inte symmetrisk här utan snarare skev åt höger, dvs. det finns en lång högersvans. Men det finns även en hel del observationer bestående av barn under fem år. Eftersom fördelningen är skev är det svårare att gissa sig till medelvärdet. De flesta individerna verkar dock ha varit mellan 15-45 år.
Argumentet breaks =
kan användas inuti funktionen histogram()
för att ange hur många staplar man vill ha. R kommer då i så hög mån som möjligt rita ett histogram med så många staplar.
Ett histograms utseende beror på antalet staplar man väljer. En täthetsplot är ett sätt att plotta fördelningen av data som inte beror på antalet staplar. En täthetsplot kan ritas med hjälp av funktionen densityplot()
som finns i mosaic
paketet.
densityplot(~ Age, data = titanic, col = "navyblue")
💪 Uppgift 4.1
Rita ett histogram likt ovan, med samma variabel men med en annan färg. Testa dig fram med breaks
argumentet tills du hittar vad du tycker är ett passande antal staplar. Rita sedan ett till likadant histogram men använd dig av Sturges regel denna gång för att bestämma hur många staplar som ska användas. Ser histogrammet bättre ut än det du ritade utan Sturges regel?
# Write your code here
Använd listan i Appendix för olika argument som kan användas i grafer för att göra dem mer informativa.
💪 Uppgift 4.2
Rita ett histogram över variabeln Paid
.
# Write your code here
💪 Uppgift 4.3
Vilket mått av medelvärdet eller medianen beskriver centralpunkten i fördelningen för Paid
bäst?
💪 Uppgift 4.4
Rita täthetsplottar för variablerna Age
och Paid
.
# Write your code here
5. Numerisk beskrivning av kvantitiva variabler
Om man använder sig av en frekvenstabell för en numerisk variabel riskerar man i värsta fall att få en tabell som är lika lång som antal observationer man har. Kanske har man inte ens ett enda fall där två olika observationer har samma värden. Därför används ofta andra beskrivande mått. Bland de viktigaste är lägesmåtten som fångar fördelningens mittpunkt
- medelvärde
- median
och spridningsmåtten som mäter variationen kring fördelningens mittpunkt:
- varians
- standardavvikelse
- variationsbredd (
range
på engelska: skillnaden mellan maximum och minimumvärdet) - Interkvartila avståndet (IQR).
Funktionen favstats()
i mosaic
-paketet beräknar dessa mått:
favstats(~ Age, data = titanic)
min Q1 median Q3 max mean sd n missing
0.08 22 29 37 74 30.14689 11.97386 2205 3
Funktionen räknar ut olika fördelningsmått, såsom minimumvärdet, maximumvärdet, första och tredje kvartilen samt medelvärdet och medianen. Både medelvärdet och medianen är mått på en fördelnings mittpunkt men hur lämpliga de är som mått beror på fördelningens utseende. Vi ser även att funktionen också skriver ut hur många värden datasetet består av och antalet saknade värden.
Ibland vill man dock inte skriva ut all denna information för en variabel. I Datorlaboration 1 använde vi oss av funktionen mean()
för att räkna ut medelvärdet av en variabel. Några andra vanliga funktioner utöver dessa är var()
och sd()
. Matematiskt motvaras dessa tre funktioner av: \[\begin{align}\nonumber
\overline{y}= \frac{1}{n} \sum_{i=1}^n y_i \\ \nonumber
s^2 =\frac{\sum_{i=1}^n(y_i-\overline{y})^2}{n-1}
\end{align}\] och \[\begin{align}
s = \sqrt{s^2}
\end{align}\]
💪 Uppgift 5.1
Använd funktionerna ovan för att räkna ut medelvärdet, variansen och standardavvikelsen för variabeln Age
. Kan man räkna ut standardavvikelsen på något annat sätt i R?
# Write your code here
💪 Uppgift 5.2
Räkna ut det variationsbredden samt det interkvartila avståndet av variabeln Age
från utskriften vi fick från funktionen favstats()
.
# Write your code here
6. Indexering och upprepning (loopar)
Låt oss titta på ett dataset över UFC’s top 10 kampsportsutövare i Welterweight klassen bland män (december 2022). Nedan matas värdena in i vektorer och sedan sätts alla variabler ihop i en och samma tabell med funktionen data.frame()
:
# Defining variables:
= c("Kamaru Usman", "Colby Covington", "Khamzat Chimaev", "Belal Muhammed",
Name "Gilbert Burns","Stephen Thompson", "Geoff Neal", "Sean Brady",
"Vicente Luque", "Shavkat Rakhmanov" )
= c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
Rank = c(9, 4, 6, 5, 6, 8, 9, 3, 11, 8)
Wins_by_knockout = c(3.01, 4.05, 3.98, 2.19, 2, 0.27, 0.59, 2.8, 0.51, 2.31)
Takedown_avg = c(35,34,27, 34, 35, 39, 31, 29, 30, 27)
Age_fighters
# Creating a dataframe with all the variables just defined above:
= data.frame(Name, Rank, Wins_by_knockout, Takedown_avg, Age_fighters)
UFC UFC
Name Rank Wins_by_knockout Takedown_avg Age_fighters
1 Kamaru Usman 1 9 3.01 35
2 Colby Covington 2 4 4.05 34
3 Khamzat Chimaev 3 6 3.98 27
4 Belal Muhammed 4 5 2.19 34
5 Gilbert Burns 5 6 2.00 35
6 Stephen Thompson 6 8 0.27 39
7 Geoff Neal 7 9 0.59 31
8 Sean Brady 8 3 2.80 29
9 Vicente Luque 9 11 0.51 30
10 Shavkat Rakhmanov 10 8 2.31 27
Datasetet består av fem stycken variabler och är sorterat efter Rank
. I Lab 1 tittade vi lite på indexering och detta bygger vidare på det. Låt säga att vi vill veta vad åldern är för den 6:e rankade utövaren. I detta fall är datasetet väldigt litet och man kan genast identifiera alla individer. Ibland har vi dataset som är väldigt stora och då kan man behöva använda sig av indexering för att få ut information om en enskild (eller ett fåtal) observationer av intresse. För att ta reda på åldern på den 6:e rankade utövaren kan man då använda sig av koden UFC[6, 5]
. Där siffran till vänster om kommatecknet i hakparantesen anger radtalet och siffran till höger om kommatecknet anger kolumntalet. Detta ger oss svaret 39.
💪 Uppgift 6.1
Använd indexering för att skriva ut hur många wins by knockout Gilbert Burns har haft.
# Write your code here
💪 Uppgift 6.2
Använd indexering för att skriva ut all information om Kamaru Usman (dvs den första raden). [Ledtråd: om man inte skriver något alls efter kommatecknet i indexeringen får man alla värden i den raden]
# Write your code here
💪 Uppgift 6.3
Använd indexering för att skriva ut alla värden för variabeln Takedown_avg
(dvs den 4:e kolumnen).
# Write your code here
En loop kan väldigt kort beskrivas som en procedur som återupprepas så länge ett visst förhållande är uppfyllt. Det finns tre vanliga loopar i R. Dessa är for
-loop, while
-loop och repeat
-loop. De två första är de vanligaste men vi kommer än så länge bara titta på for
-loopen.
Säg att du vill skriva en kod som skriver ut alla tal mellan 1 och 10 på skärmen. Du skulle kunna skriva print(1) följt av print(2) osv, men skulle vara jobbigt. Kan vi få datorn att göra det jobbet åt oss genom att använda en for
-loop? Svar ja. Nedan ges ett exempel på en loop som skriver ut talen mellan 1-10 med hjälp av print()
funktionen. Det är ett exempel på den kanske mest grundläggande loopen, men den illustrerar ändå en viktig princip. För att starta loopen används ordet for
följt av en parentes. Vad som står inom parentesen är väldigt viktigt och det första argumentet är namnet på en så kallad indexvariabel, i detta fall i
. Efter detta specificerar man från vilken siffra i
börjar på samt vilken siffra i
slutar på. Här börjar den på 1 och slutar på 10. Efter parentesen bildar man en ny så kallad klammerparentes (som ser ut som måsvingar). Där inne specificerar man allt som ska hända i varje upprepningen i loopen. I det här exemplet vill vi att loopen ska skriva ut indexnumret, ett i taget:
for (i in 1:10){
print(i)
}
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5
[1] 6
[1] 7
[1] 8
[1] 9
[1] 10
Alltså skriver loopen ut vad i
är under varje iteration (dvs upprepning).
💪 Uppgift 6.4
Använd loopen ovan men byt ut indexvariabeln i
till k
istället. Kör sedan loopen. Vad är det som händer?
# Write your code here
💪 Uppgift 6.5
Använd återigen loopen i exemplet ovan. Men ändra variabeln i
s definitionsmängd från 1:10 till 24:33.
# Write your code here
💪 Uppgift 6.6
Gör på samma vis som i övningen ovan men ändra nu definitionsmängden från 1:10 till -3:5
# Write your code here
Nedan ges ett exempel på en for
-loop som skriver ut namnet på en enskild variabel (Name
) i tur och ordning. Här används indexering av variabeln Name
för att endast ett namn ska skrivas ut i varje iteration, och då i samma ordning som den förekommer i variabeln.
for(i in 1:10){
print(Name[i])
}
[1] "Kamaru Usman"
[1] "Colby Covington"
[1] "Khamzat Chimaev"
[1] "Belal Muhammed"
[1] "Gilbert Burns"
[1] "Stephen Thompson"
[1] "Geoff Neal"
[1] "Sean Brady"
[1] "Vicente Luque"
[1] "Shavkat Rakhmanov"
💪 Uppgift 6.7
Använd en for
-loop för att skriva ut varje värde på variabeln Wins_by_knockout
.
# Write your code here
Den introduktionen till loopar kan räcka för tillfället. Men om du tyckte det var intressant kan du fortsätta läsa lite mer om loopar nedan. Annars kan du hoppas till Sammanfattningen av Lab 2.
Man kan även göra matematiska uträkningar med hjälp av en loop. Låt säga att vi vill räkna ut vad \(2^6\) är (där 2 är basen och 6 är exponenten). Detta kan enkelt göras med den matematiska operationen ^
i R vilket ger oss resultatet 64. Men eftersom vi älskar att loopa så kommer vi också älska följande exempel där vi räknar ut detta värde för hand med en loop.
Först måste man definiera ett startvärde. Detta görs med variabeln myProduct
nedan. Eftersom uträkningen av \(2^6 = 2\cdot 2\cdot 2\cdot 2\cdot 2\cdot 2 = 64\) egentligen bara är multiplikation, måste startvärdet vara like med 1 (används 0 kommer slutresultatet också att bli 0). Därefter kan loopen startas. Den kommer att iterera från värdet 1 till 6 (eftersom exponenten är 6). Efter första iterationen (loop-omgången) kommer myProduct
att vara 1 multiplicerat med 2, dvs 2. Detta värde sparas i myProduct
och syns när man skriver ut resultatet med print(myProduct)
inuti loopen. I den andra iterationen multipliceras myProduct
med 2 igen, och detta värde sparas nu i myProduct
. Resultatet är \(2\cdot2=4\). Den tredje iterationen multipliceras 4 med 2 och myProduct
uppdateras till detta nya värde 8. Denna procedur upprepas tills antal iterationer i
har nått upp till 6 gånger. Därefter avslutas loopen och myProduct
visar då svaret på vad \(2^6\) är:
= 1 # We have to start with 1 here since it's multiplication
myProduct
for (i in 1:6){
= myProduct * 2 # multiplying with 2 in each iteration
myProduct print(myProduct) # prints the result after each iteration
}
[1] 2
[1] 4
[1] 8
[1] 16
[1] 32
[1] 64
# final result myProduct
[1] 64
💪 Uppgift 6.8
Funktionen sum()
i R kan användas för att summera numeriska värden i en vektor. Använd denna funktion för att räkna ut medelvärdet för variabeln Age_fighters
ovan.
# Write your code here
💪 Uppgift 6.9
Använd en for
-loop för att räkna ut medelvärdet för variabeln Age_fighters
.
# Write your code here
7. Sammanfattning
A. Appendix
Lista över några vanliga argument i grafer
col = färg, kan markeras med siffror eller med namnet på färgen, oftast med små bokstäver. Glöm ej att texten måste ligga inom citattecken.
main = rubrik på plotten, detta sätts till en textsträng, alltså en text inom citattecken.
xlab = rubrik på x-axeln, detta sätts till en textsträng, alltså en text inom citattecken.
ylab = rubrik på y-axeln, detta sätts till en textsträng, alltså en text inom citattecken.
xlim = definitionsområde för x-axeln. Exempelvis betyder xlim = c(0, 14.3) att det lägsta värdet som ritas kommer att vara 0 och det högsta värdet kommer att vara 14.3 (på x-axeln).
ylim = definitionsområde för y-axeln. Exempelvis betyder ylim = c(-2, 20.7) att det lägsta värdet som ritas kommer att vara -2 och det högsta värdet kommer att vara 20.7 (på y-axeln).
lwd = tjocklecken på linjer (eller prickar) i ett linjediagram (spridningsdiagram), anges med ett nummer.
lty = typ av linje (rak, streckad, prickad etc) i ett linjediagram, anges med ett nummer.
pch = typ av prick (rund, fyrkantig + * etc), sätts till ett nummer.
breaks = antal staplar i ett histogram.
cex = justering av etiketternas storlek i en figur (exempelvis cex = 0.5 i en
legend()
funktion minskar storleken som “legend-texten” tar upp i en figur med hälften). Finns även exempelvis cex.axis, cex.main för att justera storleken av texter på axlar respektive rubrik.bg = bakgrundsfärg i en figur.
col.main = rubrikens färg.
col.lab = färger för rubrikerna på axlarna.
font = specificerar vilken typ av text man vill ha, exempelvis ger font = 3 kursiv text.