Objekter (R Objects)

Objekter i R

R bruker objekter til å lagre informasjon. Her er et enkelt objekt som bare lagrer den numeriske verdien 1:

my_number <- 1

Vi har laget et objekt med navnet my_number og tilordnet det verdien 1. Tilordningen av verdien 1 ble gjort med symbolene <-, som kalles the assignment operator, som blir tilordningsoperator på norsk. Man sier at my_number får verdien 1. Nå inneholder objektet my_number informasjon i form av en numerisk verdi. La oss spørre R hvilken type objekt my_number er:

class(my_number)
[1] "numeric"

Ifølge det ovenstående tolker R my_number som et numerisk objekt, noe som virker rimelig. La oss gjøre samme prosedyre med en tekststreng i stedet:

my_string <- "Hej! Mitt namn är Salvador."
class(my_string)
[1] "character"

Objektet my_string er et character-objekt, noe som betyr at det består av tegn og symboler. Disse to eksemplene viser at i det øyeblikket vi lager et objekt, vil R forsøke å gjette hvilken type informasjon objektet inneholder. La oss se hvordan R tolker en numerisk verdi omgitt av anførselstegn:

my_object <- "1"
class(my_object)
[1] "character"

R tolker my_object som en tegnstreng (character-objekt), noe som forklares av at tallet 1 var omsluttet av anførselstegn, noe som betyr at R antar at det er en tegnstreng vi vil lagre.

All informasjon du lagrer i ditt Environment, er et objekt. Eksempler på objekter er som følger:

  • Tabeller (dataframes) er objekter.
  • Lagrede enkeltverdier (som for eksempel my_object ovenfor) er et objekt.
  • Resultater fra regresjonsmodeller er objekter.

I prinsippet er alt du lager i R, et objekt. Nedenfor skal vi gå gjennom ulike typer objekter i R.

4.1 Atomic Vectors (Atomvektorer)

Den enkleste typen objekt i R er en atomic vector (atomvektor). Atomic vectors brukes alltid når du arbeider i R. La oss lage en atomvektor ved hjelp av funksjonen [c()](https://rdrr.io/r/base/c.html). Denne funksjonen kombinerer flere elementer for å danne en vektor. Vi gir objektet navnet my_first_vector, og det skal inneholde seks numeriske verdier:

my_first_vector <- c(1, 2, 3, 4, 5, 6)

Vi kan kontrollere om R betrakter my_first_vector som en atomic vector ved å bruke funksjonen [is.vector()](https://rdrr.io/r/base/vector.html):

## is.vector() kontrollerer om et objekt er en atomic vector
is.vector(my_first_vector)
[1] TRUE

Funksjonen [is.vector()](https://rdrr.io/r/base/vector.html) returnerte verdien TRUE, noe som betyr at my_first_vector er en atomic vector. Siden my_first_vector bare inneholder numeriske verdier, vil R betrakte den som en numerisk vektor, noe man kan kontrollere ved hjelp av funksjonen [is.numeric()](https://rdrr.io/r/base/numeric.html):

## is.numeric() kontrollerer om en atomic vector er numerisk
is.numeric(my_first_vector)
[1] TRUE

Atomic vectors har bare én dimensjon. Hver vektor kan bare lagre én type data. For å håndtere alle typer data finnes det derfor seks grunnleggende typer atomic vectors:

  • double: numeriske verdier med eller uten desimaler
  • integer: numeriske heltall (ingen desimaler)
  • character: tegn, symboler, tekst
  • logical: JA/NEI, 0/1, TRUE/FALSE
    • Synonym: logiske verdier (no), boolean (eng), boolske verdier (no).
  • complex og raw vectors finnes, men brukes i prinsippet aldri.
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 kontrollere om en vektor er noen av de ovenstående ved å bruke funksjonene [is.double()](https://rdrr.io/r/base/double.html), [is.numereric()](https://rdrr.io/r/base/numeric.html), [is.character()](https://rdrr.io/r/base/character.html), [is.logical()](https://rdrr.io/r/base/logical.html). Disse funksjonene returnerer verdien TRUE eller FALSE.

Hvis du trenger å kontrollere hvilken type vektor et objekt er, kan du bruke funksjonen [typeof()](https://rdrr.io/r/base/typeof.html). Nedenfor lager vi en numerisk vektor med desimaler, og deretter spør vi hvilken klasse og hvilken type vektoren har.

my_doubles <- c(1.2, 2.4, 32.1)
class(my_doubles)
[1] "numeric"
typeof(my_doubles)
[1] "double"

4.1.0.1 Lengden på vektorer

Lengden på en vektor er rett og slett antallet elementer i den. La oss lage en atomvektor med 5 numeriske verdier og kontrollere lengden på den:

my_values <- c(1, 2, 3, 4, 5)
length(my_values)
[1] 5

La oss lage en vektor med en lang streng for å kontrollere lengden:

my_string <- c("Det är roligt att lära sig R!")
length(my_string)
[1] 1

Lengden på denne vektoren var 1 fordi den inneholder 1 element, som var setningen “Det är roligt att lära sig R!”. La oss lage en vektor med to tekststrenger:

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

Nå har my_string 2 tekststrenger, og derfor har vektoren lengden 2.

En atomic vector kan bare lagre én type data. La oss teste dette ved å lage en vektor med både numeriske verdier, tekststrenger og logiske verdier.

## Lag en vektor med tekststrenger, numeriske verdier og boolske verdier
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 kontrollerer vektorens klasse:

## Kontroller vektorens klasse
class(mixed)
[1] "character"

Legg merke til følgende:

  1. Alle elementene ble skrevet ut med anførselstegn, noe som betyr at R har konvertert alle elementene til tekststrenger, også tallene, TRUE og FALSE. Dette kalles coercion (tvungen omforming), som betyr at en datatype ble omformet automatisk til en annen. Tallet 1 er dermed ikke lenger en numerisk verdi; det representerer bare tegnet 1. TRUE og FALSE er ikke lenger boolske verdier; de utgjør bare ordene TRUE og FALSE.
  2. Det ovenstående forklarer hvorfor funksjonen [class()](https://rdrr.io/r/base/class.html) hevder at vektoren er av typen character.
  3. Siden typen nå er character, kan du ikke lenger utføre matematiske beregninger (f.eks. beregne gjennomsnitt) på denne vektoren.

Du må være eksplisitt når du lager vektorer i R. Tallene fra 1 til 4 kan lages både som numerisk vektor og som character-vektor. For å lage en character-vektor må hvert element angis med anførselstegn:

Eksempel 1: Lag numerisk vektor

my_numbers <- c(1, 2, 3, 4)
my_numbers
[1] 1 2 3 4

Eksempel 2: Lag character-vektor

my_characters <- c("1", "2", "3", "4")
my_characters
[1] "1" "2" "3" "4"

Du kan konvertere vektorer mellom ulike typer med funksjonene [as.character()](https://rdrr.io/r/base/character.html), [as.numeric()](https://rdrr.io/r/base/numeric.html) osv.

Eksempel 3: Konverter numerisk til character

## Lager numerisk vektor
my_numbers <- c(1, 2, 3, 4)

## Konverterer numerisk vektor til character

my_characters <- as.character(my_numbers)
## Skriver ut resultatet
my_characters
[1] "1" "2" "3" "4"

Du kan altså konvertere vektorer mellom typer. La oss forsøke det motsatte, dvs. gå fra tegn til numerisk: Eksempel 4: Konverter tegn til numerisk

my_characters <- c("1", "2", "3", "4")
my_numbers <- as.numeric(my_characters)

## Print it
my_numbers
[1] 1 2 3 4

Dette lyktes fordi tallene kom i riktig rekkefølge uten anførselstegn. Hvis de virkelig er numeriske verdier nå, burde vi kunne beregne et gjennomsnitt av tallene:

mean(my_numbers)
[1] 2.5

Nå er vi sikre på at det ble riktig. Merk at konverteringer noen ganger kan gi uventede resultater. Derfor er det viktig å gjøre en eller annen form for kontroll for å fastslå at konverteringen blir som forventet.

La oss forsøke å konvertere strengen “Hej” til en numerisk verdi:

## Lag character-vektor
my_characters <- c("Hej")

## Konverter den til numerisk vektor
my_numbers <- as.numeric(my_characters)
Warning: NAs introduced by coercion
## Skriv ut resultatet
my_numbers
[1] NA

Her fikk vi i stedet advarselen “NAs introduced by coercion”. NA står for “Not Available” eller “Not Applicable” avhengig av sammenhengen. I dette tilfellet er det Not Available, som betyr at verdien mangler. Konverteringen har altså resultert i at R har tvunget verdien til NA. Når vi skriver ut objektet my_numbers, finnes det bare én eneste verdi, og den er NA. Med andre ord kan ikke R konvertere “Hej” til en numerisk verdi.

4.1.1 Double vector

En double lagrer numeriske verdier. Verdiene kan ha desimaler. R lagrer i prinsippet alltid numeriske vektorer som double, selv om de mangler desimaler. Dette kan vi kontrollere nå:

## Lag numerisk vektor uten desimaler
my_numbers <- c(1, 2, 3)
## Kontroller om den er en double
is.double(my_numbers)
[1] TRUE
## Lag numerisk vektor med desimaler
your_numbers <- c(1.1, 2.2, 3.3)

## Kontroller om den er en double
is.double(your_numbers)
[1] TRUE

Selv om objektet my_numbers bare består av heltall, vil R lagre det som en double. Vi kan kontrollere at vektoren ikke er et heltall:

is.integer(my_numbers)
[1] FALSE

4.1.2 Integer vector (heltall)

En integer vector lagrer bare heltall. Et heltall er en numerisk verdi uten desimaler. Det er usannsynlig at du trenger å arbeide med denne typen vektor, fordi double-vektoren også kan håndtere heltall. Du kan i prinsippet alltid bruke double i stedet for integer. Du trenger svært sjelden å ta hensyn til dette, fordi R gjør det automatisk. Hvis du likevel vil definere en vektor som integer, gjør du det ved å legge til bokstaven L etter tallene:

my_integers <- c(1L, 5L, 3L, 10L)
is.integer(my_integers)
[1] TRUE

Du kan også tvinge en double til integer:

## Lag en double-vektor
my_doubles <- c(1, 2, 3, 4)

## Kontroller om den er en double
is.double(my_doubles)
[1] TRUE
## Konverterer double til integer og lagrer resultatet i et nytt objekt kalt my_integers
my_integers <- as.integer(my_doubles)

## Kontroller om my_integers er en integer-vektor
is.integer(my_integers)
[1] TRUE

Å ha ulike typer vektorer er svært nyttig. Ulike vektorer brukes til ulike formål. Matematiske operasjoner er bare mulige på numeriske vektorer og logicals. Vi skal demonstrere dette ved hjelp av funksjonen [mean()](https://rdrr.io/r/base/mean.html), som beregner det matematiske gjennomsnittet av en serie numeriske verdier:

## Lager en double
my_values <- c(5, 10, 15, 20)

## Beregner gjennomsnittet og lagrer resultatet i et nytt objekt kalt my_mean
my_mean <- mean(my_values)

## Skriver ut objektet
my_mean
[1] 12.5

Tidligere nevnte vi at man kan bygge inn funksjoner i funksjoner, noe som kan spare mye plass. Nå beregner vi gjennomsnittet igjen uten å lagre nye objekter. Legg merke til hvordan funksjonen [c()](https://rdrr.io/r/base/c.html) bygges inn i funksjonen [mean()](https://rdrr.io/r/base/mean.html).

mean(c(5, 10, 15, 20))
[1] 12.5

4.1.3 Character vector (strenger)

Tekst og symboler lagres i character-vektorer. Følgende kommando lagrer en tekststreng ved å omslutte den med anførselstegn:

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)"

Vektoren my_string lagrer en streng som inneholder symboler, bokstaver og tall. Her følger en character-vektor med to strenger, hvorav den andre inneholder tall og 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 nevnt ovenfor vil tall omgitt av anførselstegn bli tolket som tegn (ikke numeriske verdier). Det fremgår av eksempelet nedenfor, der vi også bruker funksjonen [paste()](https://rdrr.io/r/base/paste.html) for å skrive ut kommentarer i resultatene:

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 viser anførselstegn ved utskrift av your_numbers for å tydeliggjøre at elementene er tekststrenger! Alle character-vektorer skrives ut med anførselstegn i R.

En tegnstreng inneholder tegn og symboler. Det er ikke mulig å utføre matematiske operasjoner på tegnstrenger, selv om de inneholder tall. La oss se to eksempler:

Eksempel 1: Lag en streng med bokstaver

my_string <- "Detta är en sträng"

## Multipliser den med 2
my_string*2
## Error in my_string * 2 : non-numeric argument to binary operator

Eksempel 2: Lag en streng med et tall

my_string <- "100"

## Multipliser med 2
my_string*2
## Error in my_string * 2 : non-numeric argument to binary operator

I begge eksemplene svarer R at operasjonen ikke kan utføres fordi vektoren ikke er numerisk. Character-vektorer kan altså inneholde tall, men de behandles ikke som numeriske verdier.

Du må bruke anførselstegn når du refererer til elementer i en character vector. Nedenfor lages to vektorer som deretter kombineres til en data frame. Deretter skal vi forsøke å filtrere vår data frame slik at den bare inneholder kvinner.

## Lag en vektor som inneholder kjønn<
sex <- c("Man", "Woman", "Man", "Woman")

## Lag en vektor som inneholder målte verdier for blodtrykk
blood_pressure <- c(140, 130, 120, 150)

## Slå sammen vektorene til en dataframe med funksjonen data.frame()
my_data_frame <- data.frame(sex, blood_pressure)

## Vis vår data frame
my_data_frame
    sex blood_pressure
1   Man            140
2 Woman            130
3   Man            120
4 Woman            150

Nå filtrerer vi slik at bare kvinner er igjen. For å gjøre dette bruker vi funksjonen [subset()](https://rdrr.io/r/base/subset.html):

only_women <- subset(my_data_frame, sex=="Woman")
## Vis vår data frame
only_women
    sex blood_pressure
2 Woman            130
4 Woman            150

Legg merke til at Woman er angitt med anførselstegn (i funksjonen [subset()](https://rdrr.io/r/base/subset.html)) ovenfor, noe som er et krav fordi vektoren er en character. Hvis vi vil filtrere på blodtrykk, som er en double, bruker vi ikke anførselstegn. Nedenfor filtrerer vi slik at bare rader med normalt blodtrykk (mindre enn eller lik 130) beholdes:

only_normal_blood_pressure <- subset(my_data_frame, blood_pressure <= 130)

## Vis vår data frame
only_normal_blood_pressure
    sex blood_pressure
2 Woman            130
3   Man            120

4.1.4 Logicals (boolean values, boolske verdier)

Noen variabler er binære av natur. Hvis slike variabler kan karakteriseres som TRUE eller FALSE, kalles de logicals. Om en person er død eller levende, kan betraktes som en logical. Om en person rammes av kreft eller ikke, kan også klassifiseres som TRUE eller FALSE. R kan også evaluere sammenligninger og returnere TRUE eller FALSE, som det fremgår av eksempelet nedenfor:

10>1
[1] TRUE

Det går utmerket å bruke tallene 1/0 i stedet for TRUE/FALSE. Ordene TRUE og FALSE har en særstilling i språket R. Hvis disse ordene finnes i vektorer, tolkes vektorene automatisk som logicals. R aksepterer dessuten forkortelsene T og F.

## Lag en vektor med navn
name <- c("Adam", "Umit", "Joanna", "Sarah")

## Lag en boolsk vektor med TRUE/FALSE for om personen er død
dead <- c(TRUE, FALSE, TRUE, FALSE)

## Lag en boolsk vektor med TRUE/FALSE for om personen er gift
married <- c(F, T, F, F)

## Slå sammen vektorene til 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 det fremgår ovenfor, aksepterer R forkortelsene T for TRUE og F for FALSE.

4.1.5 Complex vector, raw vector

Du kommer sannsynligvis aldri til å bruke disse vektorene i R, og derfor diskuterer vi dem ikke.

4.1.6 Datoer, tider og tidsintervaller

Det er svært vanlig å arbeide med datoer, tider og tidsintervaller. R, i likhet med flere andre språk, håndterer datoer og tider som numeriske verdier. Det betyr at hver dato og hvert tidspunkt tilordnes en numerisk verdi som deretter kan brukes i analyser For at en dato skal tilordnes en numerisk verdi, må det finnes en referansedato (en dato å ta utgangspunkt i). I språket SAS er referansedatoen 1960-01-01 00:00:00 GMT. I R er referansedatoen 1970-01-01 00:00:00 UTC, men dette kan justeres av brukeren. Hvilken referansedato som brukes, har som regel ingen betydning.

Datoer lagres i vektorer av klassen POSIXct eller POSIXlt, som faktisk er av typen double. Hvis en vektor er av typen POSIXct eller POSIXt, kan den se ut som en character-vektor (fordi det kan finnes “-” eller “/” i datoen), men de er i virkeligheten numeriske verdier av klassen POSIXct eller POSIXlt.

Nå prøver vi å lage vektorer som består av datoer:

## Lag vektor med fødselsdatoer
birth_date <- c("1990-01-01", "1999-01-04", "2002-05-05", "2001-12-12")

## Lag vektor med dødsdatoer
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 ovenfor, er ingen av vektorene av typen POSIXct eller POSIXlt (begge er av typen character), noe som er forventet fordi vi laget vektorene ved å bruke anførselstegn rundt datoene. Vi må fortelle R at disse vektorene er datoer, noe vi kan gjøre med funksjoner som finnes i standardinstallasjonen av R, eller med pakken lubridate, som inneholder enkle og effektive funksjoner for å håndtere datoer. Vi begynner med å bruke standardfunksjoner for å konvertere vektorene til datoer.

## Lager datoobjekter med GMT (Greenwich Mean Time) som tidssone
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 nå konvertert vektoren fra character til dato (POSIXct). Vi skal nå bruke funksjonen [difftime()](https://rdrr.io/r/base/difftime.html) for å beregne tidsforskjellen mellom fødselsdato og dødsdato.

difftime(death_date, birth_date)
Time differences in days
[1] 5511.000 3967.000 5720.042 3619.000

Som det fremgår ovenfor, ble tidsforskjellen beregnet i dager. Vi kan beregne tidsforskjellen i andre enheter på følgende måte:

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 bruker også tidssoner, selv om de fleste brukerne ikke tar hensyn til dette. Eksempler på tidssoner er:

  • CET: Central European Time.
  • CEST: Central European Summer Time.
  • GMT: Greenwich Mean Time

Å håndtere datoer, tidssoner og tidsintervaller med standardpakkene i R kan være komplisert. Derfor utviklet Garrett Grolemund, Hadley Wickham og Vitalie Spinu pakken lubridate, som gjør håndteringen mye enklere. Begynn med å installere lubridate:

install.packages("lubridate")

Aktiver deretter pakken:

library(lubridate)
Attaching package: 'lubridate'

The following objects are masked from 'package:base':
    date, intersect, setdiff, union

Lubridate lagrer datoer som antallet dager siden referansedatoen 1970-01-01 00:00:00 GMT. Du kan få den spesifikke datoen 18000 dager etter denne referansedatoen ved å bruke funksjonen [as_date()](https://lubridate.tidyverse.org/reference/as_date.html):

as_date(18000)
[1] "2019-04-14"

La oss lagre noen datoer ved hjelp av lubridates funksjoner. Det finnes mange funksjoner for å gjøre dette. Prinsippet for disse funksjonene er som følger:

  1. Identifiser i hvilken rekkefølge tidselementene år (year, y), måned (month, m), dag (day, d), time (hour, h), minutt (minute, m) og sekunder (seconds, s) kommer i datoen.
  2. Bruk den funksjonen som passer rekkefølgen på tidselementene.

I tabellen nedenfor ser du noen eksempler på ulike måter å skrive datoen 31. desember 2020 på, og hvilken lubridate-funksjon som klarer å lese inn datoen:

Datoformat Rekkefølge på tidselementer Funksjon 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()

Eksempler på datoformater og tilsvarende funksjoner i lubridate.

La oss teste det ved å lage en data frame med tre individer, inkludert navn, fødselsdato, dato for første undersøkelse og dødsdato. Alle datoene skal skrives på ulike måter for å teste funksjonen [ymd()](https://lubridate.tidyverse.org/reference/ymd.html):

## Lag 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å sammen vektorer til 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 gjenkjente altså ulike datoformater og konverterte alle vektorene til datoer. Funksjonen [sapply()](https://rdrr.io/r/base/lapply.html) brukes til å anvende en funksjon på hver kolonne i en data frame. Vi skal bruke [sapply()](https://rdrr.io/r/base/lapply.html) nå for å kontrollere hvilken klasse kolonnene i my_data har:

## Bruk sapply() for å anvende funksjonen class() på alle kolonner i my_data
sapply(my_data, class)
            name       birth_date examination_date       death_date
     "character"           "Date"           "Date"           "Date"

La oss endre rekkefølgen på år, måned og dag i datoene våre. Dette er uproblematisk så lenge vi bytter funksjon i lubridate:

## Dag, måned, år
dmy("30-01-2000", "25-12-2001")
[1] "2000-01-30" "2001-12-25"
## Måned, dag, år
mdy("12-25-1999", "09-29-2004")
[1] "1999-12-25" "2004-09-29"
## År, måned, dag
ymd("20181230", "20191129")
[1] "2018-12-30" "2019-11-29"

I neste eksempel lagrer vi en dato som inkluderer et klokkeslett. For å lese dette korrekt legger vi til bokstavene h (time), m (minutter) og s (sekunder) på følgende måte:

ymd_hms("2011-06-04 12:00:00")
[1] "2011-06-04 12:00:00 UTC"

R tilordnet datoen tidssonen UTC. R kan håndtere rundt 600 tidssoner, inkludert sonenes sommertid, vintertid og historiske kalendervariasjoner. Du kan få en liste over alle tidssoner ved å skrive følgende:

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"

La oss angi tidssonen til GMT (Greenwich Mean Time):

ymd_hms("2011-06-04 12:00:00", tz="GMT")
[1] "2011-06-04 12:00:00 GMT"

Datoer, tider og tidsintervaller diskuteres i detalj i senere kapitler.

4.1.7 Factor vector (faktor)

Faktorer er kategoriske variabler, som kjønn, hårfarge, etnisitet, sykdomsstatus osv. En faktor er rett og slett en kategorisk variabel som kan ha flere nivåer. Nivåene kan ha en iboende rekkefølge, men det er ikke nødvendig. Mange nye brukere har vanskelig for å skille factor fra character. Den viktigste praktiske forskjellen er at R nesten alltid bruker factor i beregninger. Hvis en variabel er av typen character, vil R som oftest omforme den til en factor før beregningen utføres. Noen ganger må du selv konvertere en character til factor, noe du gjør med funksjonen [as.factor()](https://rdrr.io/r/base/factor.html).

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)

La oss lage en tabell for hver vektor. Tabellen viser hvor mange observasjoner hvert 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 altså an å tabulere (lage en tabell) med både character og factor. La oss bruke funksjonen [levels()](https://rdrr.io/r/base/levels.html) for å se hvilke nivåer som finnes i disse vektorene:

levels(my_diagnoses_character)
NULL
levels(my_diagnoses_factor)
[1] "Cancer"        "Heart Disease"

Som det fremgår ovenfor, mangler en character-vektor levels (nivåer). Funksjonen [levels()](https://rdrr.io/r/base/levels.html) returnerer NULL når den anvendes på en character-vektor. Når vi derimot anvender [levels()](https://rdrr.io/r/base/levels.html) på en factor, får vi vite hvilke nivåer faktoren har.

Faktorer har et referansenivå (reference level)

Alle vektorer av typen factor har et referansenivå (reference level), som er den kategorien/det nivået som alle øvrige kategorier/nivåer sammenlignes med i ulike typer beregninger. Referansenivået er faktisk det første som skrives ut når du bruker [levels()](https://rdrr.io/r/base/levels.html). Referansenivået for vektoren my_diagnoses_factor er altså Cancer.

Du kan endre referansenivået for en factor, og dette må ofte gjøres når man lager deskriptive tabeller, grafer og statistiske modeller. For å forstå dette bruker vi et eksempel med kreftdata. I en studie ønsker man å sammenligne overlevelsen blant pasienter med lungekreft basert på hvilket årstall individene ble diagnostisert. Formålet er å klarlegge om overlevelsen har blitt bedre over årene, og for dette formålet skal man gjøre en logistisk regresjon der alle kalenderår skal sammenlignes med det siste året i studien. Dessverre har R satt det første året (2017) som referansenivå, som det fremgår nedenfor:

## Lag vektor med diagnoseår
cancer_diagnosis_year <- c("2020", "2022", "2019", "2017", "2022")

## Konverter vektoren til factor
cancer_diagnosis_year <- as.factor(cancer_diagnosis_year)

## Kontroller nivåer. Første nivå er referansenivået
levels(cancer_diagnosis_year)
[1] "2017" "2019" "2020" "2022"

Vi kan endre dette ved å bruke funksjonen [relevel()](https://rdrr.io/r/stats/relevel.html), på følgende måte:

## Relevel
cancer_diagnosis_year <- relevel(cancer_diagnosis_year, "2022")

## Kontroller levels igjen
levels(cancer_diagnosis_year)
[1] "2022" "2017" "2019" "2020"

4.2 Coercion (tvungen konvertering)

Du har allerede sett noen eksempler på coercion, som betyr at R tvinger frem visse konverteringer av datatyper. Den vanligste typen coercion inntreffer i følgende scenarier:

  • Hvis en vektor inneholder ett eneste ikke-numerisk symbol/tegn, konverteres hele vektoren til en vektor av typen character, selv om det egentlig er en numerisk vektor og tegnet/symbolet har havnet der ved en feil.
  • Hvis en vektor bare inneholder numeriske verdier, vil R konvertere den til en double.
  • Hvis en vektor bare inneholder 0/1, vil den bli konvertert til en double, selv om den er ment å være en vektor av typen logical.
  • Hvis en vektor bare inneholder TRUE/FALSE, vil den bli konvertert til en logical.

Du kan alltid konvertere vektorer med funksjonene [as.numeric()](https://rdrr.io/r/base/numeric.html), [as.factor()](https://rdrr.io/r/base/factor.html), [as.logical()](https://rdrr.io/r/base/logical.html), [as.character()](https://rdrr.io/r/base/character.html).

Matematisk tolkes TRUE som 1 og FALSE som 0. Dette kan bekreftes ved å lage en vektor med TRUE og FALSE og beregne summen av vektoren med funksjonen [sum()](https://rdrr.io/r/base/sum.html):

sum(c(TRUE, TRUE, FALSE, FALSE))
[1] 2

Du kan konvertere 0 og 1 til TRUE og FALSE på følgende måte:

as.logical(c(1, 0, 1, 1))
[1]  TRUE FALSE  TRUE  TRUE

Og omvendt:

as.numeric(c(TRUE, TRUE, FALSE, FALSE))
[1] 1 1 0 0

4.3 Attributes (attributter)

Attributter er tilleggsinformasjon eller presiseringer som legges til vektorer eller objekter. Attributter er nyttige i mange sammenhenger. Det vanligste attributtet i R er names, som inneholder navnene på elementene i et objekt. I en data frame (tabell) er dette rett og slett navnene på kolonnene.

4.3.1 Names

La oss lage en data frame med to kolonner (variabler), nemlig kjønn og blodtrykk. Dette gjøres ved først å lage to vektorer (gender, blood_pressure) som deretter kombineres til en data frame med funksjonen [data.frame()](https://rdrr.io/r/base/data.frame.html):

gender <- c("Man", "Woman", "Man", "Woman")
blood_pressure <- c(140, 130, 120, 150)
my_data_frame <- data.frame(gender, blood_pressure)

La oss se 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 og 2 kolonner (variabler). La oss kontrollere names (kolonnenes navn) i vår data frame:

names(my_data_frame)
[1] "gender"    "blood_pressure"

Det finnes to navneattributter: gender og blood_pressure.

Du kan endre kolonnenes navn ved å erstatte informasjonen i names med ny informasjon. Dette gjøres på følgende måte:

names(my_data_frame) <- c("Sex", "Pressure")
names(my_data_frame)
[1] "Sex"      "Pressure"

Heldigvis finnes det enklere metoder for å endre navn på kolonner, og disse presenteres i senere kapitler.

Attributtene kan brukes til å referere til innhold i objekter. Det betyr at du kan få tilgang til bestemte kolonner i en data frame ved å bruke attributtet. For å referere til Pressure i my_data_frame bruker du symbolet $, på følgende måte:

my_data_frame$Pressure
[1] 140 130 120 150

På samme måte kan du lage en ny kolonne. Nå lager vi kolonnen Pressure_Half ved å dividere 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

Slik kan man altså lage kolonner ut fra eksisterende kolonner.

4.3.2 Dimensions

La oss kontrollere attributtet dim, som er en forkortelse for dimension. Denne funksjonen returnerer objektets dimensjoner, som er antall rader og antall kolonner for en data frame (tabell):

dim(my_data_frame)
[1] 4 3

Funksjonen [dim()](https://rdrr.io/r/base/dim.html) returnerte tallene 4 og 3, som representerer henholdsvis antallet rader og kolonner.

4.4 Matrix (matrise)

Eng: entall = matrix, flertall = matrices.

No: entall = matrise, flertall = matriser.

En matrix (matrise) er en todimensjonal struktur. Du lager matriser med funksjonen [matrix()](https://rdrr.io/r/base/matrix.html). Denne funksjonen har argumentene nrow (antall rader) og ncol (antall kolonner), som spesifiserer antallet rader og kolonner. La oss først lage en numerisk vektor og deretter en matrise av den:

## Lag vektor med tall
my_vector <- c(1, 2, 3, 4, 5, 6)

## Gjør om vektoren til en matrise med 2 rader og 3 kolonner
my_matrix <- matrix(my_vector, nrow=2, ncol=3)

## Se matrisen
my_matrix
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6

Funksjonen matrix() fyller ut matrisen ovenfra og ned, én kolonne om gangen. Du kan endre denne oppførselen, slik at den i stedet fyller ut én rad om gangen, 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 matrise kan bare inneholde én enkelt type vektor. Dette er den store forskjellen mellom matriser og data frames. En data frame kan inneholde alle typer vektorer (factor, character, numeric, double, integer osv.).

4.5 Array

En array kan ha mer enn to dimensjoner. En array kan dermed betraktes som et objekt som inneholder flere separate matriser. Funksjonen [array()](https://rdrr.io/r/base/array.html) bruker argumentet dim for å spesifisere arrayens struktur. For å lage en array med 2 rader, 2 kolonner og 3 dimensjoner bruker du følgende 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

Hvis en array er større enn antallet elementer i vektoren den er basert på, vil vektoren bli gjenbrukt, som det fremgår av eksempelet ovenfor (tallene 1 og 2 er gjenbrukt i den andre matrisens andre kolonne).

4.6 Lists (Lister)

Lister er kraftige objekter fordi de kan lagre alle typer objekter. En liste kan altså inneholde flere vektorer, data frames, matriser og arrayer samtidig. Objektene kan til og med ha ulik lengde! Lister lages med funksjonen [list()](https://rdrr.io/r/base/list.html). La oss lage en liste med vektorer av typen character, numeric og logical (legg merke til at vektorene har ulik lengde):

## 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)

## Kombiner vektorene til en liste
my_list <- list(my_numbers, my_characters, my_bools)

## Se listen
my_list
[[1]]
[1] 1 2 3
[[2]]
[1] "Diabetes"      "Cancer"        "AIDS"          "Heart failure"
[5] "Arthritis"     "Depression"
[[3]]
[1]  TRUE  TRUE FALSE  TRUE

Legg merke til følgende ovenfor:

  • Vektorene som lagres i en liste, kan ha varierende lengde og datatype.
  • I utskriften ovenfor fremgår det at listen inneholder 3 objekter, noe som angis med [1[1], [2[2] og [3[3]. For å referere til objekter i en liste brukes altså doble hakeparenteser.

En liste kan til og med inneholde en data frame. La oss utvide eksempelet ovenfor med en data frame og skrive ut listen etterpå:

## 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)

## Kombiner alt til en liste
my_list <- list(my_numbers, my_characters, my_bools, my_data_frame)

## Se listen
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ørste listeobjektet ([1[1]) lagrer verdiene 1, 2 og 3. Det andre listeobjektet ([2[2]) lagrer tegnstrengene Diabetes, Cancer, AIDS osv.

Lister er svært fleksible, de kan faktisk inneholde andre lister. Et eksempel følger:

## 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

Nå kan du se at det nye objektet inneholder tre rader, men bare to objekter, og det andre objektet ([2[2]) er en liste og inneholder to objekter. Det er viktig å merke seg at en liste kan inneholde alle typer R-objekter, noe som gjør lister nyttige for lagring av data.

4.7 Data frames

Vi har allerede sett flere data frames i eksemplene ovenfor. En data frame ligner et regneark i Excel og Numbers. En typisk data frame har observasjoner på hver rad, og kolonnene utgjør variabler:

Navn Alder Inntekt Utdanning Kolesterol
Adam 45 324211 Høyskole 4.5
Zara 51 198765 Grunnskole 7.6
John 49 250643 Videregående skole 3.2

Eksempel på data frame.

I de fleste tilfeller vil radene utgjøre observasjoner og kolonnene utgjøre måleverdier (variabler) for observasjonene. Statistiske modeller, machine learning og andre vanlige funksjoner i R krever ofte at data ligger i en data frame. Nå lager vi tre vektorer og kombinerer dem til en data frame.

## Lager en vektor med tallene 1 til 15
variable1 <- 1:15

## Bruker funksjonen rnorm() for å generere 15 helt tilfeldige verdier
variable2 <- rnorm(15)

## Lager en vektor med 15 bokstaver </em>
variable3 <- c("A", "B", "W", "C", "D", "E", "A", "B", "C", "D", "E", "U", "O", "L", "E")

## Kombinerer alt til en data frame med funksjonen 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

Hver kolonne i vår data frame inneholder samme type data, og vektorene har samme lengde. Hvis vektorene ikke har samme lengde, vil R resirkulere den korteste vektoren for å lage en data frame.

Hvorfor så komplisert?

I eksemplene ovenfor har vi laget vektorer og data frames manuelt. Dette er unektelig tidkrevende og omstendelig. Når du arbeider, vil du med all sannsynlighet importere en ferdig data frame som du deretter analyserer. Grunnen til at vi likevel har laget vektorer og data frames manuelt, er for å demonstrere hvordan R oppfører seg.

La oss kontrollere strukturen i vår data frame ved hjelp av funksjonen [str()](https://rdrr.io/r/utils/str.html):

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" ...

Ifølge det ovenstående er objektet av typen ‘data.farme’, med 15 observasjoner og 3 variabler. Det fremgår at variable1 er av typen integer, variable2 er numeric og variable3 er character. Når du lager en data frame, kan du spesifisere om du vil at R skal tvinge character-vektorer til factors, med argumentet stringsAsFactors, på følgende måte:

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 ...

Nå er variable3 en factor med 9 levels (nivåer).

Ikon av et programvindu med tre fargede knapper og grønne kodelinjer på mørk bakgrunn

Data frame = df

Det er vanlig at data frame forkortes df. Du kommer til å se denne forkortelsen ofte når du arbeider med R.