Objekt i R
R använder objekt för att lagra information. Här är ett enkelt objekt som bara lagrar det numeriska värdet 1:
my_number <- 1
Vi har skapat ett objekt med namnet my_number
och tilldelade det värdet 1. Tilldelningen av värdet 1 gjordes med symbolerna <-
, vilka kallas the assignment operator, som blir tilldelningsoperator på svenska. Man säger att my_number
får värdet 1. Nu innehåller objektet my_number
information i form av ett numeriskt värde. Låt oss fråga R vilken typ av objekt my_number
är:
class(my_number)
[1] "numeric"
Enligt ovanstående tolkar R my_number
som ett numeriskt objekt, vilket verkar rimligt. Låt oss göra samma procedur med en textsträng istället:
my_string <- "Hej! Mitt namn är Salvador."
class(my_string)
[1] "character"
Objektet my_string
är ett character objekt, vilket innebär att det består av tecken och symboler. Dessa två exempel visar att i det ögonblick vi skapar ett objekt kommer R försöka gissa vilken typ av information objektet innehåller. Låt oss se hur R tolkar ett numeriskt värde omgivet av citattecken:
my_object <- "1"
class(my_object)
[1] "character"
R tolkar my_object
som en teckensträng (character objekt), vilket förklaras av att siffran 1 var omsluten av citattecken, vilket innebär att R antar att det är en teckensträng vi vill lagra.
All information som du lagrar i din Environment är ett objekt. Exempel på objekt är som följer:
- Tabeller (dataframes) är objekt.
- Sparade enskilda värden (som exempelvis
my_object
ovan) är ett objekt. - Resultat från regressionsmodeller är objekt.
I princip allt du skapar i R är ett objekt. Här nedan kommer vi gå igenom olika typer av objekt i R.
4.1 Atomic Vectors (Atomvektorer)
Den enklaste typen av objekt i R är en atomic vector (atomvektor). Atomic vectors används alltid när du arbetar i R. Låt oss skapa en atomvektor med hjälp av funktionen c()
. Denna funktion kombinerar flera element för att bilda en vektor. Vi namnger objektet my_first_vector
och det kommer att innehålla sex numeriska värden:
my_first_vector <- c(1, 2, 3, 4, 5, 6)
Vi kan kontrollera om R betraktar my_first_vector
som en atomic vector genom att använda funktionen is.vector()
:
# is.vector() kontrollerar om ett object är en atomic vector
is.vector(my_first_vector)
[1] TRUE
Funktionen is.vector()
returnerade värdet TRUE vilket innebär att my_first_vector
är en atomic vector. Eftersom my_first_vector
endast innehåller numeriska värden, kommer R att betrakta det som en numerisk vektor, vilket man kan kontrollera med hjälp av funktionen is.numeric()
:
# is.numeric() kontrollerar om en atomic vector är numerisk
is.numeric(my_first_vector)
[1] TRUE
Atomic vectors har bara en dimension. Varje vektor kan bara lagra en typ av data. För att hantera alla typer av data finns därför sex grundläggande typer av atomic vectors:
- double: numeriska värden med eller utan decimaler
- integer: numeriska heltal (inga decimaler)
- character: tecken, symboler, text
- logical: JA/NEJ, 0/1, TRUE/FALSE
- Synonym: logiska värden (sve), boolean (eng), booleska värden (sve).
- complex och raw vectors existerar men används i princip aldrig.
my_doubles <- c(1.2, 2.4, 32.1)
my_integers <- c(1L, 2L, 3L)
my_characters <- c("A", "B", "Hello", "My phone is dead")
my_logicals <- c(TRUE, TRUE, FALSE, TRUE, FALSE)
Du kan kontrollera om en vektor är något av ovanstående genom att använda funktionerna is.double()
, is.numereric()
, is.character()
, is.logical()
. Dessa funktioner returnerar värdet TRUE eller FALSE.
Om du behöver kontrollera vilken typ av vektor ett objekt är kan du använda funktionen typeof()
. Nedan skapar vi en numerisk vektor med decimaler och sedan frågar vi vilken klass respektive typ vektorn är.
my_doubles <- c(1.2, 2.4, 32.1)
class(my_doubles)
[1] "numeric"
typeof(my_doubles)
[1] "double"
4.1.0.1 Vektorers längd
Längden på en vektor är helt enkelt antalet element i den. Låt oss skapa en atomvektor med 5 numeriska värden och kontrollera längden på den:
my_values <- c(1, 2, 3, 4, 5)
length(my_values)
[1] 5
Låt oss skapa en vektor med en lång sträng för att kontrollera längden:
my_string <- c("Det är roligt att lära sig R!")
length(my_string)
[1] 1
Längden på denna vektor var 1 eftersom den innehåller 1 element, vilket var meningen “Det är roligt att lära sig R!”. Låt oss skapa en vektor med två textsträngar:
my_string <- c("Det är roligt att lära sig R!", "Det kommer ta en vecka att lära sig R")
length(my_string)
[1] 2
Nu har my_string
2 textsträngar och därför har vektorn längden 2.
En atomic vector kan bara lagra en typ av data. Låt oss testa detta genom att skapa en vektor med både numeriska värden, textsträngar och logiska värden.
# Skapa en vektor med textsträngar, numeriska värden och booleska värden
mixed <- c("Det är roligt att lära sig R!", 1, 2, TRUE, FALSE)
Vi skriver ut resultatet:
mixed
[1] "Det är roligt att lära sig R!" "1"
[3] "2" "TRUE"
[5] "FALSE"
Vi kontrollerar vektorns klass:
# Kontrollera vektorns klass
class(mixed)
[1] "character"
Observera följande:
- Alla elementen skrevs ut med citattecken, vilket innebär att R konverterat alla element till textsträngar, även siffrorna, TRUE och FALSE. Detta kallas coercion (forcerad omvandling), vilket innebär att en datatyp omvandlades automatiskt till en annan. Siffran 1 är således inte längre ett numeriskt värde; det representerar bara tecknet 1. TRUE och FALSE är inte längre booleska värden; de utgör bara orden TRUE och FALSE.
- Ovanstående förklarar varför funktionen
class()
hävdar att vektorn är av typen character. - Eftersom typen nu är character kan du inte längre utföra matematiska beräkningar (t ex beräkna medelvärde) på denna vektorn.
Du måste vara explicit när du skapar vektorer i R. Siffrorna från 1 till 4 kan skapas både som numerisk vektor eller character vektor. För att skapa en character vektor måste varje element anges med citattecken:
Exempel 1: Skapa numerisk vektor
my_numbers <- c(1, 2, 3, 4)
my_numbers
[1] 1 2 3 4
Exempel 2: Skapa character vektor
my_characters <- c("1", "2", "3", "4")
my_characters
[1] "1" "2" "3" "4"
Du kan konvertera vektorer mellan olika typer med funktionerna as.character()
, as.numeric()
, etc.
Exempel 3: Konvertera numerisk till character
# Skapar numerisk vektor
my_numbers <- c(1, 2, 3, 4)
# Konverterar numerisk vektor till character
my_characters <- as.character(my_numbers)
# Skriver ut resultatet
my_characters
[1] "1" "2" "3" "4"
Därför kan du konvertera vektor mellan typer. Låt oss försöka motsatsen, dvs gå från tecken till numerisk: Exempel 4: Konvertera tecken till numeriskt
my_characters <- c("1", "2", "3", "4")
my_numbers <- as.numeric(my_characters)
# Print it
my_numbers
[1] 1 2 3 4
Detta lyckades eftersom siffrorna kom i rätt ordning utan citattecken. Om de verkligen är numeriska värden nu så borde vi kunna beräkna ett medelvärde av siffrorna:
mean(my_numbers)
[1] 2.5
Nu är vi säkra på att det blev rätt. Observera att ibland kan konverteringar ge oväntade resultat. Därför är det viktigt att göra någon typ av kontroll för att fastställa att konverteringen blir som förväntat.
Låt oss försöka konvertera strängen “Hej” till ett numeriskt värde:
# Skapa character vektor
my_characters <- c("Hej")
# Konvertera den till numerisk vektor
my_numbers <- as.numeric(my_characters)
Warning: NAs introduced by coercion
# Skriv ut resultatet
my_numbers
[1] NA
Här fick vi istället varningen “NAs introduced by coercion”. NA står för “Not Available” eller “Not Applicable” beroende på sammanhang. I detta fall är det Not Available, vilket innebär att värdet saknas. Konverteringen har alltså resulterat i att R tvingat värdet till NA. När vi skriver ut objektet my_numbers
finns bara ett enda värde och det är NA. Med andra ord kan inte R konvertera “Hej” till ett numeriskt värde.
4.1.1 Double vector
En double lagrar numeriska värden. Värdena kan ha decimaler. R sparar i princip alltid numeriska vektorer som double, även om de saknar decimaler. Detta kan vi kontrollera nu:
# Skapa numerisk vektor utan decimaler
my_numbers <- c(1, 2, 3)
# Kontrolla om den är en double
is.double(my_numbers)
[1] TRUE
# Skapa numerisk vektor med decimaler
your_numbers <- c(1.1, 2.2, 3.3)
# Kontrolla om den är en double
is.double(your_numbers)
[1] TRUE
Även om objektet my_numbers
bara består av heltal så kommer R att spara den som en double. Vi kan kontrollera att vektorn inte är ett heltal:
is.integer(my_numbers)
[1] FALSE
4.1.2 Integer vector (heltal)
En integer vector lagrar bara heltal. Ett heltal är ett numeriskt värde utan decimaler. Det är osannolikt att du behöver arbeta med denna typen av vektor eftersom double vektorn också kan hantera heltal. Du kan i princip alltid använda double istället för integer. Du behöver ytterst sällan beakta detta eftersom R gör det automatiskt. Om du trots detta vill definiera en vektor som integer gör du det genom att lägga till bokstaven L efter siffrorna:
my_integers <- c(1L, 5L, 3L, 10L)
is.integer(my_integers)
[1] TRUE
Du kan också forcera (tvinga) en double till integer:
# Skapa en double vektor
my_doubles <- c(1, 2, 3, 4)
# Kontrollera om den är en double
is.double(my_doubles)
[1] TRUE
# Konvertera double till integer och sparar resultatet i ett nytt objekt kallat my_integers
my_integers <- as.integer(my_doubles)
# Kontrollera om my_integers är en integer vektor
is.integer(my_integers)
[1] TRUE
Att ha olika typer av vektorer är mycket användbart. Olika vektorer används för olika ändamål. Matematiska operationer är endast möjliga på numeriska vektorer och logicals. Vi kommer att demonstrera detta med hjälp av funktionen mean()
, som beräknar det matematiska medelvärdet av en serie numeriska värden:
# Skapar en double
my_values <- c(5, 10, 15, 20)
# Beräknar medelvärdet och sparar resultatet i ett nytt objekt kallat my_mean
my_mean <- mean(my_values)
# Skriver ut objektet
my_mean
[1] 12.5
Tidigare nämnde vi att man kan bädda in funktioner i funktioner, vilket kan spara mycket utrymme. Nu beräknar vi medelvärdet igen utan att spara nya objekt. Notera ur funktionen c()
bäddas in i funktionen mean()
.
mean(c(5, 10, 15, 20))
[1] 12.5
4.1.3 Character vector (strängar)
Text och symboler lagras i character vektorer. Följande kommando sparar en textsträng genom att omsluta den med citattecken:
my_string <- c("Detta är en textsträng. Den kan innehålla symboler (@, *, /) och siffror (1, 2, 3)")
my_string
[1] "Detta är en textsträng. Den kan innehålla symboler (@, *, /) och siffror (1, 2, 3)"
Vektorn my_string
sparar en sträng som innehåller symboler, bokstäver och siffror. Här följer en character vektor med två strängar, varav den andra innehåller siffror och symboler:
my_string <- c("Detta är den första strängen", "Detta är den andra strängen")
my_string
[1] "Detta är den första strängen" "Detta är den andra strängen"
Som nämnt ovan kommer siffror omgivna av citattecken att tolkas som tecken (inte numeriska värden). Det framgår av exemplet nedan, där vi även använder funktionen paste()
för att skriva ut kommentarer i resultaten:
paste("UTAN CITATTECKEN:")
[1] "UTAN CITATTECKEN:"
my_numbers <- c(1, 2, 3)
typeof(my_numbers)
[1] "double"
my_numbers
[1] 1 2 3
paste("MED CITATTECKEN:")
[1] "MED CITATTECKEN:"
your_numbers <- c("1", "2", "3")
typeof(your_numbers)
[1] "character"
your_numbers
[1] "1" "2" "3"
R visar citattecken vid utskrift av your_numbers
för att klargöra att elementen är textsträngar! Alla character vektorer skrivs ut med citattecken i R.
En teckensträng innehåller tecken och symboler. Det är inte möjligt att utföra matematiska operationer på teckensträngar, även om de innehåller siffror. Låt oss se två exempel:
Exempel 1: Skapa en sträng med bokstäver
my_string <- "Detta är en sträng"
# Multiplicera den med 2
my_string*2
## Error in my_string * 2 : non-numeric argument to binary operator
Exempel 2: Skapa en sträng med ett tal
my_string <- "100"
# Multiplicera med 2
my_string*2
## Error in my_string * 2 : non-numeric argument to binary operator
I båda exemplen svarar R att åtgärden inte kan utföras eftersom vektorn inte är numerisk. Så charachter vektorer kan innehålla siffror men de behandlas inte som numeriska värden.
Du måste använda citattecken när du refererar till element i en character vector. Här nedan skapas två vektorer som sedan kombineras till en data frame. Därefter ska vi försöka filtrera vår data frame så att den bara innehåller kvinnor.
# Skapa en vektor som innehåller kön<
sex <- c("Man", "Woman", "Man", "Woman")
# Skapa en vektor som innehåller uppmätta värden för blodtryck
blood_pressure <- c(140, 130, 120, 150)
# Slå ihop vektorerna till en dataframe med funktionen data.frame()
my_data_frame <- data.frame(sex, blood_pressure)
# Visa vår data frame
my_data_frame
sex blood_pressure
1 Man 140
2 Woman 130
3 Man 120
4 Woman 150
Nu filterar vi så att bara kvinnor är kvar. För att göra detta använder vi funktionen subset()
:
only_women <- subset(my_data_frame, sex=="Woman")
# Visa vår data frame
only_women
sex blood_pressure
2 Woman 130
4 Woman 150
Observera att Woman är angivet med citattecken (i funktionen subset()
) ovan, vilket är ett krav eftersom vektorn är en character. Om vi vill filtrera på blodtryck, som är en double, använder vi inte citattecken. Här nedan filtrerar vi så att endast rader med normalt blodtryck (mindre eller lika med 130) behålls:
only_normal_blood_pressure <- subset(my_data_frame, blood_pressure <= 130)
# Visa vår data frame
only_normal_blood_pressure
sex blood_pressure
2 Woman 130
3 Man 120
4.1.4 Logicals (boolean values, booleska värden)
Vissa variabler är binära till sin natur. Om sådana variabler kan karakteriseras som TRUE eller FALSE, kallas de logicals. Om en person är död eller levande kan betraktas som en logical. Om en person drabbas av cancer eller inte kan också klassificeras som TRUE eller FALSE. R kan även utvärdera jämförelser och returnera TRUE eller FALSE, vilket framgår av exemplet nedan:
10>1
[1] TRUE
Det går utmärkt att använda siffrorna 1/0 istället för TRUE/FALSE. Orden TRUE och FALSE intar en särställning i språket R. Om dessa ord finns i vektorer så tolkas vektorerna som logicals automatiskt. R accepterar dessutom förkortningarna T och F.
# Skapa en vektor med namn
name <- c("Adam", "Umit", "Joanna", "Sarah")
# Skapa en boolesk vektor med TRUE/FALSE om personen är död
dead <- c(TRUE, FALSE, TRUE, FALSE)
# Skapa en boolesk vektor med TRUE/FALSE om personen är gift
married <- c(F, T, F, F)
# Slå ihop vektorerna till en data frame
my_data_frame <- data.frame(name, dead, married)
# Skriv ut vår data frame
my_data_frame
name dead married
1 Adam TRUE FALSE
2 Umit FALSE TRUE
3 Joanna TRUE FALSE
4 Sarah FALSE FALSE
Som framgår ovan accepterar R förkortningarna T för TRUE och F för FALSE.
4.1.5 Complex vector, raw vector
Du kommer sannolikt aldrig att använda dessa vektorer i R, varför vi inte diskuterar dem.
4.1.6 Datum, tider och tidsintervaller
Det är mycket vanligt att arbeta med datum, tider och tidsintervaller. R, liksom flera andra språk, hanterar datum och tider som numeriska värden. Det innebär att varje datum och tidpunkt tilldelas ett numeriskt värde som sedan kan användas i analyser För att ett datum ska tilldelas ett numeriskt värde måste det finnas ett referensdatum (ett datum att utgå ifrån). I språket SAS är referensdatumet 1960-01-01 00:00:00 GMT
. I R är referensdatumet 1970-01-01 00:00:00 UTC
men detta kan justeras av användaren. Vilket referensdatum som används har som regel ingen betydelse.
Datum lagras i vektorer av klassen POSIXct eller POSIXlt, vilka faktiskt är av typen double. Om en vektor är av typen POSIXct eller POSIXt så kan den se ut som en character vektor (eftersom det kan finnas “-” eller “/” i datumet), men de är i själva verket numeriska värden av klassen POSIXct eller POSIXlt.
Nu provar vi skapa vektorer som består av datum:
# Skapa vektor med födelsedatum
birth_date <- c("1990-01-01", "1999-01-04", "2002-05-05", "2001-12-12")
# Skapa vektor med dödsdatum
death_date <- c("2005-02-02", "2009-11-14", "2018-01-01", "2011-11-09")
class(birth_date)
[1] "character"
class(death_date)
[1] "character"
Som vi ser ovan är ingen av vektorerna av typen POSIXct eller POSIXlt (båda är av typen character), vilket är förväntat eftersom vi skapade vektorerna genom att använda citattecken runt datumen. Vi behöver berätta för R att dessa vektorer är datum, vilket vi kan göra med funktioner so finns i standardinstallationen av R, eller med paketet lubridate
som innehåller enkla och effektiva funktioner för att hantera datum. Vi börjar med att använda standardfunktioner för att konvertera vektorerna till datum.
# Skapar datumobjekt med GMT (Greenwich Mean Time) som tidszon
birth_date <- as.POSIXct(birth_date)
death_date <- as.POSIXct(death_date)
class(birth_date)
[1] "POSIXct" "POSIXt"
class(death_date)
[1] "POSIXct" "POSIXt"
R har nu konverterat vektorn från character till datum (POSIXct). Vi ska nu använda funktionen difftime()
för att beräkna tidsskillnaden mellan födelsedatum och dödsdatum.
difftime(death_date, birth_date)
Time differences in days
[1] 5511.000 3967.000 5720.042 3619.000
Som framgår ovan beräknades tidsskillnaden i dagar. Vi kan beräkna tidsskillnaden i andra enheter enligt följande:
difftime(death_date, birth_date, units="secs")
Time differences in secs
[1] 476150400 342748800 494211600 312681600
difftime(death_date, birth_date, units="mins")
Time differences in mins
[1] 7935840 5712480 8236860 5211360
difftime(death_date, birth_date, units="hours")
Time differences in hours
[1] 132264 95208 137281 86856
difftime(death_date, birth_date, units="weeks")
Time differences in weeks
[1] 787.2857 566.7143 817.1488 517.0000
R använder även tidszoner, även om de flesta användarna inte beaktar detta. Exempel på tidszoner är:
- CET: Central European Time.
- CEST: Central European Summer Time.
- GMT: Greenwich Mean Time
Att hantera datum, tidszoner och tidsintervaller med standardpaketen i R kan vara komplicerat. Därför utvecklade Garrett Grolemund, Hadley Wickham och Vitalie Spinu paketet lubridate
, vilket gör hanteringen mycket enklare. Börja med att installera lubridate:
install.packages("lubridate")
Aktivera därefter paketet:
library(lubridate)
Attaching package: 'lubridate'
The following objects are masked from 'package:base':
date, intersect, setdiff, union
Lubridate lagrar datum som antalet dagar sedan referensdatumet 1970-01-01 00:00:00 GMT
. Du kan få det specifika datumet 18000 dagar sedan detta referensdatum genom att använda funktionen as_date()
:
as_date(18000)
[1] "2019-04-14"
Låt oss lagra några datum med hjälp av lubridates funktioner. Det finns många funktioner för att göra detta. Principen för dessa funktioner är som följer:
- Identifiera i vilken ordning tidselementen år (year, y), månad (month, m), dag (day, d), timme (hour, h), minut (minute, m) och sekunder (seconds, s) kommer i datumet.
- Använd den funktionen som passar ordningen på tidselementen.
I tabellen nedan ser du några exempel på olika sätt att skriva datumet 31 december år 2020, och vilken lubridate funktion som klarar att läsa in datumet:
Datumformat | Ordning på tidselement | Funktion i lubridate |
---|---|---|
2020-12-31 | YYYY-MM-DD | ymd() |
2020/12/31 | YYYY/MM/DD | ymd() |
20201231 | YYYYMMDD | ymd() |
20-12-31 | YY-MM-DD | ymd() |
201231 | YYMMDD | ymd() |
Låt oss testa det genom att skapa en data frame med tre individer, inklusive deras namn, födelsedatum, datum för första undersökningen och dödsdatum. Alla datum kommer att skrivas på olika sätt för att testa funktionen ymd()
:
# Skapa vektorer
name <- c("David", "Mohammed", "Christina")
birth_date <- ymd("1990-01-01", "1999-01-04", "2002-05-05")
examination_date <- ymd("1990.01.01", "1999.01.04", "2002.05.05")
death_date <- ymd("2005/02/02", "2009/11/14", "2018/01/01")
# Slå ihop vektorer till en data frame (tabell)
my_data <- data.frame(name, birth_date, examination_date, death_date)
# Se data frame
my_data
name birth_date examination_date death_date
1 David 1990-01-01 1990-01-01 2005-02-02
2 Mohammed 1999-01-04 1999-01-04 2009-11-14
3 Christina 2002-05-05 2002-05-05 2018-01-01
R kände alltså igen olika datumformat och konverterade alla vektorerna till datum. Funktionen sapply()
används för att tillämpa en funktion på varje kolumn i en data frame. Vi kommer använda sapply()
nu för att kontrollera vilken klass kolumnerna i my_data
har:
# Använd sapply() för att tillämpa funktionen class() på alla kolumner i my_data
sapply(my_data, class)
name birth_date examination_date death_date
"character" "Date" "Date" "Date"
Låt oss ändra ordningen på år, månad och dag i våra datum. Detta är oproblematiskt så länge vi byter funktion i lubridate:
# Dag, månad, år
dmy("30-01-2000", "25-12-2001")
[1] "2000-01-30" "2001-12-25"
# Månad, dag, år
mdy("12-25-1999", "09-29-2004")
[1] "1999-12-25" "2004-09-29"
# År, månad, dag
ymd("20181230", "20191129")
[1] "2018-12-30" "2019-11-29"
I nästa exempel lagrar vi ett datum som inkluderar ett klockslag. För att läsa detta korrekt lägger vi till bokstäverna h (timme), m (minuter) och s (sekunder) enligt följande:
ymd_hms("2011-06-04 12:00:00")
[1] "2011-06-04 12:00:00 UTC"
R tilldelade datumet tidszonen UTC. R kan hantera cirka 600 tidszoner, inklusive zonernas sommartider, vintertider och historiska kalendervariationer. Du kan få en lista över alla tidszoner genom att skriva följande:
OlsonNames()
[1] "Africa/Abidjan" "Africa/Accra"
[3] "Africa/Addis_Ababa" "Africa/Algiers"
[5] "Africa/Asmara" "Africa/Asmera"
[7] "Africa/Bamako" "Africa/Bangui"
[9] "Africa/Banjul" "Africa/Bissau"
[11] "Africa/Blantyre" "Africa/Brazzaville"
[13] "Africa/Bujumbura" "Africa/Cairo"
[15] "Africa/Casablanca" "Africa/Ceuta"
[17] "Africa/Conakry" "Africa/Dakar"
[19] "Africa/Dar_es_Salaam" "Africa/Djibouti"
[21] "Africa/Douala" "Africa/El_Aaiun"
[23] "Africa/Freetown" "Africa/Gaborone"
[25] "Africa/Harare" "Africa/Johannesburg"
[27] "Africa/Juba" "Africa/Kampala"
[29] "Africa/Khartoum" "Africa/Kigali"
[31] "Africa/Kinshasa" "Africa/Lagos"
[33] "Africa/Libreville" "Africa/Lome"
[35] "Africa/Luanda" "Africa/Lubumbashi"
[37] "Africa/Lusaka" "Africa/Malabo"
[39] "Africa/Maputo" "Africa/Maseru"
[41] "Africa/Mbabane" "Africa/Mogadishu"
[43] "Africa/Monrovia" "Africa/Nairobi"
[45] "Africa/Ndjamena" "Africa/Niamey"
[47] "Africa/Nouakchott" "Africa/Ouagadougou"
[49] "Africa/Porto-Novo" "Africa/Sao_Tome"
[51] "Africa/Timbuktu" "Africa/Tripoli"
[53] "Africa/Tunis" "Africa/Windhoek"
[55] "America/Adak" "America/Anchorage"
[57] "America/Anguilla" "America/Antigua"
[59] "America/Araguaina" "America/Argentina/Buenos_Aires"
[61] "America/Argentina/Catamarca" "America/Argentina/ComodRivadavia"
[63] "America/Argentina/Cordoba" "America/Argentina/Jujuy"
[65] "America/Argentina/La_Rioja" "America/Argentina/Mendoza"
[67] "America/Argentina/Rio_Gallegos" "America/Argentina/Salta"
[69] "America/Argentina/San_Juan" "America/Argentina/San_Luis"
[71] "America/Argentina/Tucuman" "America/Argentina/Ushuaia"
[73] "America/Aruba" "America/Asuncion"
[75] "America/Atikokan" "America/Atka"
[77] "America/Bahia" "America/Bahia_Banderas"
[79] "America/Barbados" "America/Belem"
[81] "America/Belize" "America/Blanc-Sablon"
[83] "America/Boa_Vista" "America/Bogota"
[85] "America/Boise" "America/Buenos_Aires"
[87] "America/Cambridge_Bay" "America/Campo_Grande"
[89] "America/Cancun" "America/Caracas"
[91] "America/Catamarca" "America/Cayenne"
[93] "America/Cayman" "America/Chicago"
[95] "America/Chihuahua" "America/Coral_Harbour"
[97] "America/Cordoba" "America/Costa_Rica"
[99] "America/Creston" "America/Cuiaba"
[101] "America/Curacao" "America/Danmarkshavn"
[103] "America/Dawson" "America/Dawson_Creek"
[105] "America/Denver" "America/Detroit"
[107] "America/Dominica" "America/Edmonton"
[109] "America/Eirunepe" "America/El_Salvador"
[111] "America/Ensenada" "America/Fort_Nelson"
[113] "America/Fort_Wayne" "America/Fortaleza"
[115] "America/Glace_Bay" "America/Godthab"
[117] "America/Goose_Bay" "America/Grand_Turk"
[119] "America/Grenada" "America/Guadeloupe"
[121] "America/Guatemala" "America/Guayaquil"
[123] "America/Guyana" "America/Halifax"
[125] "America/Havana" "America/Hermosillo"
[127] "America/Indiana/Indianapolis" "America/Indiana/Knox"
[129] "America/Indiana/Marengo" "America/Indiana/Petersburg"
[131] "America/Indiana/Tell_City" "America/Indiana/Vevay"
[133] "America/Indiana/Vincennes" "America/Indiana/Winamac"
[135] "America/Indianapolis" "America/Inuvik"
[137] "America/Iqaluit" "America/Jamaica"
[139] "America/Jujuy" "America/Juneau"
[141] "America/Kentucky/Louisville" "America/Kentucky/Monticello"
[143] "America/Knox_IN" "America/Kralendijk"
[145] "America/La_Paz" "America/Lima"
[147] "America/Los_Angeles" "America/Louisville"
[149] "America/Lower_Princes" "America/Maceio"
[151] "America/Managua" "America/Manaus"
[153] "America/Marigot" "America/Martinique"
[155] "America/Matamoros" "America/Mazatlan"
[157] "America/Mendoza" "America/Menominee"
[159] "America/Merida" "America/Metlakatla"
[161] "America/Mexico_City" "America/Miquelon"
[163] "America/Moncton" "America/Monterrey"
[165] "America/Montevideo" "America/Montreal"
[167] "America/Montserrat" "America/Nassau"
[169] "America/New_York" "America/Nipigon"
[171] "America/Nome" "America/Noronha"
[173] "America/North_Dakota/Beulah" "America/North_Dakota/Center"
[175] "America/North_Dakota/New_Salem" "America/Nuuk"
[177] "America/Ojinaga" "America/Panama"
[179] "America/Pangnirtung" "America/Paramaribo"
[181] "America/Phoenix" "America/Port_of_Spain"
[183] "America/Port-au-Prince" "America/Porto_Acre"
[185] "America/Porto_Velho" "America/Puerto_Rico"
[187] "America/Punta_Arenas" "America/Rainy_River"
[189] "America/Rankin_Inlet" "America/Recife"
[191] "America/Regina" "America/Resolute"
[193] "America/Rio_Branco" "America/Rosario"
[195] "America/Santa_Isabel" "America/Santarem"
[197] "America/Santiago" "America/Santo_Domingo"
[199] "America/Sao_Paulo" "America/Scoresbysund"
[201] "America/Shiprock" "America/Sitka"
[203] "America/St_Barthelemy" "America/St_Johns"
[205] "America/St_Kitts" "America/St_Lucia"
[207] "America/St_Thomas" "America/St_Vincent"
[209] "America/Swift_Current" "America/Tegucigalpa"
[211] "America/Thule" "America/Thunder_Bay"
[213] "America/Tijuana" "America/Toronto"
[215] "America/Tortola" "America/Vancouver"
[217] "America/Virgin" "America/Whitehorse"
[219] "America/Winnipeg" "America/Yakutat"
[221] "America/Yellowknife" "Antarctica/Casey"
[223] "Antarctica/Davis" "Antarctica/DumontDUrville"
[225] "Antarctica/Macquarie" "Antarctica/Mawson"
[227] "Antarctica/McMurdo" "Antarctica/Palmer"
[229] "Antarctica/Rothera" "Antarctica/South_Pole"
[231] "Antarctica/Syowa" "Antarctica/Troll"
[233] "Antarctica/Vostok" "Arctic/Longyearbyen"
[235] "Asia/Aden" "Asia/Almaty"
[237] "Asia/Amman" "Asia/Anadyr"
[239] "Asia/Aqtau" "Asia/Aqtobe"
[241] "Asia/Ashgabat" "Asia/Ashkhabad"
[243] "Asia/Atyrau" "Asia/Baghdad"
[245] "Asia/Bahrain" "Asia/Baku"
[247] "Asia/Bangkok" "Asia/Barnaul"
[249] "Asia/Beirut" "Asia/Bishkek"
[251] "Asia/Brunei" "Asia/Calcutta"
[253] "Asia/Chita" "Asia/Choibalsan"
[255] "Asia/Chongqing" "Asia/Chungking"
[257] "Asia/Colombo" "Asia/Dacca"
[259] "Asia/Damascus" "Asia/Dhaka"
[261] "Asia/Dili" "Asia/Dubai"
[263] "Asia/Dushanbe" "Asia/Famagusta"
[265] "Asia/Gaza" "Asia/Harbin"
[267] "Asia/Hebron" "Asia/Ho_Chi_Minh"
[269] "Asia/Hong_Kong" "Asia/Hovd"
[271] "Asia/Irkutsk" "Asia/Istanbul"
[273] "Asia/Jakarta" "Asia/Jayapura"
[275] "Asia/Jerusalem" "Asia/Kabul"
[277] "Asia/Kamchatka" "Asia/Karachi"
[279] "Asia/Kashgar" "Asia/Kathmandu"
[281] "Asia/Katmandu" "Asia/Khandyga"
[283] "Asia/Kolkata" "Asia/Krasnoyarsk"
[285] "Asia/Kuala_Lumpur" "Asia/Kuching"
[287] "Asia/Kuwait" "Asia/Macao"
[289] "Asia/Macau" "Asia/Magadan"
[291] "Asia/Makassar" "Asia/Manila"
[293] "Asia/Muscat" "Asia/Nicosia"
[295] "Asia/Novokuznetsk" "Asia/Novosibirsk"
[297] "Asia/Omsk" "Asia/Oral"
[299] "Asia/Phnom_Penh" "Asia/Pontianak"
[301] "Asia/Pyongyang" "Asia/Qatar"
[303] "Asia/Qostanay" "Asia/Qyzylorda"
[305] "Asia/Rangoon" "Asia/Riyadh"
[307] "Asia/Saigon" "Asia/Sakhalin"
[309] "Asia/Samarkand" "Asia/Seoul"
[311] "Asia/Shanghai" "Asia/Singapore"
[313] "Asia/Srednekolymsk" "Asia/Taipei"
[315] "Asia/Tashkent" "Asia/Tbilisi"
[317] "Asia/Tehran" "Asia/Tel_Aviv"
[319] "Asia/Thimbu" "Asia/Thimphu"
[321] "Asia/Tokyo" "Asia/Tomsk"
[323] "Asia/Ujung_Pandang" "Asia/Ulaanbaatar"
[325] "Asia/Ulan_Bator" "Asia/Urumqi"
[327] "Asia/Ust-Nera" "Asia/Vientiane"
[329] "Asia/Vladivostok" "Asia/Yakutsk"
[331] "Asia/Yangon" "Asia/Yekaterinburg"
[333] "Asia/Yerevan" "Atlantic/Azores"
[335] "Atlantic/Bermuda" "Atlantic/Canary"
[337] "Atlantic/Cape_Verde" "Atlantic/Faeroe"
[339] "Atlantic/Faroe" "Atlantic/Jan_Mayen"
[341] "Atlantic/Madeira" "Atlantic/Reykjavik"
[343] "Atlantic/South_Georgia" "Atlantic/St_Helena"
[345] "Atlantic/Stanley" "Australia/ACT"
[347] "Australia/Adelaide" "Australia/Brisbane"
[349] "Australia/Broken_Hill" "Australia/Canberra"
[351] "Australia/Currie" "Australia/Darwin"
[353] "Australia/Eucla" "Australia/Hobart"
[355] "Australia/LHI" "Australia/Lindeman"
[357] "Australia/Lord_Howe" "Australia/Melbourne"
[359] "Australia/North" "Australia/NSW"
[361] "Australia/Perth" "Australia/Queensland"
[363] "Australia/South" "Australia/Sydney"
[365] "Australia/Tasmania" "Australia/Victoria"
[367] "Australia/West" "Australia/Yancowinna"
[369] "Brazil/Acre" "Brazil/DeNoronha"
[371] "Brazil/East" "Brazil/West"
[373] "Canada/Atlantic" "Canada/Central"
[375] "Canada/Eastern" "Canada/Mountain"
[377] "Canada/Newfoundland" "Canada/Pacific"
[379] "Canada/Saskatchewan" "Canada/Yukon"
[381] "CET" "Chile/Continental"
[383] "Chile/EasterIsland" "CST6CDT"
[385] "Cuba" "EET"
[387] "Egypt" "Eire"
[389] "EST" "EST5EDT"
[391] "Etc/GMT" "Etc/GMT-0"
[393] "Etc/GMT-1" "Etc/GMT-10"
[395] "Etc/GMT-11" "Etc/GMT-12"
[397] "Etc/GMT-13" "Etc/GMT-14"
[399] "Etc/GMT-2" "Etc/GMT-3"
[401] "Etc/GMT-4" "Etc/GMT-5"
[403] "Etc/GMT-6" "Etc/GMT-7"
[405] "Etc/GMT-8" "Etc/GMT-9"
[407] "Etc/GMT+0" "Etc/GMT+1"
[409] "Etc/GMT+10" "Etc/GMT+11"
[411] "Etc/GMT+12" "Etc/GMT+2"
[413] "Etc/GMT+3" "Etc/GMT+4"
[415] "Etc/GMT+5" "Etc/GMT+6"
[417] "Etc/GMT+7" "Etc/GMT+8"
[419] "Etc/GMT+9" "Etc/GMT0"
[421] "Etc/Greenwich" "Etc/UCT"
[423] "Etc/Universal" "Etc/UTC"
[425] "Etc/Zulu" "Europe/Amsterdam"
[427] "Europe/Andorra" "Europe/Astrakhan"
[429] "Europe/Athens" "Europe/Belfast"
[431] "Europe/Belgrade" "Europe/Berlin"
[433] "Europe/Bratislava" "Europe/Brussels"
[435] "Europe/Bucharest" "Europe/Budapest"
[437] "Europe/Busingen" "Europe/Chisinau"
[439] "Europe/Copenhagen" "Europe/Dublin"
[441] "Europe/Gibraltar" "Europe/Guernsey"
[443] "Europe/Helsinki" "Europe/Isle_of_Man"
[445] "Europe/Istanbul" "Europe/Jersey"
[447] "Europe/Kaliningrad" "Europe/Kiev"
[449] "Europe/Kirov" "Europe/Kyiv"
[451] "Europe/Lisbon" "Europe/Ljubljana"
[453] "Europe/London" "Europe/Luxembourg"
[455] "Europe/Madrid" "Europe/Malta"
[457] "Europe/Mariehamn" "Europe/Minsk"
[459] "Europe/Monaco" "Europe/Moscow"
[461] "Europe/Nicosia" "Europe/Oslo"
[463] "Europe/Paris" "Europe/Podgorica"
[465] "Europe/Prague" "Europe/Riga"
[467] "Europe/Rome" "Europe/Samara"
[469] "Europe/San_Marino" "Europe/Sarajevo"
[471] "Europe/Saratov" "Europe/Simferopol"
[473] "Europe/Skopje" "Europe/Sofia"
[475] "Europe/Stockholm" "Europe/Tallinn"
[477] "Europe/Tirane" "Europe/Tiraspol"
[479] "Europe/Ulyanovsk" "Europe/Uzhgorod"
[481] "Europe/Vaduz" "Europe/Vatican"
[483] "Europe/Vienna" "Europe/Vilnius"
[485] "Europe/Volgograd" "Europe/Warsaw"
[487] "Europe/Zagreb" "Europe/Zaporozhye"
[489] "Europe/Zurich" "Factory"
[491] "GB" "GB-Eire"
[493] "GMT" "GMT-0"
[495] "GMT+0" "GMT0"
[497] "Greenwich" "Hongkong"
[499] "HST" "Iceland"
[501] "Indian/Antananarivo" "Indian/Chagos"
[503] "Indian/Christmas" "Indian/Cocos"
[505] "Indian/Comoro" "Indian/Kerguelen"
[507] "Indian/Mahe" "Indian/Maldives"
[509] "Indian/Mauritius" "Indian/Mayotte"
[511] "Indian/Reunion" "Iran"
[513] "Israel" "Jamaica"
[515] "Japan" "Kwajalein"
[517] "Libya" "MET"
[519] "Mexico/BajaNorte" "Mexico/BajaSur"
[521] "Mexico/General" "MST"
[523] "MST7MDT" "Navajo"
[525] "NZ" "NZ-CHAT"
[527] "Pacific/Apia" "Pacific/Auckland"
[529] "Pacific/Bougainville" "Pacific/Chatham"
[531] "Pacific/Chuuk" "Pacific/Easter"
[533] "Pacific/Efate" "Pacific/Enderbury"
[535] "Pacific/Fakaofo" "Pacific/Fiji"
[537] "Pacific/Funafuti" "Pacific/Galapagos"
[539] "Pacific/Gambier" "Pacific/Guadalcanal"
[541] "Pacific/Guam" "Pacific/Honolulu"
[543] "Pacific/Johnston" "Pacific/Kanton"
[545] "Pacific/Kiritimati" "Pacific/Kosrae"
[547] "Pacific/Kwajalein" "Pacific/Majuro"
[549] "Pacific/Marquesas" "Pacific/Midway"
[551] "Pacific/Nauru" "Pacific/Niue"
[553] "Pacific/Norfolk" "Pacific/Noumea"
[555] "Pacific/Pago_Pago" "Pacific/Palau"
[557] "Pacific/Pitcairn" "Pacific/Pohnpei"
[559] "Pacific/Ponape" "Pacific/Port_Moresby"
[561] "Pacific/Rarotonga" "Pacific/Saipan"
[563] "Pacific/Samoa" "Pacific/Tahiti"
[565] "Pacific/Tarawa" "Pacific/Tongatapu"
[567] "Pacific/Truk" "Pacific/Wake"
[569] "Pacific/Wallis" "Pacific/Yap"
[571] "Poland" "Portugal"
[573] "PRC" "PST8PDT"
[575] "ROC" "ROK"
[577] "Singapore" "Turkey"
[579] "UCT" "Universal"
[581] "US/Alaska" "US/Aleutian"
[583] "US/Arizona" "US/Central"
[585] "US/East-Indiana" "US/Eastern"
[587] "US/Hawaii" "US/Indiana-Starke"
[589] "US/Michigan" "US/Mountain"
[591] "US/Pacific" "US/Samoa"
[593] "UTC" "W-SU"
[595] "WET" "Zulu"
attr(,"Version")
[1] "2022f"
Låt oss ange tidszonen till GMT (Greenwich Mean Time):
ymd_hms("2011-06-04 12:00:00", tz="GMT")
[1] "2011-06-04 12:00:00 GMT"
Datum, tider och tidsintervaller diskuteras i detalj i senare kapitel.
4.1.7 Factor vector (faktor)
Faktorer är kategoriska variabler, såsom kön, hårfärg, etnicitet, sjukdomsstatus, etc. En faktor är helt enkelt en kategorisk variabel som kan ha flera nivåer. Nivåerna kan ha en inneboende ordning men det är inte nödvändigt. Många nya användare har svårt att skilja factor från character. Den viktigaste praktiska skillnaden är att i beräkningar använder R nästan alltid factor. Om en variabel är av typen character kommer R oftast att omvandla den till en factor innan beräkningen utförs. Ibland måste du själv konvertera en character till factor, vilket du gör med funktionen as.factor()
.
my_diagnoses <- c("Cancer", "Cancer", "Heart Disease", "Heart Disease", "Heart Disease")
my_diagnoses_character <- as.character(my_diagnoses)
my_diagnoses_factor <- as.factor(my_diagnoses)
Låt oss skapa en tabell för varje vektor. Tabellen redovisar hur många observationer varje nivå (kategori) har:
table(my_diagnoses_character)
my_diagnoses_character
Cancer Heart Disease
2 3
table(my_diagnoses_factor)
my_diagnoses_factor
Cancer Heart Disease
2 3
Det går alltså att tabellera (skapa en tabell) med både character och factor. Låt oss använda funktionen levels()
för att se vilka nivåer som finns i dessa vektorer:
levels(my_diagnoses_character)
NULL
levels(my_diagnoses_factor)
[1] "Cancer" "Heart Disease"
Som framgår ovan saknar en character vektor levels (nivåer). Funktionen levels()
retuernerar NULL när den tillämpas på en character vektor. När vi däremot tillämpar levels()
på en factor så får vi veta vilka nivåer som faktorn har.
Faktorer har en referensnivå (reference level)
Alla vektorer av typen factor har en referensnivå (reference level), vilket är den kategorin/nivån som alla övriga kategorier/nivåer jämförs med i olika typer av beräkningar. Referensnivån är faktiskt den första som skrivs ut när du använder levels()
. Refernsnivån för vektorn my_diagnoses_factor
är alltså Cancer
.
Du kan ändra referensnivån för en factor och detta behöver ofta göras när man skapar deskriptiva tabeller, grafer och statistiska modeller. För att förstå detta använder vi ett exempel med cancerdata. I en studie önskar man jämföra jämföra överlevnaden bland patienter med lungcancer baserat på vilket årtal individerna blev diagnostiserade. Syftet är att klargöra om överlevnaden har blivit bättre över åren och för detta ändamål skall man göra en logistisk regression där alla kalenderår skall jämföras med det sista året i studien. Tyvärr har R satt det första året (2017) som referensnivå, som framgår här nedan:
# Skapa vektor med diagnosår
cancer_diagnosis_year <- c("2020", "2022", "2019", "2017", "2022")
# Konvertera vektorn till factor
cancer_diagnosis_year <- as.factor(cancer_diagnosis_year)
# Kontrollera nivåer. Första nivån är referensnivån
levels(cancer_diagnosis_year)
[1] "2017" "2019" "2020" "2022"
Vi kan ändra detta genom att använda funktionen relevel()
, enligt följande:
# Relevel
cancer_diagnosis_year <- relevel(cancer_diagnosis_year, "2022")
# Kontrollera levels igen
levels(cancer_diagnosis_year)
[1] "2022" "2017" "2019" "2020"
4.2 Coercion (tvingad konvertering)
Du har redan sett några exempel på coercion, vilket innebär att R forcerar (tvingar) vissa konverteringar av datatyper. Den vanligaste typen av coercion inträffar i följande scenarion:
- Om en vektor innehåller en enda icke-numerisk symbol/tecken så konverteras hela vektorn till en vektor av typen character, även om det egentligen är en numerisk vektor och tecknet/symbolen hamnat där av ett misstag.
- Om en vektor endast innehåller numeriska värden kommer R konvertera den till en double.
- Om en vektor endast innehåller 0/1 kommer den konverteras till en double, även om det är avsett att vara en vektor av typen logical.
- Om en vektor endast innehåller TRUE/FALSE kommer den konverteras till en logical.
Du kan alltid konvertera vektorer med funktionerna as.numeric()
, as.factor()
, as.logical()
, as.character()
.
Matematiskt tolkas TRUE som 1 och FALSE som 0. Detta kan bekräftas genom att skapa en vektor med TRUE och FALSE och beräkna summan av vektorn med funktionen sum()
:
sum(c(TRUE, TRUE, FALSE, FALSE))
[1] 2
Du kan konvertera 0 och 1 till TRUE och FALSe enligt följande:
as.logical(c(1, 0, 1, 1))
[1] TRUE FALSE TRUE TRUE
Och vice versa:
as.numeric(c(TRUE, TRUE, FALSE, FALSE))
[1] 1 1 0 0
4.3 Attributes (attribut)
Attribut är ytterligare information eller förtydligande som adderas till vektorer eller objekt. Attribut är användbara i många sammahang. Det vanligaste attributet i R är names
, som innehåller namnen på elementen i ett objekt. I en data frame (tabell) är detta helt enkelt namnen på kolumnerna.
4.3.1 Names
Låt oss skapa en data frame med två kolumner (variabler), nämligen kön och blodtryck. Detta görs genom att först skapa två vektorer (gender
, blood_pressure
) som sedan kombineras till en data frame med funktionen data.frame()
:
gender <- c("Man", "Woman", "Man", "Woman")
blood_pressure <- c(140, 130, 120, 150)
my_data_frame <- data.frame(gender, blood_pressure)
Låt oss titta på vår data frame:
my_data_frame
gender blood_pressure
1 Man 140
2 Woman 130
3 Man 120
4 Woman 150
Vår data frame har 4 rader och 2 kolumner (variabler). Låt oss kontrollera names
(kolumnernas namn) i vår data frame:
names(my_data_frame)
[1] "gender" "blood_pressure"
Det finns två namnattribut: gender och blood_pressure.
Du kan ändra kolumnernas namn genom att ersätta informationen i names med ny information. Detta görs enligt följande:
names(my_data_frame) <- c("Sex", "Pressure")
names(my_data_frame)
[1] "Sex" "Pressure"
Det finns lyckligtvis enklare metoder för att byta namn på kolumner och dessa presenteras i senare kapitel.
Attributen kan användas för att referera till innehåll i objekt. Det innebär att du kan komma åt specifika kolumner i en data frame genom att använda attributet. För att referera till Pressure
i my_data_frame
använder du symbolen $
, enligt följande:
my_data_frame$Pressure
[1] 140 130 120 150
På samma sätt kan du skapa en ny kolumn. Nu skapar vi kolumnen Pressure_Half
genom att dividera Pressure
med 2:
my_data_frame$Pressure_Half <- my_data_frame$Pressure/2
# Se vår data frame
my_data_frame
Sex Pressure Pressure_Half
1 Man 140 70
2 Woman 130 65
3 Man 120 60
4 Woman 150 75
Så här kan man alltså skapa kolumner utifrån befintliga kolumner.
4.3.2 Dimensions
Låt oss kontrollera attrbituet dim
, som är förkortning för dimension. Denna funktion returnerar objektets dimensioner, vilket är antal rader och antal kolumner för en data frame (tabell):
dim(my_data_frame)
[1] 4 3
Funktionen dim()
returnerade talet 4 och 3, som representerar antalet rader respektive kolumner.
4.4 Matrix (matris)
Eng: singular = matrix, plural = matrices.
Sv: singular = matris, plural = matriser.
En matrix (matris) är en tvådimensionell struktur. Du skapar matriser med funktionen matrix()
. Denna funktionen har argumenten nrow (antal rader) och ncol (antal kolumner), vilka specificerar antalet rader och kolumner. Låt oss först skapa en numerisk vektor och därefter en matris av den:
# Skapa vektor med siffror
my_vector <- c(1, 2, 3, 4, 5, 6)
# Omvandla vektorn till en matris med 2 rader och 3 kolumner
my_matrix <- matrix(my_vector, nrow=2, ncol=3)
# Se matrisen
my_matrix
[,1] [,2] [,3]
[1,] 1 3 5
[2,] 2 4 6
Funktionen matrix() fyller i matrisen uppifrån och ned, en kolumn i taget. Du kan ändra detta beteende, så att den istället fyller i en rad i taget med argumentet byrow=TRUE
:
my_matrix <- matrix(my_vector, nrow=2, ncol=3, byrow=TRUE)
# Se matrisen
my_matrix
[,1] [,2] [,3]
[1,] 1 2 3
[2,] 4 5 6
En matris kan bara innehålla en enda typ av vektor. Detta är den stora skillnaden mellan matriser och data frames. En data frame kan innehålla alla typer av vektorer (factor, character, numeric, double, integer, etc).
4.5 Array
En array kan ha mer än två dimensioner. En array kan således betraktas som ett objekt som innehåller flera separata matriser. Funktionen array()
använder argumentet dim
för att specificera arrayens struktur. För att skapa en array med 2 rader, 2 kolumner och 3 dimensioner, använder du följande kommando:
my_vector <- c(1, 2, 3, 4, 5, 6)
my_array <- array(my_vector, dim=c(2, 2, 2))
# View my_array
my_array
, , 1
[,1] [,2]
[1,] 1 3
[2,] 2 4
, , 2
[,1] [,2]
[1,] 5 1
[2,] 6 2
Om en array är större än antalet element i vektorn den baseras på så kommer vektorn att återanvändas, vilket framgår av exemplet ovan (siffrorna 1 och 2 har återanvänts i andra matrisens andra kolumn).
4.6 Lists (Listor)
Listor är kraftfulla objekt eftersom de kan lagra alla typer av objekt. En lista kan alltså innehålla flera vektorer, data frames, matriser och arrayer samtidigt. Objekten tillåts även ha olika längd! Listor skapas med funktionen list()
. Låt oss skapa en lista med en vektorer av typen character, numeric och logical (notera att vektorerna har olika längd):
# Numerisk vektor
my_numbers <- c(1, 2, 3)
# Character vektor
my_characters <- c("Diabetes", "Cancer", "AIDS", "Heart failure", "Arthritis", "Depression")
# Logical vektor
my_bools <- c(TRUE, TRUE, FALSE, TRUE)
# Kombinera vektorerna till en lista
my_list <- list(my_numbers, my_characters, my_bools)
# Se listan
my_list
[[1]]
[1] 1 2 3
[[2]]
[1] "Diabetes" "Cancer" "AIDS" "Heart failure"
[5] "Arthritis" "Depression"
[[3]]
[1] TRUE TRUE FALSE TRUE
Notera följande ovan:
- Längden på vektorerna som lagras i en lista kan ha varierande längd och datatyp.
- I utskriften ovan framgår att listan innehåller 3 objekt, vilket specificeras med [[1]], [[2]] och [[3]]. För att referera till objekt i en lista används alltså dubbla hakperenteser.
En lista kan till och med innehålla en data frame. Låt oss expandera ovanstående exempel med en data frame och skriva ut listan därefter:
# Numerisk vektor
my_numbers <- c(1, 2, 3)
# Character vektor
my_characters <- c("Diabetes", "Cancer", "AIDS", "Heart failure", "Arthritis", "Depression")
# Logical vektor
my_bools <- c(TRUE, TRUE, FALSE, TRUE)
# Data frame
age <- c(1, 2, 3, 4)
sex <- c("male", "female", "male", "female")
my_data_frame <- data.frame(age, sex)
# Kombinera allt till en lista
my_list <- list(my_numbers, my_characters, my_bools, my_data_frame)
# Se listan
my_list
[[1]]
[1] 1 2 3
[[2]]
[1] "Diabetes" "Cancer" "AIDS" "Heart failure"
[5] "Arthritis" "Depression"
[[3]]
[1] TRUE TRUE FALSE TRUE
[[4]]
age sex
1 1 male
2 2 female
3 3 male
4 4 female
Det första listobjektet ([[1]]) lagrar värdena 1, 2 och 3. Det andra listobjektet ([[2]]) lagrar karaktärssträngarna Diabetes, Cancer, AIDS etc.
Listor är mycket flexibla, de kan faktiskt innehålla andra listor. Ett exempel följer:
# Create atomic vector
my_numbers <- c(1, 2, 3)
# Create a list
my_first_list <- list(c("A", "B", "C"), c(100, 200, 300))
# Create a list storing both an atomic vector and a list
my_second_list <- list(my_numbers, my_first_list)
# View my list
my_second_list
[[1]]
[1] 1 2 3
[[2]]
[[2]][[1]]
[1] "A" "B" "C"
[[2]][[2]]
[1] 100 200 300
Nu kan du se att det nya objektet innehåller tre rader men bara två objekt, men det andra objektet ([[2]]) är en lista och innehåller två objekt. Det är viktigt att notera att en lista kan innehålla alla typer av R-objekt, vilket gör listor användbara för lagring av data.
4.7 Data frames
Vi har redan sett flera data frames i exemplen ovan. En data frame liknar ett kalkylblad i Excel och Numbers. En typisk data frame har observationer på varje rad och kolumnerna utgör variabler:
Namn | Ålder | Inkomst | Utbildning | Kolesterol |
---|---|---|---|---|
Adam | 45 | 324211 | Högskola | 4.5 |
Zara | 51 | 198765 | Grundskola | 7.6 |
John | 49 | 250643 | Gymnasium | 3.2 |
I majoriteten av fallen kommer raderna utgöra observationer och kolumnerna utgöra mätvärden (variabler) på observationerna. Statistiska modeller, machine learning och andra vanliga funktioner i R kräver ofta att data finns i en data frame. Nu skapar vi tre vektorer och kombinerar dem till en data frame.
# Skapar en vektor med siffrorna 1 till 15
variable1 <- 1:15
# Använder funktionen rnorm() för att generera 15 helt slumpmässiga värden
variable2 <- rnorm(15)
# Skapar en vektor med 15 bokstäver </em>
variable3 <- c("A", "B", "W", "C", "D", "E", "A", "B", "C", "D", "E", "U", "O", "L", "E")
# Kombinerar allt till en data frame med funktionen data.frame()
my_data_frame <- data.frame(variable1, variable2, variable3)
# Se vår data frame
my_data_frame
variable1 variable2 variable3
1 1 0.61687819 A
2 2 -1.49693238 B
3 3 -0.02426337 W
4 4 0.97459121 C
5 5 -1.03211448 D
6 6 -0.57205032 E
7 7 -0.30575213 A
8 8 -0.77495326 B
9 9 -0.67784625 C
10 10 0.50121613 D
11 11 1.23014030 E
12 12 -1.84284583 U
13 13 0.16945138 O
14 14 0.91849363 L
15 15 0.69476883 E
Varje kolumn i vår data frame innehåller samma typ av data och vektorerna har samma längd. Om vektorerna inte har samma längd kommer R återvinna den mindre vektorn för att skapa en data frame.
Varför så krångligt?
I ovanstående exempel har vi skapat vektorer och data frames manuellt. Detta är onekligen tidskrävande och omständligt. När du arbetar kommer du med största sannolikhet importera en färdig data frame som du sedan analyserar. Anledningen till att vi ändå skapat vektorer och data frames manuellt är för att demonstrera hur R beter sig.
Låt oss kontrollera strukturen i vår data frame med hjälp av funktionen str()
:
str(my_data_frame)
'data.frame': 15 obs. of 3 variables:
$ variable1: int 1 2 3 4 5 6 7 8 9 10 ...
$ variable2: num 0.6169 -1.4969 -0.0243 0.9746 -1.0321 ...
$ variable3: chr "A" "B" "W" "C" ...
Enligt ovanstående är objektet av typen ‘data.farme’, med 15 observationer och 3 variabler. Det framgår att variable1
är av typen integer, variable2
är numeric och variable3
är character. När du skapar en data frame kan du specificera om du vill att R tvingar character vektorer till factors med argumentet stringsAsFactors
, enligt följande:
my_data_frame <- data.frame(variable1, variable2, variable3, stringsAsFactors = TRUE)
str(my_data_frame)
'data.frame': 15 obs. of 3 variables:
$ variable1: int 1 2 3 4 5 6 7 8 9 10 ...
$ variable2: num 0.6169 -1.4969 -0.0243 0.9746 -1.0321 ...
$ variable3: Factor w/ 9 levels "A","B","C","D",..: 1 2 9 3 4 5 1 2 3 4 ...
Nu är variable3
en factor med 9 levels (nivåer).
Data frame = df
Det är vanligt att data frame förkortas df. Du kommer se denna förkortningen ofta när du arbetar med R.