Programering i R

Föreläsning 3: Programkontroll

Josef Wilzén

STIMA, Linköpings universitet

2021-02-08

Föreläsning 3: Innehåll

  • Programkontroll
    • Villkorssatser
    • Loopar
  • Funktionsmeddelanden: message, warning, stop
  • Intro debugging

Allmänt

  • Inlämningsuppgifter
    • Rätta med mark_my_file()
  • sayhello på Teams
  • Några frågor så här långt?

Programkontroll

Programkontroll

  • Att kontrollera körning av program / funktioner
  • Det finns olika kontroller vi kan vilja göra, exempelvis:
    • köra / (åter) använda en annan del av koden
    • villkorsstyra kod
    • köra kod 0 eller fler gånger
    • köra kod till dess ett villkor är uppfyllt
    • avbryta ett program

Villkorssatser

Villkorssatser - Syntax

Pseudokod:

if ( Villkor ) { 
  Kod om Villkor == TRUE 
}
  • Om Villkor är en logisk vektor prövas bara det första elementet
  • Logisk switch:
if ( Villkor ) {
  Kod om Villkor == TRUE 
} else {
  Kod om Villkor == FALSE 
}

Villkorssatser - Syntax forts.

if ( Villkor 1 ) { 
  Kod om Villkor 1 == TRUE 
} else if ( Villkor 2 ){
  Kod om Villkor 2 == TRUE 
} else {
  Kod om Villkor 1 och 2 == FALSE 
}

Villkorssatser - Exempel

prgm <- "R"
if ( prgm == "R" ) { cat("Kul!") }
Kul!
prgm <- "Excel"
if ( prgm == "R" ) { cat("Kul!") }

Villkorssatser - Exempel II

prgm <- "Excel"
if ( prgm == "R" ) { 
  print("Kul!")
} else if ( prgm == "Python"){
  print("Okej då!")
} else {
  print("Ehhh...")
}
[1] "Ehhh..."

Demo: Villkorssatser

  • Villkorssatser
  • Villkorssatser i funktioner

Loopar

for - loop

Vad är en "for-loop"?

  • Kontrollerar upprepningar av (samma) kod
  • I R används for, loopar över en vektor/lista
for ( elem in vektor ) { 
  # Kod som anropas en gång per element
  # elem är ett element i vektorn  
}
  • Vilken vektor eller lista som helst kan användas
  • Viktigt koncept: loopens index “elem” är det ENDA som ändras i loopen (innanför “{…}”)

Loopar (for-loop): Exempel

vektor <- c("Oleg", "Annika", "Lotta")
for ( element in vektor ) { 
  print(element) 
}
[1] "Oleg"
[1] "Annika"
[1] "Lotta"

Loopar (for-loop): Exempel

for ( element in 1:5 ) { 
  print(element) 
}
[1] 1
[1] 2
[1] 3
[1] 4
[1] 5

Loopar (for - loop): Exempel

Vi kan loopa på flera sätt:

for ( element in vektor ) { 
  print(element) 
}
for ( index in seq_along(vektor) ) { 
  print(vektor[index]) 
}
for ( index in 1:length(vektor) ) {
  print(vektor[index])
}

Demo: for-loopar

Nästlade loopar (nested loops)

  • Om vi vill loopa i flera dimensioner/nivåer
  • Delas upp i “Inre” och “yttre” loop
  • Tänk klocka
    • Timmar: yttersta loopen
    • Minuter: gör 60 iterationer/ timme
    • Sekunder: gör 60 iterationer/ minut

Nästlade loopar (nested loops)

A <- matrix(1:6, nrow = 2)
for ( i in 1:2 ) {
  for ( j in 1:3 ) {
    text<-paste("r:",i,"  k:",j,"  v:",A[i,j])
    print(text)
  }
}
[1] "r: 1   k: 1   v: 1"
[1] "r: 1   k: 2   v: 3"
[1] "r: 1   k: 3   v: 5"
[1] "r: 2   k: 1   v: 2"
[1] "r: 2   k: 2   v: 4"
[1] "r: 2   k: 3   v: 6"

Demo: Nästlade for-loopar

Kontrollstrukturer för loopar

Kontrollstrukturer för loopar

  • Vi vill ofta kontrollera hur looparna arbetar
  • För detta finns följande kontrollstrukturer:
Kontrollstruktur Effekt
next() Börjar om med nästa iteration direkt
break() Avbryter den aktuella/innersta loopen.
stop() Avbryter allt och genererar ett felmeddelande (Fungerar även i funktioner)

Exempel: next()

# skriv ut udda tal:
for ( i in 1:10 ) {
  if(i %% 2 == 0) { next() }
  print(i)
}
[1] 1
[1] 3
[1] 5
[1] 7
[1] 9

Exempel: break()

for ( i in 1:3 ) {
  for ( letter in c("a","b","c") ) {
    if(letter == "b") { break() }
    print(letter)
  }
}
[1] "a"
[1] "a"
[1] "a"

Exempel: stop()

for ( i in 1:3 ) {
  for ( letter in c("a","b","c") ) {
    if(letter == "b") { stop("Mitt fel!") }
    print(letter)
  }
}
[1] "a"
Error: Mitt fel!

Demo: kontrollstrukturer för loopar

Villkorstyrda loopar (while - loop)

Villkorstyrda loopar (while - loop)

  • Om vi inte vet antalet iterationer
while ( Villkor ) { 
  # Kod som anropas så länge Villkor == TRUE
}
  • Varning! Kan fortsätta hur länge som hellst
  • Obs! Villkor måste kunna utvärderas innan loopen startar
  • repeat() repeterar kod till break

Villkorstyrda loopar: Exempel

i <- 1 # Obs!
while ( i < 5 ) { 
  print(i)
  i <- i + 1
}
[1] 1
[1] 2
[1] 3
[1] 4

Demo: villkorsstyrda loopar

Varningsmeddelanden och Debugging

Varningsmeddelanden

  • stop() avbryter funktioner/loopar och meddelar ett fel
  • Skapa en varning, som inte avbryter: warning()
  • Varningar sparas och skrivs ut sist
  • warnings(): skriva ut tidigare varningar

Varningsmeddelanden

for (i in 1:2){
  print(i)
  warning(paste("Farligt värre", i))
}
[1] 1
[1] 2
Warning messages:
1: Farligt värre 1 
2: Farligt värre 2 

Debugging

Det uppstår ofta fel vid programmering! Debugging handlar om att hitta orsaken till att en kod/funktion inte fungerar som det var tänkt. Olika typer av fel:

  • Syntaktiska fel: Felaktig syntax är angiven i koden (ofta stavfel)
  • Semantiska fel: Olämplig använding av objekt/funktioner, tex x<-0, y<-3, y/x.
  • Logiska fel: Programmet löser inte det tänkta problemmet. Kan vara svåra att lösa.

Debugging

  • Använd cat(), print() eller message() för att skriva ut värden på olika variabler -> få en uppfattning av vad som händer i en funktion
    • Använd paste() för att kombinera text och variabler
  • browser(): “hoopar in i funktionen på valt ställe”
    • n: kör nästa rad kod
    • c: kör allt i funktion/loop
    • Q: avsluta
  • debugg(): “hoopar in i funktionen från början”

Demo: debugging