Chapter 5 Bearbejdning dag 1

5.1 Hvad er Tidyverse?

Tidyverse er en samling af pakker i R, som man bruger til at bearbejde datasæt. Formålet er ikke nødvendigvis at erstatte funktionaliteten af base-pakken, men til at bygge på den. Som vi kommer til at se i detaljer, tidyverse deler faktisk meget af den samme tankegang bag ggplot2 - men i stedet for at bruge + til at bygge komponenter op i et plot, bruger man %>% (udtales ‘pipe’) til at tilknytte de forskellige funktioner til hinanden.

Most common tidyverse packages

Læringsmålene til i dag

I skal være i stand til at:

  • Beskrive generelle hvad R-pakken Tidyverse kan benyttes til.
  • Beskrive en tibble og genkende når et datasæt er betragtet som “tidy”.
  • Benytte nogle vigtige Tidyverse-verbs til at bearbejde data (filter(),select(), mutate(), rename(), arrange(), recode()).
  • Bruge %>% til at forbinde Tidyverse-verber sammen og at overføre data til et plot.

5.2 Video ressourcer

  • Begynd ved at læse “Principper med ‘tidy data’” og ‘Lidt om tibbles’ nedenunder, og så se følgende videoer.

  • Video 1 - rydde op i datasættet titanic med select() og drop_na()

Link her hvis det ikke virker nedenunder: https://player.vimeo.com/video/706266697

  • Video 2 - tidyverse verber: select og filter

Link her hvis det ikke virker nedenunder: https://player.vimeo.com/video/705136725

  • Video 3 - flere tidyverse verber
    • Lave en ny kolon med mutate()
    • Ændre variabelnavne med rename()
    • Ændre på værdierne med recode()
    • Ændre rækkefølgen af observationerne med arrange()
    • Bruge tidyverse kommandoer som input i ggplot2()

Link her hvis det ikke virker nedenunder: https://player.vimeo.com/video/706266885

5.3 Oversigt over pakker

Lad os starte med at indlæse pakken tidyverse. Vær opmærksom på, at har du ikke pakken på din computer, kan det tage lidt tid at installere - det er pga. de mange pakke der tidyverse er afhængig af, der enten skal også installeres eller opdateres. Hvis har pakken installeret men oplever problemer tjek om du har det seneste versioner af pakkerne og R på dit system.

#install.packages("tidyverse)
library(tidyverse)

Du kan se, at det faktisk er ikke kun én, men otte pakke som er blevet indlæst. Man kan godt indlæse alle pakke individuelt ved at bruge fk. library(dplyr), men det er meget bekvemt at indlæse alle på samme tid med brugen af library(tidyverse). Her er nogle beskrivelser af de pakker:

pakke korte beskrivelse
readr indlæse data
ggplot2 plot data
tibble lave “tibbles” - tidyverse’s svar på datarammer (data.frame).
tidyr skifte imellem data forms (fk. ‘long’ > ‘wide’ format, eller omvendt)
purrr functional programming, gentalelse
dplyr manipulere tibbles - beholde delmængder, skabe nye variabler, beregne oversigtsstatistikker osv.
stringr manipulere strings (ikke brugt i dette kursus)
forcats FOR CATegorical data (factors); håndtere faktor variabler

Man kan også indlæse alle pakke individuelt ved at bruge fk. library(dplyr), men det er meget bekvemt bare at indlæse alle på samme tid med brugen af library(tidyverse).

5.4 Principper med ‘tidy data’

Idéen bag tidyverse er, at hvis alle datasæt følger præcis den samme struktur, så er det enkelt datasæt ligefrem at bearbejde til præcis som vi gerne vil have det. Datasæt som har den struktur hedder “tidy data”. For at betragte et datasæt som “tidy”, må det opfylde tre kriterie:

  • Hver variabel i datasættet har sin egen kolonne
  • Hver observation i datasættet har sin egen række
  • Hver værdi i datasættet få sin egen cell

Iris er et godt eksempel af tidy data:

data(iris)
head(iris)
##   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
## 1          5.1         3.5          1.4         0.2  setosa
## 2          4.9         3.0          1.4         0.2  setosa
## 3          4.7         3.2          1.3         0.2  setosa
## 4          4.6         3.1          1.5         0.2  setosa
## 5          5.0         3.6          1.4         0.2  setosa
## 6          5.4         3.9          1.7         0.4  setosa

Hver variabel (Sepal.Length, Sepal.Width, Petal.Length, Petal.Width og Species) har sin egen kolon, og hver observation (e.g. 1,2,3, osv.) har sin egen række. Derudover har hver cell sin egen data værdi og det er dermed meget klart at læse og forstå dataframen ved øjnene.

Principper af tidy data

Det er tilfældet, at de fleste af datasæt i dette kursus hører til “tidy data”, især i disse notater, hvor vi benytter en del af indbygget datasæt. Nogle gange kan det dog være, at vi er nødt til at gøre noget, til at lave et datasæt om til en “tidy datasæt”. R-pakker dplyr og tidyr er velegnet til at hjælpe med at transformere et datasæt til en, der er “tidy”, og bagefter kan man forsætte i den sædvanlige måde med at analyse datasættet. Bemærk at bare fordi et datasæt er “tidy”, betyder det ikke nødvendigvis, at det er klart til at analysere, for der kan godt være, at man har bruge for at bearbejde videre på det første - igen med pakkerne dplyr og tidyr.

5.5 Lidt om tibbles

En tibble er det tidyverse svar på en data.frame fra base-R. De ligner hinanden meget og derfor behøver man ikke tænk for meget over forskellen, men der er nogle opdateret aspekter i en tibble - for eksempel bruger en tibble ikke row.names, og når man visualiserer en tibble i R Markdown, få man lidt ekstra oplysninger, såsom dimensioner og data typer. Bemærk, at de fleste tidyverse funktioner fungerer lige så godt uanset om man har en tibble eller en data.frame. Bemærk, at jeg vedligeholder ordet ‘dataframe’ indenfor almindelig tekst.

Man kan lave sin egen tibble på samme måde som en data.frame.

tibble(x=1:3,y=c("a","b","c"))
## # A tibble: 3 × 2
##       x y    
##   <int> <chr>
## 1     1 a    
## 2     2 b    
## 3     3 c

Man kan også lave en tribble, som er den samme som en tibble men har en lidt anderledes måde at indsætte data på. For eksempel er følgende tilsvarende til den overstående tibble:

tribble(~x, ~y,
       1, "a",
       2, "b",
       3, "c")
## # A tibble: 3 × 2
##       x y    
##   <dbl> <chr>
## 1     1 a    
## 2     2 b    
## 3     3 c

Man kan lave en data.frame om til en tibble som i følgende:

as_tibble(iris)
## # A tibble: 150 × 5
##    Sepal.Length Sepal.Width Petal.Length Petal.Width Species
##           <dbl>       <dbl>        <dbl>       <dbl> <fct>  
##  1          5.1         3.5          1.4         0.2 setosa 
##  2          4.9         3            1.4         0.2 setosa 
##  3          4.7         3.2          1.3         0.2 setosa 
##  4          4.6         3.1          1.5         0.2 setosa 
##  5          5           3.6          1.4         0.2 setosa 
##  6          5.4         3.9          1.7         0.4 setosa 
##  7          4.6         3.4          1.4         0.3 setosa 
##  8          5           3.4          1.5         0.2 setosa 
##  9          4.4         2.9          1.4         0.2 setosa 
## 10          4.9         3.1          1.5         0.1 setosa 
## # … with 140 more rows

De fleste tidyverse koder fungerer lige så godt uanset om man har en tibble eller en data.frame.

5.6 Transition fra base til tidyverse

Jeg introducerer tidyverse gennem et meget berømt datasæt som hedder titanic - det er ikke biologiske data men er stadigvæk ret interessant, og sjovt at manipulere på.

titanic er brugt som en del af en åben konkurrence på hjemmesiden Kaggle, hvor mindst 31.000 personer indtil videre har arbejdet på at lave den bedste model til at forudsige, hvem der overlever katastrofen - linket er her, hvor du kan også læse om baggrunden til datasættet https://www.kaggle.com/c/titanic.

5.6.1 Om Titanic datasæt

Man kan downloade datasættet, der hedder titanic_train, direkte fra Kaggle, men der er faktisk en R-pakke, der hedder titanic som gøre det mere bekvemt:

#install.packages("titanic") #hvis ikke allerede installerede
library(titanic)

Her er beskrivelsen for pakken:

titanic is an R package containing data sets providing information on the fate of passengers on the fatal maiden voyage of the ocean liner “Titanic”, summarized according to economic status (class), sex, age and survival. These data sets are often used as an introduction to machine learning on Kaggle.

Vi vil gerne bruge titanic_train fordi det er datasættet, der bliver brugt på Kaggle til at træne maskinelærings modeller (som bliver testet på titanic_test for at evaluere, hvor god modellen er). Til at gøre tingene nemmere, lad os bare omdøb titanic_train til titanic og anvende glimpse, der er fra pakken dplyr, på datasættet.

titanic <- as_tibble(titanic_train)
glimpse(titanic)
## Rows: 891
## Columns: 12
## $ PassengerId <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,…
## $ Survived    <int> 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1…
## $ Pclass      <int> 3, 1, 3, 1, 3, 3, 1, 3, 3, 2, 3, 1, 3, 3, 3, 2, 3, 2, 3, 3…
## $ Name        <chr> "Braund, Mr. Owen Harris", "Cumings, Mrs. John Bradley (Fl…
## $ Sex         <chr> "male", "female", "female", "female", "male", "male", "mal…
## $ Age         <dbl> 22, 38, 26, 35, 35, NA, 54, 2, 27, 14, 4, 58, 20, 39, 14, …
## $ SibSp       <int> 1, 1, 0, 1, 0, 0, 0, 3, 0, 1, 1, 0, 0, 1, 0, 0, 4, 0, 1, 0…
## $ Parch       <int> 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 5, 0, 0, 1, 0, 0, 0…
## $ Ticket      <chr> "A/5 21171", "PC 17599", "STON/O2. 3101282", "113803", "37…
## $ Fare        <dbl> 7.2500, 71.2833, 7.9250, 53.1000, 8.0500, 8.4583, 51.8625,…
## $ Cabin       <chr> "", "C85", "", "C123", "", "", "E46", "", "", "", "G6", "C…
## $ Embarked    <chr> "S", "C", "S", "S", "S", "Q", "S", "S", "S", "C", "S", "S"…

Jeg har også kopieret de variable beskrivelser her:

  • PassengerId: unique index for each passenger
  • Survived: Whether or not the passenger survived. 0 = No, 1 = Yes.
  • Pclass: Ticket class: 1 = 1st Class, 2 = 2nd Class, 3 = 3rd Class.
  • Name: A character string containing the name of each passenger.
  • Sex: Character strings for passenger sex (“male”/ “female”).
  • Age: Age in years.
  • SibSp: The number of siblings/spouses aboard the titanic with the passenger
  • Parch: The number of parents/children aboard the titanic with the passenger
  • Ticket: Another character string containing the ticket ID of the passenger.
  • Fare: The price paid for tickets in pounds Sterling (Keep in mind that unskilled workers made around 1 pound a week - these were expensive tickets!)
  • Cabin: The cabin number of the passengers (character).
  • Embarked: Where passengers boarded the titanic. C = Cherbourg, Q = Queenstown, S = Southampton).

5.6.2 Titanic: oprydning

Der er faktisk nogle rengøring i datasættet vi skal tage os af, før vi kan komme videre med analysen. Vi kan se fra glimpse(titanic) ovenpå at der er 891 observationer. De fleste (687) passagerer har faktisk ingenting for variabel Cabin:

sum(titanic$Cabin=="") #ingenting for variabelen 'cabin'
## [1] 687

Andre har mere end én cabin. Det ser ikke særlig tidy ud, og man kan hellere ikke forestille sig at få meget insigt fra variablen, så vi vælger at fjerne hele kolon med funktionen select():

titanic_no_cabin <- select(titanic, -Cabin) 

select() er en af de kerne funktioner i tidyverse - her angiver vi, hvilke kolonner vi gerne vil beholde eller fjerne fra datasættet. I dette tilfælde har vi specificeret -Cabin, som betyder, at vi ikke vil have variablen Cabin med, men gerne vil beholde resten af kolonnerne. Prøv selv at køre select(titanic, Cabin) i stedet for - så får vi kun Cabin og fjerner resten af vores variabler.

glimpse(titanic_no_cabin)
## Rows: 891
## Columns: 11
## $ PassengerId <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17,…
## $ Survived    <int> 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1, 0, 1…
## $ Pclass      <int> 3, 1, 3, 1, 3, 3, 1, 3, 3, 2, 3, 1, 3, 3, 3, 2, 3, 2, 3, 3…
## $ Name        <chr> "Braund, Mr. Owen Harris", "Cumings, Mrs. John Bradley (Fl…
## $ Sex         <chr> "male", "female", "female", "female", "male", "male", "mal…
## $ Age         <dbl> 22, 38, 26, 35, 35, NA, 54, 2, 27, 14, 4, 58, 20, 39, 14, …
## $ SibSp       <int> 1, 1, 0, 1, 0, 0, 0, 3, 0, 1, 1, 0, 0, 1, 0, 0, 4, 0, 1, 0…
## $ Parch       <int> 0, 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 5, 0, 0, 1, 0, 0, 0…
## $ Ticket      <chr> "A/5 21171", "PC 17599", "STON/O2. 3101282", "113803", "37…
## $ Fare        <dbl> 7.2500, 71.2833, 7.9250, 53.1000, 8.0500, 8.4583, 51.8625,…
## $ Embarked    <chr> "S", "C", "S", "S", "S", "Q", "S", "S", "S", "C", "S", "S"…

Næste tjekker vi efter NA i datasættet. NA er hvordan R betegner manglende værdier. Man kan se i følgende, mens de fleste variabler ikke har NA værdier, har variablen Age 177 NA.

colSums(is.na(titanic_no_cabin))
## PassengerId    Survived      Pclass        Name         Sex         Age 
##           0           0           0           0           0         177 
##       SibSp       Parch      Ticket        Fare    Embarked 
##           0           0           0           0           0

I dette tilfælde vælger jeg at fjerne alle passagerer som har NA i stedet for deres alder. Til dette formål bruger jeg funktionen drop_na, som fjerner alle observationer, der har NA i mindst èn variabel.

titanic_clean <- drop_na(titanic_no_cabin)
colSums(is.na(titanic_clean))
## PassengerId    Survived      Pclass        Name         Sex         Age 
##           0           0           0           0           0           0 
##       SibSp       Parch      Ticket        Fare    Embarked 
##           0           0           0           0           0

Nu kan vi tjekke igen, hvor mange observationer og variabel vi har tilbage.

glimpse(titanic_clean)
## Rows: 714
## Columns: 11
## $ PassengerId <int> 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19…
## $ Survived    <int> 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1…
## $ Pclass      <int> 3, 1, 3, 1, 3, 1, 3, 3, 2, 3, 1, 3, 3, 3, 2, 3, 3, 2, 2, 3…
## $ Name        <chr> "Braund, Mr. Owen Harris", "Cumings, Mrs. John Bradley (Fl…
## $ Sex         <chr> "male", "female", "female", "female", "male", "male", "mal…
## $ Age         <dbl> 22, 38, 26, 35, 35, 54, 2, 27, 14, 4, 58, 20, 39, 14, 55, …
## $ SibSp       <int> 1, 1, 0, 1, 0, 0, 3, 0, 1, 1, 0, 0, 1, 0, 0, 4, 1, 0, 0, 0…
## $ Parch       <int> 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 5, 0, 0, 1, 0, 0, 0, 0…
## $ Ticket      <chr> "A/5 21171", "PC 17599", "STON/O2. 3101282", "113803", "37…
## $ Fare        <dbl> 7.2500, 71.2833, 7.9250, 53.1000, 8.0500, 51.8625, 21.0750…
## $ Embarked    <chr> "S", "C", "S", "S", "S", "S", "S", "S", "C", "S", "S", "S"…

Vi har beholdt 714 observationer og 11 variabler, og datasættet opfylder kriteren for at være tidy.

5.6.3 Pipe

Man kan faktisk gøre den samme som i ovenstående ved at bruge pipe %>%:

titanic_clean <- titanic %>% # we take the titanic dataset
    select(-Cabin) %>% # select the bits we want
    drop_na() # then remove the NAs

Man bruger pipe %>% til at kombinere adskillige tidyverse funktioner i den samme kommando - linjen slutter med %>%, der fortæller, at vi skal bruge resultatet fra den linje som inputtet i den næste linje. Logikken er således, at vi starter med en dataframe, gør dernæst én ting ad gangen, og så slutter med en ny dataframe (som vi kan gemme med <-).

Bemærk, at processen ligner den, man bruger i ggplot2, men forskellen er at man bruger %>% i stedet for + i denne ramme. Bemærk også her, at ligesom i ggplot2, skriver jeg koden over flere linjer. Det er ikke et krav men det gøre det nemmere at læse og forstå koden.

For at illustrerer logikken, kan man se, at følgende to linjer er tilsvarende:

#take x and apply some function f
f(x)    #traditional approach
x %>% f #tidyverse approach

I begge tilfælde starter vi med x, og så anvender vi funktionen f med x som argument - en kæmpe fordel med den tidyverse løsning er, at når man har flere funktioner, slipper man for at anvende mange parenteser, og rækkefølgen man skriver funktionerne læses fra venstre til højre og ikke omvendt, se for eksempel følgende:

#take x, apply f, then apply g, then apply h
h(g(f(x)))          #traditional approach
x %>% f %>% g %>% h #tidyverse approach

På sammen måde i vores titanic oprydning kan man både pakke funktionen select() ind i funktionen drop_na(), eller bruge den tidyverse løsning, ligesom i nedenstående - de to giver det tilsvarende resultat: første bruger vi select() til at fjerne kolonnen Cabin, og så bruger vi drop_na() til at fjerne alle række med mindste én NA .

titanic_clean <- drop_na(select(titanic,-Cabin))

titanic_clean <- titanic %>% 
    select(-Cabin) %>%
    drop_na() 

5.7 Bearbejdning af data: dplyr

Pakken dplyr er nok den meste brugbare pakke til at bearbejde dataframes. Jeg gennemgår nogle af de meste almindelige muligheder med pakken, og der er også en “cheatsheet” som du kan downloade som reference: https://github.com/rstudio/cheatsheets/raw/master/data-transformation.pdf. Jeg tager afsæt i følgende funktioner, og dækker flere gennem de forskellige øvelese og øvrige emner.

dplyr verbs beskrivelse
select() udvælge kolonner (variabler)
filter() udvælge rækker (observationer)
arrange() sortere rækker
mutate() tilføje eller ændre eksisterende kolonner
rename() ændre variabler navne
recode() ændre selve data
group_by() dele datasættet op efter en variabel
summarise() aggregere rækker, findes ofte tilknyttet til group_by()

Bemærk, at alle disse funktioner tager udgangspunkt i en dataframe, og man får altid en ny dataframe som outputtet. Ved at kunne bruge disse funktioner og kombinere dem (ved hjælp af %>%), har man godt styr på bearbejdningen af datarammer.

5.7.1 dplyr verbs: select()

Som vi lige har set i ovenstående, med select() udvælger man bestemte variabler. Vi kan vælger at beholde, fjerne eller andre rækkefølgen af variablerne i dataframe. Som eksempel, her beholder vi kun variablerne Name og Age:

titanic_clean %>% 
  select(Name, Age) %>%
  glimpse()
## Rows: 714
## Columns: 2
## $ Name <chr> "Braund, Mr. Owen Harris", "Cumings, Mrs. John Bradley (Florence …
## $ Age  <dbl> 22, 38, 26, 35, 35, 54, 2, 27, 14, 4, 58, 20, 39, 14, 55, 2, 31, …

Hvis vi gerne vil fjerne en variabel fra en dataframe, kan vi bruge et minustegn. I nedenstående fjerner vi Name og Age fra dataframe:

titanic_clean %>% 
  select(-Name, -Age) %>%
  glimpse()
## Rows: 714
## Columns: 9
## $ PassengerId <int> 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19…
## $ Survived    <int> 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1…
## $ Pclass      <int> 3, 1, 3, 1, 3, 1, 3, 3, 2, 3, 1, 3, 3, 3, 2, 3, 3, 2, 2, 3…
## $ Sex         <chr> "male", "female", "female", "female", "male", "male", "mal…
## $ SibSp       <int> 1, 1, 0, 1, 0, 0, 3, 0, 1, 1, 0, 0, 1, 0, 0, 4, 1, 0, 0, 0…
## $ Parch       <int> 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 5, 0, 0, 1, 0, 0, 0, 0…
## $ Ticket      <chr> "A/5 21171", "PC 17599", "STON/O2. 3101282", "113803", "37…
## $ Fare        <dbl> 7.2500, 71.2833, 7.9250, 53.1000, 8.0500, 51.8625, 21.0750…
## $ Embarked    <chr> "S", "C", "S", "S", "S", "S", "S", "S", "C", "S", "S", "S"…

5.7.1.1 Hjælper funktioner til select()

Hjælper funktioner til funktionen select() kan være brugbare hvis du gerne vil udvælge bestemte variabler efter nogle kriterier. Jeg har samlet nogle (men ikke alle mulige!) funktioner nedenfor og inddrager eksempler i problemstillingerne.

select helper beskrivelse
starts_with() starts with a prefix
ends_with() ends with a prefix
contains() contains a literal string
matches() matches a regular expression
num_range() a numerical range like x01, x02, x03.
one_of() variables in character vector.
everything() all variables.
where() fk. takes a function and returns all variables for which the function returns TRUE:

For eksempel:

titanic_clean %>% select(starts_with("P"))
## # A tibble: 714 × 3
##    PassengerId Pclass Parch
##          <int>  <int> <int>
##  1           1      3     0
##  2           2      1     0
##  3           3      3     0
##  4           4      1     0
##  5           5      3     0
##  6           7      1     0
##  7           8      3     1
##  8           9      3     2
##  9          10      2     0
## 10          11      3     1
## # … with 704 more rows

Særligt brugbar i statistik statistisk metoder der kræver kun numeriske variabler er where() når kombinerede med is.numeric. Eksempelvis i følgende kode udvælger man kun numeriske variabler fra datasættet titanic_clean:

titanic_clean %>% select(where(is.numeric))
## # A tibble: 714 × 7
##    PassengerId Survived Pclass   Age SibSp Parch  Fare
##          <int>    <int>  <int> <dbl> <int> <int> <dbl>
##  1           1        0      3    22     1     0  7.25
##  2           2        1      1    38     1     0 71.3 
##  3           3        1      3    26     0     0  7.92
##  4           4        1      1    35     1     0 53.1 
##  5           5        0      3    35     0     0  8.05
##  6           7        0      1    54     0     0 51.9 
##  7           8        0      3     2     3     1 21.1 
##  8           9        1      3    27     0     2 11.1 
##  9          10        1      2    14     1     0 30.1 
## 10          11        1      3     4     1     1 16.7 
## # … with 704 more rows

5.7.2 dplyr verbs: filter()

Med funktionen select() udvælger man bestemte variabler. Man anvender til gengæld funktionen filter() til at udvælge bestemte observationer (rækker) fra dataframe. I nedenstående beholder jeg rækkerne, hvor variablen Age er lig med 50. Bemærk, at vi bevarer alle variabler i dataframe.

titanic_clean %>% 
  filter(Age == 50) %>%
  glimpse()
## Rows: 10
## Columns: 11
## $ PassengerId <int> 178, 260, 300, 435, 459, 483, 527, 545, 661, 724
## $ Survived    <int> 0, 1, 1, 0, 1, 0, 1, 0, 1, 0
## $ Pclass      <int> 1, 2, 1, 1, 2, 3, 2, 1, 1, 2
## $ Name        <chr> "Isham, Miss. Ann Elizabeth", "Parrish, Mrs. (Lutie Davis)…
## $ Sex         <chr> "female", "female", "female", "male", "female", "male", "f…
## $ Age         <dbl> 50, 50, 50, 50, 50, 50, 50, 50, 50, 50
## $ SibSp       <int> 0, 0, 0, 1, 0, 0, 0, 1, 2, 0
## $ Parch       <int> 0, 1, 1, 0, 0, 0, 0, 0, 0, 0
## $ Ticket      <chr> "PC 17595", "230433", "PC 17558", "13507", "F.C.C. 13531",…
## $ Fare        <dbl> 28.7125, 26.0000, 247.5208, 55.9000, 10.5000, 8.0500, 10.5…
## $ Embarked    <chr> "C", "S", "C", "S", "S", "S", "S", "C", "S", "S"

Man kan også vælge intervaller - for eksempel hvis man vil vælge alle som er i halvtredserne.

titanic_clean %>% 
  filter(Age >= 50 & Age < 60) %>%
  head()
## # A tibble: 6 × 11
##   PassengerId Survived Pclass Name          Sex     Age SibSp Parch Ticket  Fare
##         <int>    <int>  <int> <chr>         <chr> <dbl> <int> <int> <chr>  <dbl>
## 1           7        0      1 "McCarthy, M… male     54     0     0 17463  51.9 
## 2          12        1      1 "Bonnell, Mi… fema…    58     0     0 113783 26.6 
## 3          16        1      2 "Hewlett, Mr… fema…    55     0     0 248706 16   
## 4          95        0      3 "Coxon, Mr. … male     59     0     0 364500  7.25
## 5         125        0      1 "White, Mr. … male     54     0     1 35281  77.3 
## 6         151        0      2 "Bateman, Re… male     51     0     0 S.O.P… 12.5 
## # … with 1 more variable: Embarked <chr>

Man kan også kombinere betingelser fra forskellige kolonner, for eksempel i nedenstående vælger vi alle personer som er kvinder og som rejste ved første klasse.

titanic_clean %>% 
    filter(Sex == 'female' & Pclass == 1) %>%
    head()
## # A tibble: 6 × 11
##   PassengerId Survived Pclass Name          Sex     Age SibSp Parch Ticket  Fare
##         <int>    <int>  <int> <chr>         <chr> <dbl> <int> <int> <chr>  <dbl>
## 1           2        1      1 Cumings, Mrs… fema…    38     1     0 PC 17…  71.3
## 2           4        1      1 Futrelle, Mr… fema…    35     1     0 113803  53.1
## 3          12        1      1 Bonnell, Mis… fema…    58     0     0 113783  26.6
## 4          53        1      1 Harper, Mrs.… fema…    49     1     0 PC 17…  76.7
## 5          62        1      1 Icard, Miss.… fema…    38     0     0 113572  80  
## 6          89        1      1 Fortune, Mis… fema…    23     3     2 19950  263  
## # … with 1 more variable: Embarked <chr>

Vi kan også inddrage flere symboler. For eksempel i nedenståenden vælger vi personer som er kvinder og som rejste i enten første eller anden klass og som er i trediverne. Huske at tilføje runde parenteser omkring de to Pclass - prøv selv at fjerne dem og se, hvad der sker.

titanic_clean %>% 
    filter(Sex == 'female' & (Pclass == 1 | Pclass == 2) & Age %in% c(30:39)) %>%
    glimpse()
## Rows: 43
## Columns: 11
## $ PassengerId <int> 2, 4, 62, 99, 191, 212, 216, 219, 231, 258, 259, 270, 310,…
## $ Survived    <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1…
## $ Pclass      <int> 1, 1, 1, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 2…
## $ Name        <chr> "Cumings, Mrs. John Bradley (Florence Briggs Thayer)", "Fu…
## $ Sex         <chr> "female", "female", "female", "female", "female", "female"…
## $ Age         <dbl> 38, 35, 38, 34, 32, 35, 31, 32, 35, 30, 35, 35, 30, 31, 30…
## $ SibSp       <int> 1, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0…
## $ Parch       <int> 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0…
## $ Ticket      <chr> "PC 17599", "113803", "113572", "231919", "234604", "F.C.C…
## $ Fare        <dbl> 71.2833, 53.1000, 80.0000, 23.0000, 13.0000, 21.0000, 113.…
## $ Embarked    <chr> "C", "S", "", "S", "S", "S", "C", "C", "S", "S", "C", "S",…

5.7.3 Comparitiver reference

Her er en tabel af comparitiver (kopirede fra grundlæggende R) - de er brugbare i både filter() og i baseR (fordi koncepten bag er den samme, bare tilgang er ænderledes).

comparitive beskrivelse
< less than
> greater than
<= less than or equal to
>= greater than or equal to
== equal to
!= not equal to
& and
%in% in
| or

5.7.4 Kombinere filter() og select()

Man kan også kombinere både filter() og select() i samme kommando, som i følgende:

titanic_clean %>% 
    filter(Sex == 'female' & (Pclass == 1 | Pclass == 2) & Age %in% c(30:39)) %>%
    select(Name, Fare)  %>% 
    glimpse()
## Rows: 43
## Columns: 2
## $ Name <chr> "Cumings, Mrs. John Bradley (Florence Briggs Thayer)", "Futrelle,…
## $ Fare <dbl> 71.2833, 53.1000, 80.0000, 23.0000, 13.0000, 21.0000, 113.2750, 7…

Bemærk at man bør passe på rækkefølgen, som man anvender de forskellige funktioner. For eksempel hvis man bytter rundt filter() og select() i ovenstående, få man en advarsel - prøv selv at køre følgende:

##virker ikke!!!!!#####
titanic_clean %>% 
    select(Name, Fare)  %>% 
    filter(Sex == 'female' & (Pclass == 1 | Pclass == 2) & Age %in% c(30:39)) %>%
    glimpse()

Det er fordi, hvis man første vælger at beholde variablerne Name og Age, så findes de andre variabler ikke mere i de resulterende dataframe, som bliver dernæst brugt i funktionen filter() - man kan derfor ikke benytte funktionen filter() på variablerne Pclass,Sex og Age.

5.7.5 dplyr verbs: mutate()

Man kan avende funktionen mutate() til at tilføje en ny variable til en dataframe. I nedenstående tilføjer jeg en ny variabel med navnet Adult, der angiver om personen kan betragtes som en voksen (hvis vedkommende er mindst 18 år gammel).

titanic_with_Adult <- titanic_clean %>% 
    mutate(Adult = Age>=18)

titanic_with_Adult %>% select(Adult) %>% glimpse 
## Rows: 714
## Columns: 1
## $ Adult <lgl> TRUE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, FALSE, FALSE, T…

#Så kan man se, at der er 601 voksne og 113 børn som passagerere på skibet.

Bemærk her, at jeg gemmer resultatet som en ny dataframe, der hedder titanic_with_Adult, og derefter bruger jeg glimpse() på det nye objekt titanic_with_Adult for at se, hvordan min nye dataframe ser ud. I forudgående eksempler havde jeg ikke gemt resultatet - bare brugt glimpse() for at se resultatet på skærmen. Hvis du gerne vil bruge din resulterende dataframe videre, så skal du husk at gemme den (med brugen af <- tegn)

funktionen ifelse() indenfor mutate()

Jeg kan oprette variablen Adult sådan at den er mere informativ end bare TRUE eller FALSE. Jeg anvender funktionen ifelse(), der giver mulighed for at angive, at jeg gerne vil have teksten “adult” hvis udsagnet Age>=18 er TRUE, og hvis FALSE vil jeg have teksten “child”:

ifelse(Age>=18,"adult","child")

Fuktionen ifelse() bruges indenfor funktionen mutate(), fordi vi er i gang med at oprette en ny variable Adult - ifelse() giver bare mulighed for at fortælle, hvordan den nye variablen skal ser ud.

titanic_clean %>% 
    mutate(Adult = ifelse(Age>=18,"adult","child")) %>%
    select(Age,Adult) %>%
    glimpse()
## Rows: 714
## Columns: 2
## $ Age   <dbl> 22, 38, 26, 35, 35, 54, 2, 27, 14, 4, 58, 20, 39, 14, 55, 2, 31,…
## $ Adult <chr> "adult", "adult", "adult", "adult", "adult", "adult", "child", "…

Så er variablen lidt mere informativ end før.

5.7.6 rename()

Man kan bruge rename() til at ændre navnet på en eller flere variabler i datasættet. Som eksempel bruger jeg rename() til at give en variable navnet Years i stedet for Age (bemærk at variablen Age findes ikke længere).

titanic_clean %>%
  rename(Years = Age) %>%
  glimpse()
## Rows: 714
## Columns: 11
## $ PassengerId <int> 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19…
## $ Survived    <int> 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1…
## $ Pclass      <int> 3, 1, 3, 1, 3, 1, 3, 3, 2, 3, 1, 3, 3, 3, 2, 3, 3, 2, 2, 3…
## $ Name        <chr> "Braund, Mr. Owen Harris", "Cumings, Mrs. John Bradley (Fl…
## $ Sex         <chr> "male", "female", "female", "female", "male", "male", "mal…
## $ Years       <dbl> 22, 38, 26, 35, 35, 54, 2, 27, 14, 4, 58, 20, 39, 14, 55, …
## $ SibSp       <int> 1, 1, 0, 1, 0, 0, 3, 0, 1, 1, 0, 0, 1, 0, 0, 4, 1, 0, 0, 0…
## $ Parch       <int> 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 5, 0, 0, 1, 0, 0, 0, 0…
## $ Ticket      <chr> "A/5 21171", "PC 17599", "STON/O2. 3101282", "113803", "37…
## $ Fare        <dbl> 7.2500, 71.2833, 7.9250, 53.1000, 8.0500, 51.8625, 21.0750…
## $ Embarked    <chr> "S", "C", "S", "S", "S", "S", "S", "S", "C", "S", "S", "S"…

Man kan også ændre navne på flere kolonner samtidigt - for eksempel, i følgende laver jeg nogle oversættelsesarbejde:

titanic_clean_dansk <- titanic_clean %>%
  rename(Overlevede = Survived,
         Navn = Name,
         Klasse = Pclass)

Så du kan se, at jeg har ændrede de variabler navne. Jeg kalder den nye dataframe for titanic_clean_dansk, så jeg min danske udgave er blevet gemt et sted.

Man kan også gøre sådan, at man har kun små bogstaver i de variabler navne. Jeg benytter den danske version, og Jeg anvender rename_with() og specificerer tolower.

titanic_clean_dansk %>%
  rename_with(tolower)  %>% #all variable names are lower case only
  glimpse() 
## Rows: 714
## Columns: 11
## $ passengerid <int> 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19…
## $ overlevede  <int> 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 1…
## $ klasse      <int> 3, 1, 3, 1, 3, 1, 3, 3, 2, 3, 1, 3, 3, 3, 2, 3, 3, 2, 2, 3…
## $ navn        <chr> "Braund, Mr. Owen Harris", "Cumings, Mrs. John Bradley (Fl…
## $ sex         <chr> "male", "female", "female", "female", "male", "male", "mal…
## $ age         <dbl> 22, 38, 26, 35, 35, 54, 2, 27, 14, 4, 58, 20, 39, 14, 55, …
## $ sibsp       <int> 1, 1, 0, 1, 0, 0, 3, 0, 1, 1, 0, 0, 1, 0, 0, 4, 1, 0, 0, 0…
## $ parch       <int> 0, 0, 0, 0, 0, 0, 1, 2, 0, 1, 0, 0, 5, 0, 0, 1, 0, 0, 0, 0…
## $ ticket      <chr> "A/5 21171", "PC 17599", "STON/O2. 3101282", "113803", "37…
## $ fare        <dbl> 7.2500, 71.2833, 7.9250, 53.1000, 8.0500, 51.8625, 21.0750…
## $ embarked    <chr> "S", "C", "S", "S", "S", "S", "S", "S", "C", "S", "S", "S"…

Prøv også at erstatte tolower med toupper.

5.7.7 dplyr verbs: recode()

Med recode() kan man ændre hvordan en variable ser ud - fk. male/female kan ændres til 0/1, som i følgende.

 titanic_clean %>%
   mutate(Sex = recode(Sex,  "male" = 0, "female" = 1)) %>%
   select(PassengerId,Name,Sex) %>% glimpse()
## Rows: 714
## Columns: 3
## $ PassengerId <int> 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19…
## $ Name        <chr> "Braund, Mr. Owen Harris", "Cumings, Mrs. John Bradley (Fl…
## $ Sex         <dbl> 0, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 1, 1, 0, 1, 0, 0, 1…

Bemærk den måde, at funktionen recode() er blevet brugt indenfor funktionen mutate(): jeg lavede en ny variable af samme navn, men med ændret værdier indenfor variablen.

Hvis vi gerne vil skifter omvendt fra 0/1 til male/female er vi nødt til at skrive 1 / 0 for at specificie at vi har værdier som er tal, og vi gerne vil kalde dem for nogle andet (“male”/“female” i dette tilfælde):

#recodes variable Sex and then recodes it back to original form again
 titanic_clean %>%
   mutate(Sex = recode(Sex,  male = 1, female = 0)) %>%
   mutate(Sex = recode(Sex,  `1` = "male", `0` = "female")) %>% #note use of `` in the numbers 
   select(PassengerId,Name,Sex) %>% glimpse()
## Rows: 714
## Columns: 3
## $ PassengerId <int> 1, 2, 3, 4, 5, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 19…
## $ Name        <chr> "Braund, Mr. Owen Harris", "Cumings, Mrs. John Bradley (Fl…
## $ Sex         <chr> "male", "female", "female", "female", "male", "male", "mal…

5.7.8 dplyr verbs: arrange()

Man anvender arrange() for at vælge rækkefølgen på observationerne. I nedenstående tager vi datarammen titanic_clean og arrangerer observationer efter variablen Fare. Det sker således at, personer som betalt mindst er på toppen af de resultarende dataramme, og personer som betalt mest er på bunden.

# Arrange by increasing Fare
titanic_clean %>%
  arrange(Fare) %>%
  glimpse()
## Rows: 714
## Columns: 11
## $ PassengerId <int> 180, 264, 272, 303, 598, 807, 823, 379, 873, 327, 844, 819…
## $ Survived    <int> 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0…
## $ Pclass      <int> 3, 1, 3, 3, 3, 1, 1, 3, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3…
## $ Name        <chr> "Leonard, Mr. Lionel", "Harrison, Mr. William", "Tornquist…
## $ Sex         <chr> "male", "male", "male", "male", "male", "male", "male", "m…
## $ Age         <dbl> 36.0, 40.0, 25.0, 19.0, 49.0, 39.0, 38.0, 20.0, 33.0, 61.0…
## $ SibSp       <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0…
## $ Parch       <int> 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0…
## $ Ticket      <chr> "LINE", "112059", "LINE", "LINE", "LINE", "112050", "19972…
## $ Fare        <dbl> 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 4.…
## $ Embarked    <chr> "S", "S", "S", "S", "S", "S", "S", "C", "S", "S", "C", "S"…

Hvis man gerne vil få det omvendt - at personer som betalt mest er på toppen af datarammen, kan man bruge desc() omkring Fare, som i nedenstående:

# Arrange by decreasing Fare
titanic_clean %>%
  arrange(desc(Fare)) %>%
  glimpse()
## Rows: 714
## Columns: 11
## $ PassengerId <int> 259, 680, 738, 28, 89, 342, 439, 312, 743, 119, 300, 381, …
## $ Survived    <int> 1, 1, 1, 0, 1, 1, 0, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1…
## $ Pclass      <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ Name        <chr> "Ward, Miss. Anna", "Cardeza, Mr. Thomas Drake Martinez", …
## $ Sex         <chr> "female", "male", "male", "male", "female", "female", "mal…
## $ Age         <dbl> 35.00, 36.00, 35.00, 19.00, 23.00, 24.00, 64.00, 18.00, 21…
## $ SibSp       <int> 0, 0, 0, 3, 3, 3, 1, 2, 2, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1…
## $ Parch       <int> 0, 1, 0, 2, 2, 2, 4, 2, 2, 1, 1, 0, 0, 0, 2, 1, 0, 1, 2, 1…
## $ Ticket      <chr> "PC 17755", "PC 17755", "PC 17755", "19950", "19950", "199…
## $ Fare        <dbl> 512.3292, 512.3292, 512.3292, 263.0000, 263.0000, 263.0000…
## $ Embarked    <chr> "C", "C", "C", "S", "S", "S", "S", "C", "C", "C", "C", "C"…

5.8 Visualisering: bruge som input i ggplot2

Efter man har lavet bearbejdning med tidyverse kommandoer, kan man specificere de resulterende dataframe som data i funktionen ggplot(). Man benytter %>% til at forbinde de dpylr kommandoer med den ggplot funktion, og I dette tilfælde behøver man ikke at angive navnet på datasættet indenfor funktionen ggplot. I nedenstående eksempel tager jeg udgangspunkt i titanic_clean og så laver jeg et barplot som viser antallet af passagerer som rejste i hver af de tre klass.

titanic_clean %>% 
  ggplot(aes(x=Pclass,fill=as.factor(Pclass))) + 
  geom_bar(stat="count") +
  theme_minimal()

Jeg gør det lidt mere kompliceret i følgende, ved at tage titanic_clean, lave en ny kolon der hedder Adult, og så bruge den resulterende dataframe med funktionen ggplot, hvor jeg laver et plot med Adult på x-aksen for at tælle op antallet af voksne og børn.

titanic_clean %>% 
   mutate(Adult = ifelse(Age>=18,"Adult","Child")) %>% 
   ggplot(aes(x=Adult,fill=Adult)) + 
   geom_bar(stat="count") + 
   theme_minimal()

Så viser det, at der var 600 Adults og lidt over 100 Children ombord skibet.

5.9 Misc funktioner som er nyttige at vide

5.9.1 Pull

I tidyverse arbejder vi meget med dataframes - tilgagen er således at man tager udgangspunkt i en dataframe, får en dataframe som resultat og så arbejde videre på den dataframe. Nogle gange kan det dog være at man gerne vil udtrække en variabel som vector fra en dataframe, fk. hvis man gerne vil bruge den i en bestemt statistik metode.

Se følgende eksempel, hvor man udtrække variable Age for “male” og “female” (variablen Sex) og bruge resulterende vectorer i en t-test sammenhæng:

ages_male <- titanic_clean %>% filter(Sex=="male") %>% pull(Age)
ages_female <- titanic_clean %>% filter(Sex=="female") %>% pull(Age)
t.test(ages_male,ages_female)
## 
##  Welch Two Sample t-test
## 
## data:  ages_male and ages_female
## t = 2.5259, df = 560.05, p-value = 0.01181
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  0.6250732 4.9967983
## sample estimates:
## mean of x mean of y 
##  30.72664  27.91571

Så kan man se at mænd og kvinder har signifikant forskellige alder i gennemsnit (hvor mændene er ældre en kvinderne).

5.9.2 Slice

Med funktionen Slice kan man kigge på nogle bestemte observationer, for eksempel, viser følgende de to passagerer der betalt mest for billeten (variable Fare).

titanic %>% 
  arrange(desc(Fare)) %>%
  select(Name,Age) %>% 
  slice(1,2)
## # A tibble: 2 × 2
##   Name                                 Age
##   <chr>                              <dbl>
## 1 Ward, Miss. Anna                      35
## 2 Cardeza, Mr. Thomas Drake Martinez    36

Se udvidet muligheder her: https://dplyr.tidyverse.org/reference/slice.html

5.10 Problemstillinger

Problem 1) Lav quizzen på Absalon - “Quiz - tidyverse - part 1”


Vi øver os med titanic. Inlæs datasættet og lav overstående oprydningen med følgende kode:

library(tidyverse)
library(titanic)
titanic <- as_tibble(titanic_train)

titanic_clean <- titanic %>% 
    select(-Cabin) %>% 
    drop_na() %>% 
    mutate(Adult = ifelse(Age>=18,"adult","child")) %>%
    mutate(Survived = recode(Survived,  `1` = "yes", `0` = "no")) 
    
glimpse(titanic_clean) #take a look!

Problem 2) select(). Fjern variablen Name fra titanic_clean (du behøver ikke at gemme din nye dataframe).

titanic_clean %>% 
    select(...) #redigere her
  • Tilføj også glimpse() for at se et overblik (man kan også bruge head())

Problem 3) select(). Lave en ny dataframe fra titanic_clean med kun variabler Name, Pclass og Fare.

  • Gør det en forskel, hvilke rækkefølger man skriver Name, Pclass og Fare?

Problem 4) select() og hjælper funktoner. I stedet for at specificere bestemt kolonner navn, skriv starts_with("S") indenfor select(). Hvad sker der?

  • Prøv også contains("ar")

  • Prøv også -any_of(c("Survived","Pclass","FavouriteColour")) og -all_of(c("Survived","Pclass","FavouriteColour")

    • i tilfældet af all_of skal alle variablerne i vectoren c("Survived","Pclass","FavouriteColour") være i datasættet, ellers får man en advarsal.
    • i tilfældet af any_of gælder det alle variabler fra vectoren c("Survived","Pclass","FavouriteColour") der er i datasættet, og resten bliver ignoreret.
  • Prøv også matches("^S[i|u]") - kan du gisner på hvad det betyder (se nedenunder)?


Problem 5) filter(). Lave en ny dataframe fra titanic_clean med alle passagerer som er mellem 10 og 15 og rejst enten første eller anden klass.

  • Prøv at tilføje %>% count() til kommandoen - Hvor mange observationer er der i den nye dataframe?

Problem 6) filter() og select() : kombinering med %>%

Lave en ny dataramme fra titanic_clean med alle passagerer som er “male” og overlevede (variablen Survived er “yes”), og udvælg kun kolonner Name, Age og Fare.


Problem 7) filter() og select() kombinering med %>%

Lave en ny dataramme fra titanic_clean med kun variabler Name og Age og dernæst specificere kun de passagerer som er over 60.

  • Få man så den samme sæt observationer hvis du skriver dine select() og filter() funktionerne omvendt her? Hvorfor?

Problem 8) Mutate(). Lave en ny dataframe fra titanic_clean som hedder FareRounded og viser Fare rundet til det nærmest integar (hint: benyt funktionen round()).


Problem 9) Mutate() og ifelse(). Lave en ny dataramme fra titanic_clean med en ny kolon som hedder Family som angiver TRUE hvis Parch er ikke nul, ellers FALSE.

  • Anvende ifelse til at gøre variablen mere intuitiv - “Family” og “Not family”.

Problem 10) Mutate() og ifelse()

Kig en gang til på beskrivelsen af følgende to variabler i datasættet:

SibSp: The number of siblings/spouses aboard the titanic with the passenger

Parch: The number of parents/children aboard the titanic with the passenger

  • Lav en ny variabel Solo som viser “Yes” hvis passageren rejste alene, og “No” hvis passageren rejste med andre.
  • Brug mutate igen til at lave den nye variabel om til at være en factor.
  • Gem også dit output (som titanic_clean igen) så du kan bruge din nye variable videre i næste spørgsmål.
titanic_clean <- titanic_clean %>%  ... 

Problem 11) pull() og t.test() Betalte passagererne der rejste alene (variablen Solo fra sidste problem) den samme i gennemsnit for deres billet (variablen Fare) end passagererne der ikke rejste alene? Lav et t.test (anvend pull() til at udtrække hensigtsmæssige vectorer - se også eksempel i kursusnotaterne)

t.test(titanic_clean %>% filter(Solo=="Yes") %>% pull(Fare),
       titanic_clean %>% filter(Solo=="No") %>% pull(Fare) )
## 
##  Welch Two Sample t-test
## 
## data:  titanic_clean %>% filter(Solo == "Yes") %>% pull(Fare) and titanic_clean %>% filter(Solo == "No") %>% pull(Fare)
## t = -6.9703, df = 573.64, p-value = 8.724e-12
## alternative hypothesis: true difference in means is not equal to 0
## 95 percent confidence interval:
##  -35.57536 -19.93377
## sample estimates:
## mean of x mean of y 
##  22.64421  50.39878

Problem 12) Recode() I variablen Embarked:

  • C står for Cherbourg
  • Q står for Queenstown
  • S står for Southampton

a) Anvend recode (indenfor mutate) til at ændre værdierne i variablen Embarked således at man får de fulde navne af de steder folk gik ombord skibet, i stedet for kun den første bogstav. Gem også dit output (som titanic_clean igen) så du kan bruge din nye variable videre.

b) Erstat recode med recode_factor og sammenlign datatypen af variablen Embarked i din nye dataframe.

c) Prøv at tilføje funktionen count() for at tælle op hvor mange gik om bord i de forskellige steder.

  • Prøv også med to variabler indenfor count() - Solo og Embarked

Resultatet ser sådan ud:

## # A tibble: 7 × 3
##   Solo  Embarked          n
##   <fct> <fct>         <int>
## 1 No    "Southampton"   229
## 2 No    "Queenstown"      9
## 3 No    "Cherbourg"      72
## 4 Yes   "Southampton"   325
## 5 Yes   "Queenstown"     19
## 6 Yes   "Cherbourg"      58
## 7 Yes   ""                2

d) Man kan se, at der er to passagerer hvor der ikke er noget skrevet i Embarked. + Rejste de alene? + Lav en ny dataframe med de to passagerer fjernet fra datasættet.


Problem 13) Arrange(). Lave en ny dataramme fra titanic_clean med observationerne arrangerede således at de yngst er på toppen og ældste er på bunden. Kig på resultatet - hvad kan du fortælle om den yngste passager ombord skibet Titanic?

  • Hvad kan du fortælle om den ældste passager ombord skibet? Overlevede de? Hvad med de andre ældste passagerer?

Problem 14) Arrange() og kombinering med andre verber. Lave en ny dataramme fra titanic_clean med kun personer med SibSp>0 og som gik ombord skibet i Southampton, arrangere de resulterende observationer efter Fare (højeste på toppen) og udvælg kun kolonnerne Name, Age og Fare.


Problem 15) Rename. Fra titanic_clean udvælg kun variabler Survived,Ticket, og Name og ændre deres navne til Overlevede, Billet og Navn.

  • Gør variabler navne til store bogstaver ved at anvende rename_with().

Problem 16) Lave et plot. Fra titanic_clean bruge filter() til at lave en ny dataramme kun med personer under 30 og bruge den til at lave et barplot som viser antallet af personer opdelt efter Pclass. Bruge følgende struktur for koden:

titanic_clean %>% 
  filter(...) %>% #rediger linjen
  ggplot(aes(...)) + .... #tilføj plot

Problem 17) Lave et plot. Fra titanic_clean, bruge mutate() til at lave et nyt kolon der hedder with_siblings_spouses der er TRUE hvis SibSp ikke er nul. Brug den til at lave boxplots som viser Fare på y-aksen og with_siblings_spouses på x-aksen.

  • Ekstra: Ændre skalen på y-aksen for at gøre plottet klarer at fortolke.

5.11 Kommentarer

  • matches("^S[i|u]") betyder
    • ^S variabel navn skal starter med en S
    • [i|u] den næste bogstav i variabel navnet skal være enten i eller u
  • OBS det er ikke vigtigt at lære pattern matching i kurset men det er meget brugbart i andre sammenhænge!

Næste gange arbejder vi videre med tidyverse.

  • Group_by kombinerede med Summarise
  • Pivot_Longer/Pivot_Wider
  • Join funktionerne