Programering i R

Föreläsning 3: Programkontroll

Josef Wilzén

STIMA, Linköpings universitet

Uppdaterad 2017-02-07 12:56:17

Föreläsning 3: Innehåll

  • Interaktiv del ~ 45 min
  • Programkontroll
    • Villkorssatser
    • Loopar
  • Funktionsmeddelanden: message, warning, stop
  • Intro debugging

Interaktiv del

Interaktiv del

Se kod…

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

if ( Villkor ) { Kod om Villkor == TRUE }
  • Om Villkor är en logisk vektor prövas bara det första elementet
  • Pseudokod:
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 - Syntax forts.

  • Om det är många else if kan switch vara smidigare:
switch(type,
        villkor1 = {
          "kod för villkor1"
          },
        villkor2 = {
          "kod för villkor2"
          },
        villkor3 = {
          "kod för villkor3"
          },
       {
         "Om type != villkor1, villkor2 eller villkor3"
       }
)

Villkorssatser - Syntax forts.

elak_dator <- "skynet" 
switch(elak_dator, 
  # Kod om elak_dator = "hal"
  hal = { print(2001) },     
  # Kod om elak_dator = "skynet"
  skynet = {
    # Det går att skriva flera rader
    print(1997)},
  # Om inget alternativ ovan
  { print(2000) }
)
[1] 1997

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

Villkorssatser

Funktionen ifelse() är en vektoriserad variant av if-else.

Syntax:

  • test= ett logiskt test
  • yes= värden att returnera om test är sann
  • no= värden att returnera om test är falsk

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” kan påverka koden innanför “{…}”

Loopar (for-loop): Exempel

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

Loopar (for - loop): Exempel II

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
  • Delas upp i “Inre” och “yttre” loop
A <- matrix(1:4, nrow = 2)
for ( i in 1:2 ) {
  for ( j in 1:2 ) {
    print(A[i,j])
  }
}
[1] 1
[1] 3
[1] 2
[1] 4

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 i R Effekt
next() Börjar om loopen direkt.
break() Avbryter den aktuella/innersta loopen.
stop() Avbryter allt och genererar ett felmeddelande (Fungerar även i funktioner)

Exempel: next()

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: nästlade for-loopar och 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
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
  • 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