Charlie Lindgren, Doktorand i Mikrodata Analys
5 april 2017
I R kan varierande uppgifter såsom linjär eller icke-linjär modellering, klassiska statistiska test, tidserieanalys samt klassificering och klusteranalys genomföras.
Utöver detta är en av styrkorna i R att kunna hantera vektorer och matrisalgebra.
Ja och nej.
Kan åstadkomma mycket med paketen.
Förinbyggda funktioner för enklare uppgifter.
Inlärningskurva kan vara rätt brant men det lönar sig i slutändan.
Inte alltid tydligt vad som finns tillgängligt (paket och funktioner).
Analys går ned på detaljnivå, istället för vissa program som har funktioner som återger all output.
Mer intimitet med data.
R kan laddas ner och köras direkt men jag och många andra använder R-Studio som ”skal” på grund av dess användbarhet. R-Studio har likt många andra program menyer och gränssnitt där man kan se sina angivna variabler och data.
Ni måste inte använda R-Studio men jag kommer att använda detta ”skal” till R och det är rekommenderat att ni gör detsamma.
Man behöver inte programmera allt i R, mycket har redan gjorts och det är oftast inte klokt att “uppfinna hjulet på nytt” i många avseenden. Då kan man använda färdiga paket.
Koden nedan installerar ett paket, öppnar detta och ger information om detta.
install.packages("car")
library(car)
?car
Samtidigt är det också en dygd att inte förlita sig fullt ut på paket i varje tillfälle då dessa även ger koden ett visst beroende.
Skulle ett paket mot förmodan bli gammalt och ej uppdaterat så skulle koden kunna stå och falla med detta (såvida man inte skriver sin egen kod för ändamålet).
Detta är dock sällan ett problem.
I R-Studio kan ni använda file -> new -> R-script för att öppna ett nytt script att skriva ned er kod i samt spara för framtida användning.
Er “console” till höger kan även användas för att skriva kod i och där kommer även all kod som körs att visas, men det som visas där sparas inte.
Använd ctrl + R (Windows) eller cmd + Enter (Mac) för att köra den kod som är markerad. Att klicka för att köra koden blir väldigt omständigt annars, men går även det.
För den som inte har programmerat förut så kan man kommentera sin text med en “hashtag” eller hashtecken, #. Kommentarer är bra att använda för att beskriva vad koden gör eller namnge delar av sina kod. Detta är både bra för en möjlig utomstående läsare av koden samt för ens egen del då minnet sviker.
# Det här är en kommentar eftersom hashtecknet står framför,
# därför kommer koden aldrig att köras vad som än står bakom tecknet.
R kan enkelt användas för enklare beräkningar, beräkna 3 + 4 nedan.
3 + 4
[1] 7
Vi fortsätter med 3 - 5…
3 - 5
[1] -2
Här nere gick det snett… eller? division med 0 återger “Inf”.
8 / 0
[1] Inf
Vad betyder detta? Antingen skriv ner och vänta så kommer en hjälptext eller ange frågetecken framför och kör koden.
?Inf
Man kan läsa att detta gäller “oändliga” tal, alltså division med noll ger oändligheten. Hjälpfilerna är oerhört… hjälpsamma för att lära sig koda ☺.
Råkar vi skriva fel så hjälper R till att försöka korrigera våra misstag.
8 / / 0
Error: <text>:1:5: unexpected '/'
1: 8 / /
^
Vi har alltså ett oväntat “/” i koden ovan och vi får därmed felmeddelande med förklaring.
Notera: Detta felmeddelande ser något annorlunda mot för presentationens felmeddelande.
Nu fortsätter vi med lite fler räkneoperationer.
5 + 5 / 2
[1] 7.5
Okej, det gick ju bra! Men det var inte det jag var ute efter egentligen. Ville egentligen beräkna
(5 + 5) / 2
[1] 5
Så parantesuträkningen går före divisionen, alltså 10 delat på 2
Exponenter beräknas enligt
5 ^ 2
[1] 25
Ytterligare en artimetisk operator (vilken jag personligen ej har behövt använda) är “modulo” operatorn
5 %% 3
[1] 2
Detta betyder helt enkelt att vid divisionen 5 / 3 så återstår en rest 2 som inte är jämnt delbart med 3.
Beräkna arean av en rektangel med sidorna 2 m och 3 m.
Beräkna arean av en triangel med sidorna 2 m och 3 m.
Beräkna medelvärdet av dessa tre värden: 2, 5, 7.
Kan ni ändra summan av talen i medelvärdet ovan så det blir jämnt delbart med 3?
Vad anger 1 %% 2?
I förgående script så kunde vi utföra enklare uträkningar, men det blir omständigt att skriva hela sin uträkning på en och samma rad. Då är det hjälpsamt att spara variabler för att kunna använda när man vill. R kan göra detta för er och ni kan själva namnge era variabler. I R använder vi inte
=
likhetstecken (men vi kan!) utan istället en pil enligt nedan
<-
till vänster om pilen anges vår namngivning av variabeln och till höger vårt objekt eller värde som vi vill ska sparas.
Exempelvis
x <- 5
Nedan i “environment” i R-Studio så har nu värdet 5 sparats i variabeln x. Detta syns inte i “vanliga” R utan bara i R-Studio IDE. Vill vi återge denna variabel så anger vi helt enkelt x och kör!
x
[1] 5
Alltså representerar x nu vår variabel och kan användas fritt istället för att skriva 5.
Tänk er en situation där ni vill göra många uträkningar, då är det jobbigt att fylla i en ny siffra för varje ekvation då ni vill ändra något. Används istället variabeln ni anger så blir det mycket enklare! Byt helt enkelt ut x mot det värde ni istället vill ange och kör koden för dessa uträkningar.
x + 3
x - 2
2 * x
x / 3
x ^ 2
x %% 3
Pröva nu istället att ange x som talet 6 (5 skrivs över) och kör koden ovan igen (markera allt och tryck ctrl + R)
Vi kan även lägga till fler variabler
y <- 3
och använda denna/dessa i uträkningar som involverar våra andra variabler
x + y
x - y
y * x
x / y
x ^ y
x %% y
Slutligen kan vi gå ett steg ytterligare och kombinera våra variabler till nya variabler, som då också kommer att få ett beroendeförhållande till de variabler som formar dessa.
z <- y + x + 10
z
[1] 18
Vilket vi förväntades få då x = 6 och y = 3 (i deras senast angivna form).
Ange variablerna x = 2 och y = 3. Använd dessa variabler för att beräkna arean av en rektangel med sidorna x och y.
Använd samma variabler för att beräkna arean av en triangel med sidorna x och y.
Ange istället x = 4 och beräkna rektangeln och triangeln igen.
Spara triangeln och rektangeln som variablerna t och r och summera dessa till en variabel tr.
Utöver enkla reella tal finns det andra datatyper som är användbara i R vilka jag skall gå igenom nu.
Först ut är text typen
x <- "Hej"
x
[1] "Hej"
med citattecken så har vi alltså angett en text variabel.
Som tidigare avsnitt om variabler antyder så kan man manipulera text med dessa variabler. Först kan vi lära oss att skriva funktionen (mer om funktioner i senare kapitel)
paste("Hej",", jag heter Charlie", sep="")
[1] "Hej, jag heter Charlie"
där sep=“” måste ingå annars kommer resultatet bli som nedan
paste("Hej",", jag heter Charlie")
[1] "Hej , jag heter Charlie"
Men på samma sätt som förut kan vi nu använda variabler
x <- "Hej"
y <- ", jag heter Charlie"
z <- paste(x,y,sep="")
z
[1] "Hej, jag heter Charlie"
där variabeln z medvetet angavs för att spara vår nya text.
Utöver text kan heltal (integer) definieras
x <- as.integer(5)
försöker vi ange 5.7 som heltal får vi
x <- as.integer(5.7)
x
[1] 5
Alltså istället närmaste heltal avrundat nedåt. Heltal kan vara användbara då vi vill spara minne.
Vet vi inte om en variabel är heltal eller reellt tal så kan man använda funktionen class()
class(x)
[1] "integer"
Så får man reda på vilken klass variabeln har. Här är x senast angiven som heltal från förgående slide. Man kan inte lägga ihop olika klasser av variabler
1 + "hej"
Error in 1 + "hej": non-numeric argument to binary operator
En annan data typ som kan anges är logiska värden, sant eller falskt påstående helt enkelt
x <- TRUE
y <- FALSE
x
[1] TRUE
y
[1] FALSE
Mer om dessa senare.
Ange ditt förnamn som en textvariabel kallad namn.
Ange ditt efternamn som en textvariabel kallad efternamn.
Klistra ihop dessa till ditt hela namn med för- och efternamn och ett mellanrum och spara dessa i en ny variabel id.
Lägg till din ålder efter ditt namn.
Hitills har vi bara tittat på enskilda värden angivna på varje variabler, men framöver kommer det blir viktigare att ange en mängd värden till en variabel.
I R kan vi ange en kombination av värden till en variabel i form av vektorer. Ni kan komma ihåg c() funktionen då vi ska kombinera, från engelskans “combine”.
mina_variabler <- c(1,3,5,7)
mina_variabler
[1] 1 3 5 7
Nu har vi kombinerat flera värden till en variabel “mina_variabler”! ☺☺☺
Det finns en del knep för att välja rätt namn på sina variabler, för långa namn blir krångliga medan för korta variabelnamn kan bli svåra att tyda eller sammanfalla med funktionsnamn som redan finns i R.
Det går även bra att kombinera text värden och logiska operatorer till vektorer.
mina_text_variabler <- c("hej","hallå","hejsan","tja")
mina_logiska_variabler <- c(TRUE,FALSE,FALSE,TRUE)
Med vektorer kan vi även göra beräkningar såsom nedan
c(1, 2, 3) + c(4, 5, 6)
[1] 5 7 9
c(1 + 4, 2 + 5, 3 + 6)
[1] 5 7 9
c(5, 7, 9)
[1] 5 7 9
I förgående slide så summeras vektorernas element, alltså varje värde i vektorerna, elementvis, det vill säga element 1 summeras med element 1 i den andra vektorn och så vidare.
Multiplikation sker också elementvis
c(1,2,3)*2
[1] 2 4 6
såväl som division
c(1,2,3)/2
[1] 0.5 1.0 1.5
Och vän av ordning så visar jag även att potenser och modulo sker elementvis.
c(1,2,3)^2
[1] 1 4 9
c(1,2,3)%%2
[1] 1 0 1
Skapa en variablerna x = 3, y = 2. Anta en triangel med sidorna x och y, spara en vektor kallad tri med sidorna och arean av triangeln.
Justera koden i tri så att detta bli en vektor som gäller för en rektangel. Spara denna som variabeln rek.
Summera tri och rek, vad anger elementen i den vektorn?
Ange samma uträkning som ovan fast direkt i vektorn med variablerna x och y.
Vi kan även namnge individuella element i den vektor vi har skapat.
x <- c(1,3,5,7)
namn_för_elementen <- c("element 1","element 2","element 3","element 4")
names(x) <- namn_för_elementen
x
element 1 element 2 element 3 element 4
1 3 5 7
som ni ser så har nu varje element ett eget namn, det är användbart om man vill identifiera exempelvis personer eller objekt.
Vi kan välja ut enstaka element från vektorn med hakparanteser.
x[1]
element 1
1
x[4]
element 4
7
Vi kan även välja ut elementen med hjälp av de namn vi har skapat…
x["element 3"]
element 3
5
…och dessutom välja flera element samtidigt med hjälp av vektorer inom hakparanteserna!
x[c(1,3,4)]
element 1 element 3 element 4
1 5 7
x[c("element 1","element 2")]
element 1 element 2
1 3
Med kolon : tecknet så kan vi bestämma ett intervall av värden som vi vill hämta, …
x[1:3]
element 1 element 2 element 3
1 3 5
…där alltså
1:3
[1] 1 2 3
c(1,2,3)
[1] 1 2 3
anger samma vektor utan att de mellanliggande värdena behöver anges (I detta fall 2)!
Skapa en vektor kallad veckoförsäljning med 7 valfria värden (varierande) och namnge alla veckans dagar.
Välj ut fredagens och söndagens försäljning, separat.
Visa försäljningen för alla vardagar
Välj ut tisdagens och torsdagens försäljning i samma vektor.
Funktioner är enkla att skapa i R. För att skapa en funktion kan ni helt enkelt skriva “fun” och trycka enter när ni är inuti ett script (R-Studio). Men det kan vara informativt att lära sig strukturen på funktionen då den används så flitigt.
name <- function(variables) {
}
Ovan så kommer name vara funktionens namn som man kallar, och variables (kan vara flera) är de variabler som man vi ange i sin funktion.
Låt oss göra en funktion!
medelvärde <- function(x) {
sum(x)/length(x)
}
I denna funktion har vi som ni märker redan använt två funktioner, “sum” och “length”. “sum” summerar vektorn man anger i funktionen och “length” ger som output längden av vektorn, det vill säga antalet element.
Notera hur beräkningarna anges inom klammerparanteserna.
Vi kan nu ange en vektor x, som då alltså innehåller numeriska värden, och testa vår funktion
x <- c(1,3,5,7)
medelvärde(x)
[1] 4
På samma sätt som sum() och length() är funktioner så är nu medelvärde() en funktion som vi kan kalla! ♪♫♪
Men att vi nu har skapat denna funktion var något onödigt då R redan innehåller en funktion för medelvärdet
mean(x)
[1] 4
med fler argument (variabler) som kan ändras.
Vi kan lägga till fler variabler som input i vårfunktion och även ange vad som ska återges med return()
name <- function(variabel1,variabel2) {
...
return(output)
}
Skapa en funktion kallad “triangel” som beräknar en arean av en triangel med två variabler, sidorna av denna. Kalla denna funktion med några värden.
Skapa samma funktion för en rektangel.
skapa en funktion som kallar de två skapade funktioner inom sig för att beräkna den sammanlagda arean. Kalla denna funktion total_area.
Modifiera din tidigare funktion så den även beräknar medelvärdet före summan av areorna, men bara har medelvärdet som output, döp funktionen till medel (Tips: ge medelvärdet ett varibelnamn i funktionen och lägg in detta i return() i slutet av funktionen).
I R är det användbart att använda logiska jämförelser för att kunna välja element eller ge betingelser för funktioner.
De logiska operatorerna i R är
< # Mindre eller större än
> # Mindre eller större än
<= # Mindre eller större och lika med
>= # Mindre eller större och lika med
== # Lika med varandra (notera, två stycken!)
!= # Inte lika med varandra
Exempelvis så är det naturligt att
3 > 2
Varvid får det logiska utfallet TRUE då 3 är större än 2
Vi anger en vektor x igen och använder lite logiska operatorer på denna vektor!
x <- c(1, 3, 5, 7)
x < 3
[1] TRUE FALSE FALSE FALSE
x > 3
[1] FALSE FALSE TRUE TRUE
x <= 3
[1] TRUE TRUE FALSE FALSE
x >= 3
[1] FALSE TRUE TRUE TRUE
x == 3
[1] FALSE TRUE FALSE FALSE
Man kan i sin tur använda dessa logiska utfall för att hämta element från vektorn x där dessa vektorer anger TRUE, alltså hämtas inte sådana värden som anges som FALSE.
x[x < 3]
[1] 1
x[x > 3]
[1] 5 7
Det går även att kombinera logiska operatorer med ett och-tecken, & (engelska: ampersand).
x[x < 3 & x != 7]
[1] 1
x[x > 1 & x < 5]
[1] 3
ange en vektor med värden 10,5,7,2,9. Skapa en vektor med logiska utfall för denna vektor där denna är större än 6.
Skapa en ny vektor med utfall där värden inte är lika med 7.
Skapa en vektor med utfall där värden är mindre än 7 och större eller lika med 2.
Använd dessa logiska utfall för att välja de elemenet från vektorn som avses.
Det är viktigt att i R kunna känna till faktorer, för att underlätta för er så kommer jag ta ett vanligt exempel. Ta tillexempel faktorn kön, alltså man eller kvinna. En sådan faktor kan endast anges två “värden”, man eller kvinna, och inte en kontinuerlig mängd av värden.
kön <- c("Kvinna","Man","Kvinna","Kvinna","Man")
kön_faktor <- factor(kön)
kön_faktor
[1] Kvinna Man Kvinna Kvinna Man
Levels: Kvinna Man
Nu kan man se att vektorn även har nivåer, “Levels”, bestående av Kvinna och Man.
Faktorer kallas även kategoriska variabler eftersom de har kategorier. Dessa kan även klassificeras i två ytterligare nivåer, nominal skala och ordinal skala.
Vi skapar ordinalskalan för kläder som jag nyss nämnde (utesluter “_faktor” i namnet eftersom det nu är underförstått)
klädstorlek <- factor(c("medium","small","large","small","small","XL"), order=TRUE, levels = c("small","medium","large","XL"))
klädstorlek
[1] medium small large small small XL
Levels: small < medium < large < XL
Så nu kan vi se att utöver angivna faktorer så har de en naturlig ordning! ♪♫♪♫♪
Nu ska vi introducera en av de mest användbara funktionerna i R: summary.
summary(klädstorlek)
small medium large XL
3 1 1 1
Summary ger en snabb överblick över de flesta objekt i R; Matriser, vektorer, datamängder m.m. När koden ovan kördes så får vi en snabb summering av antalet element i varje faktorvärde. Vi kommer använda summary fler gånger för att överblicka data innan vi hanterar dessa, detta då en översikt ger indikationer på om man skall hysa någon misstro mot sitt data samt se sammanfattande statistik över dessa.
Faktorer såsom kön ovan kan inte bli manipulerade av alla logiska operatorer. Se nedan för felmeddelande.
kön_faktor[1] > kön_faktor[2]
[1] NA
Det finns således ingen rangordning mellan män och kvinnor så att den ena kan antas vara större eller mindre än den andra.
Däremot för klädstorlek…
klädstorlek[1] > klädstorlek[2]
[1] TRUE
…så är medium större än small.
Skapa en faktorvektor med textvärden “fågel”, “mittemellan”, “fisk”, “mittemellan” och “fisk”, i den ordningen.
Justera denna vektor så att den blir på ordinalskala istället.
Skapa en vektor med logiska värden för ovan vektor för det som är “större eller lika med mittemellan”.
Använda detta logiska påstående för att ta ut dessa element från vektorn.
Vi kan skapa en matris enligt nedan
matrix(1:9, nrow = 3, ncol = 3, byrow = TRUE)
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
[3,] 7 8 9
där 1:9 anger vektorn vi vill lägga in i matrisen, nrow är antalet rader och ncol antalet kolumner.
Byrow är en logisk operator för vilken vi säger att värdena skall läggas in radvis. Hade vi istället skrivit
matrix(1:9, nrow = 3, ncol = 3)
[,1] [,2] [,3]
[1,] 1 4 7
[2,] 2 5 8
[3,] 3 6 9
Så läggs per automatik värdena in kolumnvis.
Vi kan namnge raderna och kolumnerna likt vi gjorde med vektorerna.
vår_matris <- matrix(1:9, nrow = 3, ncol = 3, byrow = TRUE)
colnames(vår_matris) <- c("kolumn_1", "kolumn_2", "kolumn_3")
rownames(vår_matris) <- c("rad_1", "rad_2", "rad_3")
vår_matris
kolumn_1 kolumn_2 kolumn_3
rad_1 1 2 3
rad_2 4 5 6
rad_3 7 8 9
På samma sätt som med vektorer så kan vi hämta element från matrisen
[,] används, där före kommatecknet så anger vi rader och efter komma tecknet så anger vi kolumner.
vår_matris[1, 2] # rad 1 och kolumn 2
[1] 2
vår_matris[1:2, 3] # rad 1 och 2 samt kolumn 3 (notera att detta blir en vektor)
rad_1 rad_2
3 6
vår_matris[2:3, 2:3] # rad 2 och 3 samt kolumn 2 och 3
kolumn_2 kolumn_3
rad_2 5 6
rad_3 8 9
Istället för numeriska värden kan vi använda namnet på raderna och kolumnerna om vi vill.
vår_matris["rad_1", "kolumn_2"] # rad 1 och kolumn 2
[1] 2
vår_matris[c("rad_1", "rad_2"), "kolumn_3"] # rad 1 och 2 samt kolumn 3 (notera att detta blir en vektor)
rad_1 rad_2
3 6
vår_matris[c("rad_2", "rad_3"),c("kolumn_2","kolumn_3")] # rad 2 och 3 samt kolumn 2 och 3
kolumn_2 kolumn_3
rad_2 5 6
rad_3 8 9
Det finns inget som hindrar en från att blanda dessa.
vår_matris[2:3,c("kolumn_2","kolumn_3")] # rad 2 och 3 samt kolumn 2 och 3
kolumn_2 kolumn_3
rad_2 5 6
rad_3 8 9
Om vi lämnar ett fält blankt för rader så väljs helt enkelt alla rader
vår_matris[,c("kolumn_2","kolumn_3")]
kolumn_2 kolumn_3
rad_1 2 3
rad_2 5 6
rad_3 8 9
Det samma gäller för kolumner
vår_matris[c("rad_2","rad_3"),]
kolumn_1 kolumn_2 kolumn_3
rad_2 4 5 6
rad_3 7 8 9
Några bra matrisoperationer kan vara att summera över alla rader eller kolumner
rowSums(vår_matris)
rad_1 rad_2 rad_3
6 15 24
colSums(vår_matris)
kolumn_1 kolumn_2 kolumn_3
12 15 18
Säg att vi vill lägg till en kolumn i vår matris
ny_kolumn <- c(1,2,3)
då använder vi cbind för att lägga till kolumner
cbind(vår_matris,ny_kolumn)
kolumn_1 kolumn_2 kolumn_3 ny_kolumn
rad_1 1 2 3 1
rad_2 4 5 6 2
rad_3 7 8 9 3
Vill vi istället lägga till en ny rad
ny_rad <- c(1,2,3)
Så använder vi rbind
rbind(vår_matris,ny_rad)
kolumn_1 kolumn_2 kolumn_3
rad_1 1 2 3
rad_2 4 5 6
rad_3 7 8 9
ny_rad 1 2 3
Operatorerna som vi redan har lärt oss, d.v.s +, -, *, /, ^ och %% kan användas på matriser, vilket sker på alla element, ta exempelvis vår matris
vår_matris
kolumn_1 kolumn_2 kolumn_3
rad_1 1 2 3
rad_2 4 5 6
rad_3 7 8 9
så sker addition för varje element
vår_matris + 2
kolumn_1 kolumn_2 kolumn_3
rad_1 3 4 5
rad_2 6 7 8
rad_3 9 10 11
utelämnar exempel för andra operatorer men ni kan pröva er fram!
Skapa en matris med två rader och två kolumner med värdena 2, 5, 3, 7 kolumnvis. Döp matrisen till “mat”.
Namnge raderna “rad 1” och “rad 2” samt kolumnerna “kolumn 1” och “kolumn 2”.
Utöka matrisen med radsummorna, kolumnsummorna samt totalen.
Hämta de nya raderna och kolumnerna samt totalen.
Vi tittade kort på en matris, problemet med att använda endast matriser för att representera data är att matriser endast tillåter samma typ av data i dess element, alltså ingen blandning av exempelvis text, faktorer, numeriska värden etc etc.
Det skapar problem då man ofta vill titta på olika saker samtidigt utan att behöva dela upp detta i flera matriser.
I data frames så kan vi ange olika datatyper i kolumnerna till skillnad från en matris.
R har som ni har märkt förinställda funktioner såsom mean() och length() m.m. Utöver detta så kan man få tillgång till data som redan ligger förberett i R som exempeldata.
Ett av dessa är “mtcars” vilken brukar användas för introduktion till R samt test av olika modeller för att jämföra resultat.
Lite bakgrund till datasetet fås genom
?mtcars
Vi kan summera med summary() funktionen och på nästa slide printar jag ut hela datasetet.
summary(mtcars)
mpg cyl disp hp
Min. :10.40 Min. :4.000 Min. : 71.1 Min. : 52.0
1st Qu.:15.43 1st Qu.:4.000 1st Qu.:120.8 1st Qu.: 96.5
Median :19.20 Median :6.000 Median :196.3 Median :123.0
Mean :20.09 Mean :6.188 Mean :230.7 Mean :146.7
3rd Qu.:22.80 3rd Qu.:8.000 3rd Qu.:326.0 3rd Qu.:180.0
Max. :33.90 Max. :8.000 Max. :472.0 Max. :335.0
drat wt qsec vs
Min. :2.760 Min. :1.513 Min. :14.50 Min. :0.0000
1st Qu.:3.080 1st Qu.:2.581 1st Qu.:16.89 1st Qu.:0.0000
Median :3.695 Median :3.325 Median :17.71 Median :0.0000
Mean :3.597 Mean :3.217 Mean :17.85 Mean :0.4375
3rd Qu.:3.920 3rd Qu.:3.610 3rd Qu.:18.90 3rd Qu.:1.0000
Max. :4.930 Max. :5.424 Max. :22.90 Max. :1.0000
am gear carb
Min. :0.0000 Min. :3.000 Min. :1.000
1st Qu.:0.0000 1st Qu.:3.000 1st Qu.:2.000
Median :0.0000 Median :4.000 Median :2.000
Mean :0.4062 Mean :3.688 Mean :2.812
3rd Qu.:1.0000 3rd Qu.:4.000 3rd Qu.:4.000
Max. :1.0000 Max. :5.000 Max. :8.000
mtcars
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
Merc 280C 17.8 6 167.6 123 3.92 3.440 18.90 1 0 4 4
Merc 450SE 16.4 8 275.8 180 3.07 4.070 17.40 0 0 3 3
Merc 450SL 17.3 8 275.8 180 3.07 3.730 17.60 0 0 3 3
Merc 450SLC 15.2 8 275.8 180 3.07 3.780 18.00 0 0 3 3
Cadillac Fleetwood 10.4 8 472.0 205 2.93 5.250 17.98 0 0 3 4
Lincoln Continental 10.4 8 460.0 215 3.00 5.424 17.82 0 0 3 4
Chrysler Imperial 14.7 8 440.0 230 3.23 5.345 17.42 0 0 3 4
Fiat 128 32.4 4 78.7 66 4.08 2.200 19.47 1 1 4 1
Honda Civic 30.4 4 75.7 52 4.93 1.615 18.52 1 1 4 2
Toyota Corolla 33.9 4 71.1 65 4.22 1.835 19.90 1 1 4 1
Toyota Corona 21.5 4 120.1 97 3.70 2.465 20.01 1 0 3 1
Dodge Challenger 15.5 8 318.0 150 2.76 3.520 16.87 0 0 3 2
AMC Javelin 15.2 8 304.0 150 3.15 3.435 17.30 0 0 3 2
Camaro Z28 13.3 8 350.0 245 3.73 3.840 15.41 0 0 3 4
Pontiac Firebird 19.2 8 400.0 175 3.08 3.845 17.05 0 0 3 2
Fiat X1-9 27.3 4 79.0 66 4.08 1.935 18.90 1 1 4 1
Porsche 914-2 26.0 4 120.3 91 4.43 2.140 16.70 0 1 5 2
Lotus Europa 30.4 4 95.1 113 3.77 1.513 16.90 1 1 5 2
Ford Pantera L 15.8 8 351.0 264 4.22 3.170 14.50 0 1 5 4
Ferrari Dino 19.7 6 145.0 175 3.62 2.770 15.50 0 1 5 6
Maserati Bora 15.0 8 301.0 335 3.54 3.570 14.60 0 1 5 8
Volvo 142E 21.4 4 121.0 109 4.11 2.780 18.60 1 1 4 2
I förgående slide så var det på håret att ni skulle kunna se hela datasetet (jag skrev medvetet ingen förklarande text till detta utan la den på sliden före). Ibland kan datamängden vara för stor att överblicka eller enorm inom det som nuförtiden populärt kallas “Big Data”, då kan det vara bra att få en inblick i datat genom att bara titta på de första raderna.
vi använder funktionen head() som i dess enklaste form ger de första 6 raderna.
head(mtcars)
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225 105 2.76 3.460 20.22 1 0 3 1
vill vi visa fler rader, exempelvis de 10 första, kan vi ange detta med
head(mtcars,10)
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
Valiant 18.1 6 225.0 105 2.76 3.460 20.22 1 0 3 1
Duster 360 14.3 8 360.0 245 3.21 3.570 15.84 0 0 3 4
Merc 240D 24.4 4 146.7 62 3.69 3.190 20.00 1 0 4 2
Merc 230 22.8 4 140.8 95 3.92 3.150 22.90 1 0 4 2
Merc 280 19.2 6 167.6 123 3.92 3.440 18.30 1 0 4 4
Vi kan även överblicka data med str() funktionen som återger datastrukturen.
str(mtcars)
'data.frame': 32 obs. of 11 variables:
$ mpg : num 21 21 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 ...
$ cyl : num 6 6 4 6 8 6 8 4 4 6 ...
$ disp: num 160 160 108 258 360 ...
$ hp : num 110 110 93 110 175 105 245 62 95 123 ...
$ drat: num 3.9 3.9 3.85 3.08 3.15 2.76 3.21 3.69 3.92 3.92 ...
$ wt : num 2.62 2.88 2.32 3.21 3.44 ...
$ qsec: num 16.5 17 18.6 19.4 17 ...
$ vs : num 0 0 1 1 0 1 0 1 1 1 ...
$ am : num 1 1 1 0 0 0 0 0 0 0 ...
$ gear: num 4 4 4 3 3 3 3 4 4 4 ...
$ carb: num 4 4 1 1 2 1 4 2 2 4 ...
Där ser vi antalet observationer, antalet variabler, vilka kolumner som ingår tillsammans med datatyp och första värden. Ni undrar kanske varför det just är dollartecken framför varje kolumn?
Svaret på frågan i förgående slide är att man kan hämta en kolumn från sin data frame såsom nedan.
mtcars$mpg
[1] 21.0 21.0 22.8 21.4 18.7 18.1 14.3 24.4 22.8 19.2 17.8 16.4 17.3 15.2
[15] 10.4 10.4 14.7 32.4 30.4 33.9 21.5 15.5 15.2 13.3 19.2 27.3 26.0 30.4
[29] 15.8 19.7 15.0 21.4
Alltså väldigt enkelt, ingen komplicerad kod utan helt enkelt dollartecken och den kolumn man vill ha så återges alla värden för den vektorn.
Säg att vi vill ha de element 5 till 10 i cyl (cylinder) kolumnen, då skriver vi helt enkelt
mtcars$cyl[5:10]
[1] 8 6 8 4 4 6
och vill vi ha alla värden i den kolumnen som är lika med eller större än 6 skriver vi
mtcars$cyl[mtcars$cyl >= 6]
[1] 6 6 6 8 6 8 6 6 8 8 8 8 8 8 8 8 8 8 8 6 8
Öppna det förinstallerade datasetet mtcars.
Visa de två första raderna
Välj ut hp kolumnen och visa alla värden över 100 hästkrafter
Undersök strukturen på mtcars, vilka förändringar skulle man kunna göra?
I tidigare exempel använde vi mtcars, men vi vill ju gärna kunna använda våra egna data.
Vi kör lite hitte-på data och ser vad som händer!
kommun <-
c("Trelleborg", "Borlänge", "Stockholm", "Umeå", "Haparanda", "Kiruna")
läge <-
c("mest söder", "söder", "mer söder", "norr", "mer norr", "mest norr")
invånare <- c(43359, 41734, 789024, 111503, 4856, 18148)
IKEA <- c(FALSE, TRUE, TRUE, TRUE, TRUE, FALSE)
Brännbollsyran <- c(FALSE, FALSE, FALSE, TRUE, FALSE, FALSE)
Allt väl än så länge, men det här är ju endast vektorer och vi ville ju ha en data frame.
För detta ändamål använder vi data.frame() funktionen.
data.frame(kommun, läge, invånare, IKEA, Brännbollsyran)
kommun läge invånare IKEA Brännbollsyran
1 Trelleborg mest söder 43359 FALSE FALSE
2 Borlänge söder 41734 TRUE FALSE
3 Stockholm mer söder 789024 TRUE FALSE
4 Umeå norr 111503 TRUE TRUE
5 Haparanda mer norr 4856 TRUE FALSE
6 Kiruna mest norr 18148 FALSE FALSE
Kanon! Vi skapar ett objekt av denna data frame och summerar
kommundata <-
data.frame(kommun, läge, invånare, IKEA, Brännbollsyran)
summary(kommundata)
kommun läge invånare IKEA
Borlänge :1 mer norr :1 Min. : 4856 Mode :logical
Haparanda :1 mer söder :1 1st Qu.: 24045 FALSE:2
Kiruna :1 mest norr :1 Median : 42547 TRUE :4
Stockholm :1 mest söder:1 Mean :168104 NA's :0
Trelleborg:1 norr :1 3rd Qu.: 94467
Umeå :1 söder :1 Max. :789024
Brännbollsyran
Mode :logical
FALSE:5
TRUE :1
NA's :0
Vidare undersöker vi strukturen på data framen
str(kommundata)
'data.frame': 6 obs. of 5 variables:
$ kommun : Factor w/ 6 levels "Borlänge","Haparanda",..: 5 1 4 6 2 3
$ läge : Factor w/ 6 levels "mer norr","mer söder",..: 4 6 2 5 1 3
$ invånare : num 43359 41734 789024 111503 4856 ...
$ IKEA : logi FALSE TRUE TRUE TRUE TRUE FALSE
$ Brännbollsyran: logi FALSE FALSE FALSE TRUE FALSE FALSE
Är variablerna godtagbara?
vi kan annordna så att variabeln läge hamnar på ordinalskala istället för nominalskala.
kommundata$läge <-
factor(
kommundata$läge,
order = TRUE,
levels = c("mest söder", "mer söder", "söder", "norr", "mer norr", "mest norr")
)
Vi kontrollerar att vår nya variabel är okej.
kommundata$läge
[1] mest söder söder mer söder norr mer norr mest norr
6 Levels: mest söder < mer söder < söder < norr < ... < mest norr
Nu har vi angett en ordinal skala för kolumnen läge.
Att välja element ur data frame är identiskt mot hur det går till med matriser.
kommundata[1, 2]
[1] mest söder
6 Levels: mest söder < mer söder < söder < norr < ... < mest norr
kommundata[1:3, 3]
[1] 43359 41734 789024
Vi kan dock använda $ tecknet som extra knep.
kommundata$IKEA[3]
[1] TRUE
kommundata[1:3, "Brännbollsyran"]
[1] FALSE FALSE FALSE
Vi kan även ta urval ur data frame med subset() funktionen
subset(kommundata, invånare > 100000)
kommun läge invånare IKEA Brännbollsyran
3 Stockholm mer söder 789024 TRUE FALSE
4 Umeå norr 111503 TRUE TRUE
Vilket kan göra koden mindre komplicerad och lättförståelig för någon som skall läsa din kod.
Vi kan också sortera vektorer
order(kommundata$invånare)
[1] 5 6 2 1 4 3
vilket ger den nya ordningen med lägsta värdet till största.
Vill vi hämta värdena skriver vi
kommundata[order(kommundata$invånare),]
kommun läge invånare IKEA Brännbollsyran
5 Haparanda mer norr 4856 TRUE FALSE
6 Kiruna mest norr 18148 FALSE FALSE
2 Borlänge söder 41734 TRUE FALSE
1 Trelleborg mest söder 43359 FALSE FALSE
4 Umeå norr 111503 TRUE TRUE
3 Stockholm mer söder 789024 TRUE FALSE
och om vi skulle vilja göra detta även för läge
kommundata[order(kommundata$läge),]
kommun läge invånare IKEA Brännbollsyran
1 Trelleborg mest söder 43359 FALSE FALSE
3 Stockholm mer söder 789024 TRUE FALSE
2 Borlänge söder 41734 TRUE FALSE
4 Umeå norr 111503 TRUE TRUE
5 Haparanda mer norr 4856 TRUE FALSE
6 Kiruna mest norr 18148 FALSE FALSE
Ni kan kopiera övningsdatasetet nedan från det här kapitlet och pröva olika sätt att hämta element från data framen.
kommun <-
c("Trelleborg", "Borlänge", "Stockholm", "Umeå", "Haparanda", "Kiruna")
läge <-
c("mest söder", "söder", "mer söder", "norr", "mer norr", "mest norr")
invånare <- c(43359, 41734, 789024, 111503, 4856, 18148)
IKEA <- c(FALSE, TRUE, TRUE, TRUE, TRUE, FALSE)
Brännbollsyran <- c(FALSE, FALSE, FALSE, TRUE, FALSE, FALSE)
kommundata <-
data.frame(kommun, läge, invånare, IKEA, Brännbollsyran)
En lista i R kan samla objekt av varierande sorter.
Likna gärna det med skillnaden mellan matrisens ensidighet med data innehåll och data frames varierande kolumner, då en lista kan blanda matriser, vektorer, data frames och tillochmed fler listor i varje listelement.
På så sätt kan man lagra i princip allt man behöver i en lista.
Att skapa en lista är busenkelt
en_matris <- matrix(rnorm(1:9), nrow = 3, ncol = 3) # statistik så går inte in på detaljer
en_data_frame <- as.data.frame(en_matris)
en_vektor <- c(1,3,5,7)
ett_ord <- "Hej!"
ett_logiskt_utfall <- TRUE
min_lista <- list(en_matris,en_data_frame,en_vektor,ett_ord,ett_logiskt_utfall)
list funktionen skapar listan i den ordning som man har anget sina objekt.
Hur ser listan ut?
min_lista
[[1]]
[,1] [,2] [,3]
[1,] 1.3058407 -0.0954302 -1.4529701
[2,] 0.5112797 0.3488839 0.1165523
[3,] 1.0243029 -1.9121288 1.3179315
[[2]]
V1 V2 V3
1 1.3058407 -0.0954302 -1.4529701
2 0.5112797 0.3488839 0.1165523
3 1.0243029 -1.9121288 1.3179315
[[3]]
[1] 1 3 5 7
[[4]]
[1] "Hej!"
[[5]]
[1] TRUE
Hur kommer vi åt listelementen då? För den uppmärksamme som tagit en titt på koden så kan det bli rätt uppenbart, man lägger till extra hakparanteser för de listelement som avses. Så vi skriver helt enkelt
min_lista[[2]]
V1 V2 V3
1 1.3058407 -0.0954302 -1.4529701
2 0.5112797 0.3488839 0.1165523
3 1.0243029 -1.9121288 1.3179315
min_lista[[4]]
[1] "Hej!"
för listelement 2 och 4.
Enkelt! Och vill vi jobba med dessa listelement så är det bara att använda vilken kod som än är tillämplig på den klass av variabel som man har hämtat.
min_lista[[2]][1:2,"V3"]
[1] -1.4529701 0.1165523
min_lista[[3]][4]
[1] 7
Vill vi namnge listelementen så kan vi även göra detta! ♪♫♪
namn_lista <- c("matris","data.frame","vektor","ord","logiskt utfall")
names(min_lista) <- namn_lista
min_lista
$matris
[,1] [,2] [,3]
[1,] 1.3058407 -0.0954302 -1.4529701
[2,] 0.5112797 0.3488839 0.1165523
[3,] 1.0243029 -1.9121288 1.3179315
$data.frame
V1 V2 V3
1 1.3058407 -0.0954302 -1.4529701
2 0.5112797 0.3488839 0.1165523
3 1.0243029 -1.9121288 1.3179315
$vektor
[1] 1 3 5 7
$ord
[1] "Hej!"
$`logiskt utfall`
[1] TRUE
och i förgående lista såg vi återigen dollartecken. Det kan bara betyda en sak!
min_lista$vektor
[1] 1 3 5 7
min_lista$ord
[1] "Hej!"
min_lista$`logiskt utfall`
[1] TRUE
Smidigt!
Vi kunde även, för enklare namngivelse i framtiden, ha skrivit
min_lista <- list(matris = en_matris,
data.frame = en_data_frame,
vektor = en_vektor,
ord = ett_ord,
"logiskt utfall" = ett_logiskt_utfall)
för att lägga till listnamnen när listan skapades.Notera att för alla namn utom “logiskt utfall” kunde jag undvika att skriva citattecken, detta beror på mellanrummet som inte accepteras för namnet “logiskt utfall”.
Nu har vi en lista men säg att den inte riktigt räcker till, vi vill lägga till mtcars datasetet vi använde tidigare.
Detta är riktigt enkelt, kom ni ihåg c() funktionen som vi använder för att kombinera värden till vektorer? Samma funktion kan kombinera en lista med ytterligare ett listelement, kom då ihåg att säkerställa att det är ett listelement, men det behöver inte göras om man lägger till exempelvis en vektor.
ny_lista <- c(min_lista, list(cars = mtcars))
listan blir förstås för lång för att printa men mtcars är nu med i listan med namnet “cars”.
Slutligen kan vi överblicka listan med… just det, str() och summary()
str(ny_lista)
summary(ny_lista)
vilket jag låter er göra själva.
Ni kan kopiera listan och pröva olika kommandon från kapitlet.
en_matris <- matrix(rnorm(1:9), nrow = 3, ncol = 3) # statistik så går inte in på detaljer
en_data_frame <- as.data.frame(en_matris)
en_vektor <- c(1,3,5,7)
ett_ord <- "Hej!"
ett_logiskt_utfall <- TRUE
min_lista <- list(en_matris,en_data_frame,en_vektor,ett_ord,ett_logiskt_utfall)