Gå till index

Analys och forskning med R

0% färdig
0/0 Steps
  1. Analys och forskning med R och Posit (Rstudio)
  2. Grunderna i R och Rstudio
    7 Ämnen
  3. Importera, exportera, spara och ladda data
    5 Ämnen
  4. Strängar och regular expressions (regex)
    1 Ämne
  5. Bearbetning av data med dplyr
    12 Ämnen
  6. Visualisera och presentera
    14 Ämnen
  7. Explorerande och deskriptiva analyser
    6 Ämnen
  8. Prediktionsmodeller
    12 Ämnen
  9. Klassisk regressionsanalys
    8 Ämnen
  10. Machine learning (ML) och Artificiell Intelligens (AI)
    9 Ämnen
  11. Skapa prediktionsmodeller med Tidymodels
    6 Ämnen
  12. Hypotestester och epidemiologiska mått
    5 Ämnen
Avsnitt 5, Ämne 9

Dplyr ifelse(), if_else(), case_when(): Villkor

Avsnitt Progress
0% färdig

Det är omöjligt att arbeta med analys av data utan att använda villkor för att skapa eller modifiera variabler. De mest använda funktionerna för villkor är ifelse() (från base R), if_else() (från dplyr) och case_when() (från dplyr).

I detta kapitel kommer vi demonstrera funktionerna med hjälp av data som vi själva genererar direkt i R med funktionen tibble():

R
my_data <- tibble(Var1 = c(NA, 5, 9, 5, 3, 4, 10, 20, 30),
                  Var2 = c(1, NA, 3, 6, 1, 12, 0, 12, 3),
                  Var3 = c("Ja", "Nej", NA, "Ja", "Ja", "Ja", "Ja", "Nej", NA),
                  Var4 = rnorm(9), # genererar 9 slumpvärden med normalfördelning
                  Var5 = letters[1:9]) # första 9 bokstäverna i alfabetet
my_data
R
  Var1  Var2 Var3    Var4 Var5 
    NA     1 Ja    -0.234 a    
     5    NA Nej    0.794 b    
     9     3 NA     0.834 c    
     5     6 Ja    -1.40  d    
     3     1 Ja    -0.818 e    
     4    12 Ja     0.688 f    
    10     0 Ja     0.218 g    
    20    12 Nej   -2.14  h    
    30     3 NA    -0.449 i    

ifelse()

Med ifelse() från base definieras ett villkor med följande syntax:

ifelse(VILLKORET, OM_SANT, OM_FALSKT)

  • I första position (VILLKORET) specificeras villkoret.
  • I andra position (OM_SANT) specificeras vad funktionen skall returnera om villkoret är sant.
  • I tredje position (OM_FALSKT) specificeras vad funktionen skall returnera om villkoret är falskt.

Vi använder nu denna funktion för att skapa en ny variabel kallad ny_variabel. Denna variabeln får värdet 0 om Var är mindre än 5 och i annat fall 1:

R
my_data |> 
  mutate(ny_variabel = ifelse(Var1 < 5, 0, 1))
Resultat
   Var1  Var2 Var3    Var4 Var5  ny_variabel
     NA     1 Ja     0.276 a              NA
      5    NA Nej    1.15  b               1
      9     3 NA     0.162 c               1
      5     6 Ja    -0.517 d               1
      3     1 Ja     1.36  e               0
      4    12 Ja    -0.454 f               0
     10     0 Ja    -0.445 g               1
     20    12 Nej    0.394 h               1
     30     3 NA    -0.642 i               1

Det fungerade med undantag för att första observationen fick NA (missing) på ny_variabel. Förklaringen till detta är enkel: den observationen saknar information om Var1 och då kan inte villkoret utvärderas. Vi kan däremot specificera i villkoret hur NA ska hanteras. I nästa exempel utökar vi villkoret så att även missing (NA) får värdet 0. Detta gör vi genom att använda funktionen is.na() och operanden | som betyder "eller".

R
my_data |> 
  mutate(ny_variabel = ifelse(Var1 < 5 | is.na(Var1), 0, 1))
Resultat
   Var1  Var2 Var3    Var4 Var5  ny_variabel
1    NA     1 Ja     0.276 a               0
2     5    NA Nej    1.15  b               1
3     9     3 NA     0.162 c               1
4     5     6 Ja    -0.517 d               1
5     3     1 Ja     1.36  e               0
6     4    12 Ja    -0.454 f               0
7    10     0 Ja    -0.445 g               1
8    20    12 Nej    0.394 h               1
9    30     3 NA    -0.642 i               1

ifelse() kan bli krånglig om flera villkor behöver utvärderas sekventiellt, vilket är mycket vanligt. För att göra detta med ifelse() måste det tredje argumentet ersättas med en ny ifelse(). Ett exempel på detta följer:

R
my_data |> 
  mutate(ny_variabel = ifelse(Var1 < 4, "Mindre än 4",
                       ifelse(Var1 < 7, "Mindre än 7",
                       ifelse(Var1 < 10, "Mindre än 10", "Övriga"))))
R
   Var1  Var2 Var3    Var4 Var5  ny_variabel 
1    NA     1 Ja     0.276 a     NA          
2     5    NA Nej    1.15  b     Mindre än 7 
3     9     3 NA     0.162 c     Mindre än 10
4     5     6 Ja    -0.517 d     Mindre än 7 
5     3     1 Ja     1.36  e     Mindre än 4 
6     4    12 Ja    -0.454 f     Mindre än 7 
7    10     0 Ja    -0.445 g     Övriga      
8    20    12 Nej    0.394 h     Övriga      
9    30     3 NA    -0.642 i     Övriga 

Notera att det sista argumentet (ovan specificerat som "Övriga") är värdet som skall retuernas om inget av villkoren stämmer. Notera också att allra sist måste samtliga parenteser stängas.

if_else()

I dplyr finns funktionen if_else() som liknar ifelse(). Skillnaderna mellan dessa funktioner demonstreras nedan.

if_else() är mer strikt än ifelse()

Observera följande kommando och resultat med ifelse():

R
my_data |> 
  mutate(ny_variabel = ifelse(Var1 < 4, "Mindre än 4", 0))
Resultat
   Var1  Var2 Var3    Var4 Var5  ny_variabel
1    NA     1 Ja     0.276 a     NA         
2     5    NA Nej    1.15  b     0          
3     9     3 NA     0.162 c     0          
4     5     6 Ja    -0.517 d     0          
5     3     1 Ja     1.36  e     Mindre än 4
6     4    12 Ja    -0.454 f     0          
7    10     0 Ja    -0.445 g     0          
8    20    12 Nej    0.394 h     0          
9    30     3 NA    -0.642 i     0   

Det verkar som att koden fungerade. Nu upprepas identisk kod med undantag för att ifelse() ersätts med if_else():

Resultat
my_data |> 
  mutate(ny_variabel = if_else(Var1 < 4, "Mindre än 4", 0))
Resultat
Error in `mutate()`:
! Problem while computing `ny_variabel = if_else(Var1 < 4, "Mindre än 4", 0)`.
Caused by error in `if_else()`:
! `false` must be a character vector, not a double vector.

Detta resulterade däremot i error. Förklaringen till detta är att villkoret returnerar en textsträng ("Mindre än 4") om det är sant och ett numeriskt värde (0) om det är falskt. Detta ogillas av if_else() för att värdena som kan returneras skall vara av samma typ.

if_else() konverterar inte datumvariabler till numeriska värden

Se följande exempel med resultat med ifelse():

R
# Skapar 3 datum med funktionerna c() och ymd()
my_dates <- ymd(c('2021-10-01', '2022-10-02', '2021-10-03'))

# Utvärderar ett villkor och sparar som nytt objekt
my_dates_2 <- ifelse(my_dates == '2022-10-02', my_dates + 1, my_dates)

# Visa vilken klass vektorn har
class(my_dates_2)
Resultat
[1] "Numeric"

Samma kod upprepas med ifelse() ersätts med if_else():

R
# Skapar 3 datum med funktionerna c() och ymd()
my_dates <- ymd(c('2021-10-01', '2022-10-02', '2021-10-03'))

# Utvärderar ett villkor och sparar som nytt objekt
my_dates_2 <- if_else(my_dates == '2022-10-02', my_dates + 1, my_dates)

# Visa vilken klass vektorn har
class(my_dates_2)
Resultat
[1] "Date"

if_else() har ett extra argument för missing

Vi upprepar första exemplet, men nu med if_else() och specificerar ett värde på missing:

R
my_data |> 
  mutate(ny_variabel = if_else(Var1 < 4, "Mindre än 4", "4 eller mer", missing="Saknas"))
R
   Var1  Var2 Var3    Var4 Var5  ny_variabel
1    NA     1 Ja     0.276 a     Saknas     
2     5    NA Nej    1.15  b     4 eller mer
3     9     3 NA     0.162 c     4 eller mer
4     5     6 Ja    -0.517 d     4 eller mer
5     3     1 Ja     1.36  e     Mindre än 4
6     4    12 Ja    -0.454 f     4 eller mer
7    10     0 Ja    -0.445 g     4 eller mer
8    20    12 Nej    0.394 h     4 eller mer
9    30     3 NA    -0.642 i     4 eller mer

if_else() är snabbare än ifelse()

Sist men inte minst är if_else() snabbare än ifelse().

case_when()

Istället för att skapa nestade ifelse() eller if_else() satser kan case_when() användas. Denna funktionen gör det möjligt att med effektiv syntax specificera en rad sekventiella villkor. Villkoren testas ett i taget. Notera att med case_when() används ~. Till vänster om ~ anges villkoret, och till höger om ~ anges värdet som funktionen skall returnera om villkoret stämmer. Notera att vi kan specificera missing med funktionen is.na().

R
my_data |> mutate(ny_variabel = case_when(Var1 == 3 ~ "Lika med 3",
                                          Var1 > 3 ~ "Större än 3",
                                          Var1 > 6 ~ "Större än 6",
                                          Var1 > 9 ~ "Större än 9",
                                          is.na(Var1) ~ "Saknas"))
R
   Var1  Var2 Var3    Var4 Var5  ny_variabel
1    NA     1 Ja     0.276 a     Saknas     
2     5    NA Nej    1.15  b     Större än 3
3     9     3 NA     0.162 c     Större än 3
4     5     6 Ja    -0.517 d     Större än 3
5     3     1 Ja     1.36  e     Lika med 3 
6     4    12 Ja    -0.454 f     Större än 3
7    10     0 Ja    -0.445 g     Större än 3
8    20    12 Nej    0.394 h     Större än 3
9    30     3 NA    -0.642 i     Större än 3

Logga in för att läsa

Som medlem har du tillgång till allt nuvarande och kommande utbildningsmaterial. Du kan följa din utveckling och få intyg på avklarade moment.