Programmering i R. 6. mars 2004

Like dokumenter
Notat 2, ST Sammensatte uttrykk. 27. januar 2006

Notat 2, ST januar 2005

Notat 6 - ST februar 2005

Bioberegninger - notat 4: Mer om sannsynlighetsmaksimering

INF2810: Funksjonell programmering: Mer om Scheme. Rekursjon og iterasjon.

<?php. count tar en array som argument, og returnerer et tall som uttrykker antallet innførsler i arrayen.

Øvingsforelesning i Matlab TDT4105

Læringsmål og pensum. Oversikt

Finne ut om en løsning er helt riktig og korrigere ved behov

ST Bioberegninger, introduksjon Om kurset

Kapittel Oktober Institutt for geofag Universitetet i Oslo. GEO En Introduksjon til MatLab. Kapittel 14.

Notat 3 - ST februar 2005

Hvis en person har inntekt < , så betaler han 10% skatt på alt, og ellers betaler han 10% skatt på de første og 30% på resten.

Hvis en person har inntekt < , så betaler han 10% skatt på alt, og ellers betaler han 10% skatt på de første og 30% på resten.

Introduksjon til objektorientert. programmering. Hva skjedde ~1967? Lokale (og globale) helter. Grunnkurs i objektorientert.

Finne ut om en løsning er helt riktig og korrigere ved behov

Programmering i R - del 2

INF 1000 høsten 2011 Uke september

INF1000 undervisningen INF 1000 høsten 2011 Uke september

lage og bruke funksjoner som tar argumenter lage og bruke funksjoner med returverdier forklare forskjellen mellom globale og lokale variabler

Matematikk Øvingsoppgaver i numerikk leksjon 5 Løsningsforslag

Øving 12, ST1301 A: B:

Norsk informatikkolympiade runde

INF1000 EKSTRATILBUD. Stoff fra uke 1-5 (6) 3. oktober 2012 Siri Moe Jensen

Norsk informatikkolympiade runde. Sponset av. Uke 46, 2017

2 Om statiske variable/konstanter og statiske metoder.

TDT4110 IT Grunnkurs Høst 2016

Øvingsforelesning i Matlab TDT4105

}?> <!DOCTYPE... <html xmlns=" <head>... </head> <body> <p>nå skal vi printe hallo:</p> <?php //funksjonskall

Introduksjon til objektorientert programmering

Innhold uke 4. INF 1000 høsten 2011 Uke 4: 13. september. Deklarasjon av peker og opprettelse av arrayobjektet. Representasjon av array i Java

Feilmeldinger, brukerinput og kontrollflyt

Norsk informatikkolympiade runde

Object interaction. Innhold. Abstraksjon Grunnleggende programmering i Java Monica Strand 3. september 2007.

Øvingsforelesning TDT4105 Matlab

ST1301 Bioberegninger - Introduksjon

Betinget eksekvering og logiske tester i shell

Løsningsforslag øving 8, ST1301

Utførelse av programmer, metoder og synlighet av variabler i JSP

MAT1030 Diskret Matematikk

4 Matriser TMA4110 høsten 2018

TDT4110 Informasjonsteknologi grunnkurs: Tema: Mer om strenger. - 3rd edition: Kapittel 8. Professor Alf Inge Wang

Debugging. Tore Berg Hansen, TISIP

INF1000 Metoder. Marit Nybakken 16. februar 2004

Norsk informatikkolympiade runde

Løsningskisse for oppgaver til undervisningsfri uke 8 ( februar 2012)

Norsk informatikkolympiade runde

Matematikk Øvingsoppgaver i numerikk leksjon 7 Løsningsforslag

Uendelig bakke. Introduksjon. Skrevet av: Kine Gjerstad Eide

Matematikk Øvingsoppgaver i numerikk leksjon 4 m-ler

Matematikk Øvingsoppgaver i numerikk leksjon 2 Løsningsforslag

Metoder med parametre, løkker og arrayer

Newtons metode er en iterativ metode. Det vil si, vi lager en funksjon. F x = x K f x f' x. , x 2

Informasjon Eksamen i IN1000 høsten 2017

Statistikk 1 kapittel 5

Matematikk Øvingsoppgaver i numerikk leksjon 2 Løsningsforslag

Bioberegninger, ST november 2006 Kl. 913 Hjelpemidler: Alle trykte og skrevne hjelpemidler, lommeregner.

class Book { String title; } class Dictionary extends Book { int wordcount; } class CartoonAlbum extends Book { int stripcount; }

Norsk informatikkolympiade runde

Mengder, relasjoner og funksjoner

Løse reelle problemer

Rekursjon som programmeringsteknikk

TDT4105 Informasjonsteknologi, grunnkurs (ITGK)

1 Section 4-1: Introduksjon til sannsynlighet. 2 Section 4-2: Enkel sannsynlighetsregning. 3 Section 5-1: Introduksjon til sannsynlighetsfordelinger

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme, del 2

INF2810: Funksjonell Programmering. Tilstand og verditilordning

Løse reelle problemer

2 Om statiske variable/konstanter og statiske metoder.

Jentetreff INF1000 Debugging i Java

ST1301 Bioberegninger. Jarle Tufto

Matematikk Øvingsoppgaver i numerikk leksjon 1. Løsningsforslag

MAT1030 Plenumsregning 1

INF2810: Funksjonell Programmering. Kommentarer til prøveeksamen

INF1000 Uke 4. Innlesning fra terminal. Uttrykk og presedens. Oversikt

TDT4110 IT Grunnkurs Høst 2016

En innføring i MATLAB for STK1100

TDT4105 Informasjonsteknologi, grunnkurs. Introduksjon til programmering i Matlab. Rune Sætre / Anders Christensen {satre,

Plenumsregning 1. MAT1030 Diskret Matematikk. Repetisjon: Algoritmer og pseudokode. Velkommen til plenumsregning for MAT1030

Arv. Book book1 = new Book(); book1. title = "Sofies verden" class Book { String title; } class Dictiona ry extends Book {

Plenumsregning 1. Kapittel 1. Roger Antonsen januar Velkommen til plenumsregning for MAT1030. Repetisjon: Algoritmer og pseudokode

EKSAMENSOPPGAVE / EKSAMENSOPPGÅVE

Matematikk Øvingsoppgaver i numerikk leksjon 5 for-løkker

TDT4105 Informasjonsteknologi, grunnkurs (ITGK)

if-tester Funksjoner, løkker og iftester Løkker og Informasjonsteknologi 2 Læreplansmål Gløer Olav Langslet Sandvika VGS

Velkommen til plenumsregning for MAT1030. MAT1030 Diskret matematikk. Repetisjon: Algoritmer og pseudokode. Eksempel fra boka. Eksempel

INF2810: Funksjonell Programmering. Dataabstraksjon og Trerekursjon

HØGSKOLEN I SØR-TRØNDELAG Avdeling for informatikk og e-læring AITeL

En enkel while-løkke. 1 of :28. 2 of :28. while-løkker gjentar instruksjonene så lenge en betingelse er oppfylt

Noen innebygde funksjoner - Vektorisering

Norsk informatikkolympiade runde. Sponset av. Uke 46, 2015

INF2810: Funksjonell Programmering. En Scheme-evaluator i Scheme, del 2

Norsk informatikkolympiade runde. Sponset av. Uke 46, 2013

Noen innebygde funksjoner - Vektorisering

Matematikk Øvingsoppgaver i numerikk leksjon 1 Løsningsforslag

YouTube-kanal ITGK. Læringsmål og pensum

while-økker while-løkker gjentar instruksjonene så lenge en betingelse er oppfylt Eksempel 1: en enkel while-løkke

Python: Variable og beregninger, input og utskrift. TDT4110 IT Grunnkurs Professor Guttorm Sindre

Løse reelle problemer

løsningsforslag-uke5.txt

Transkript:

Programmering i R 6. mars 2004 1 Funksjoner 1.1 Hensikt Vi har allerede sette på hvordan vi i et uttrykk kan inkludere kall til funksjoner som er innebygd i R slik som funksjonene sum, plot o.s.v. Generelt virker funksjoner ved at funksjonen først mottar visse inndata som vi oppgir som argumenter, funksjonen utfører så en bestemt oppgave, f.eks. visse beregninger, og returnerer deretter resultatet av beregningene som sine utdata gjennom funksjonsverdien. Om vi for eksempel gjør vi et kall til mean utgjør vektoren vi oppgir som argument inndataene, mean beregner så gjennomsnittet av elementene i vektoren, og returnerer dette via funksjonsverdien. Når vi skal gjøre løse problemer som krever større beregninger vil det være hensiktsmessig å definere egne funksjoner som løser bestemte avgrensede deloppgaver av hele problemet. Definering av egne funksjoner er særlig hensiktsmessig når vi skal utføre varianter av samme oppgave flere ganger. Ved å definere en funksjon slipper vi i slike tilfeller å skrive programkode for å løse problemet mer en gang; det å definere funksjoner innebærer gjenbruk av programkode som slik sparer oss for masse arbeid. I tillegg til denne direkte arbeidsbesparelsen skaper bruk av egendefinerte funksjoner bedre oversikt ved at det blir mindre programkode å holde styr på. Når vi har skrevet en funksjon ferdig som løser en avgrenset veldefinert del av hele oppgaven kan vi glemme hvordan funksjonen virker i detalj og konsentrere oss om å løse resten av problemet. 1

Mindre programkode gjør at det blir lettere på et senere tidspunkt å endre programkoden hvis oppgaven vi ønsker å løse skulle endre seg eller hvis programkoden skulle vise seg å inneholde feil. 1.2 Formell virkemåte La oss først se på hvordan vi definerer en funskjon og hvordan en funksjon virker formelt ved å se på et enkelt eksempel. I likhet med andre objekter som vektorer o.l. lager vi en funksjon ved å bruke tilordningsoperatoren. Funksjonen blir altså selv et objekt i R sitt workspace på samme måte som andre variable. Fordi funksjonsdefinisjonen vanligvis går over flere linjer er det praktisk å skrive funskjonsdefinisjonen inn i en teksteditor, f.eks. notepad i windows. Skriv følgende inn i notepad, merk teksten og kopier denne ved å trykke ctrl-c, å lim så dette inn i R-vinduet ved å trykke ctrl-v i R. minfunksjon <- function(arg1,arg2=20) { arg1 <- arg1 + 5 a <- arg1+arg2 return(a^2) Gjør vi dette får vi opprettet et objekt av type funksjon med navn minfunksjon i R sitt workspace. Funksjonen har to formelle argumenter med navn arg1 og arg2. Argumentene vil være å betrakte som variable når uttrykkene inne i funksjonen blir beregnet (når vi gjør et kall til funksjonen). I linje to tilordnes verdien av uttrykket arg1 + 5 til arg1 (arg1 øker sin verdi med 5). I linje tre tilordnes verdien uttrykket arg1+arg2 nå har fått til variabelen a. I linje 4 beregnes verdien av uttrykket aˆ2 som returneres som funksjonsverdi. Dette uttrykket trenger strengt tatt ikke å omsluttes av return( ); lar vi være vil funksjonen returnere verdien av uttrykket på siste linje i funksjonsdefinisjonen. Som for innebygde funksjoner i R kan vi nå gjøre et kall til funksjonen: > minfunksjon(10,5) [1] 400 Vi ser at funksjonen oppfører seg som forventet; først legges 5 til 10 slik at arg1 får verdien 15. Variabelen a blir så lik summen av variablene arg1 og arg2 (20). Dette opphøyes så i andre slik at funksjonsverdien blir lik 400. Merk at variabelen a og argumentene arg1 og arg2 ikke lenger er tilstede etter kallet til funksjonen; disse er å betrakte som lokale variable som bare er synlige fra innsiden av funksjonen og som forsvinner når funksjonen har gjort sitt: 2

> a Error: Object "a" not found > arg1 Error: Object "arg1" not found > arg2 Error: Object "arg2" not found Dette er også ønskelig oppførsel i og med at vi ikke ønsker at variable vi bruker lokalt inne i funksjonen for å løse funksjonens oppgaver skal komme i konflikt med variabler vi har opprettet for å ta vare på beregningsresultat utenfor funksjonen. Om vi har opprettet en variabel a før kallet til minfunksjon vil a fortsatt ha samme verdi etter funksjonskallet: > a <- c(1,2,3) > minfunksjon(10,5) [1] 400 > a [1] 1 2 3 Vektoren a her er å betrakte som en global variabel som ikke endrer seg når vi tilordner verdier til den lokale variabelen a inne i funksjonen minfunksjon. Sett fra utsiden trenger vi med andre ord ikke å bekymre oss for hvilke variabelnavn som brukes internt av funksjonen. Eksempelet over illusterer også bruken av default-verdier. I første linje i funksjonsdefinisjonen har vi spesifisert at arg2 har 100 som sin defaultverdi. Lar vi være å oppgi arg2 i kallet til funksjonen vil arg2 ta verdien 100 i påfølgende beregninger internt i funksjon slik at vi får: > minfunksjon(10) [1] 1225 1.3 Eksempel La oss betrakte tenke oss en bestand på N = 50 moskusokser. m = 15 av disse bærer på en bestemt genvariant på sitt Y-kromosom (hver hann har bare ett Y-kromosom). Fordi bestanden er blitt for stor blir det besluttet at bestanden skal reduseres til n = 20 okser. La oss anta at disse blir valgt tilfeldig fra den opprinnelige bestanden. Lar vi X betegne antall kopier av genvarianten som er i igjen i utvalget etter bestandsreduksjonen følger det 3

at X blir hypergeometrisk fordelt med sannsynlighetsfordeling ( )( ) m N m p X (x) = x n x ( ) N (1) n Vi ønsker å lage et plot over sannsynlighetsfordelingen. I første omgang ønsker vi å beregne uttrykket over, la oss si for x = 10. Vi ser at uttrykket innebærer at vi må beregne tre binomialkoeffisienter. Videre en binomial koeffisienten definert som ( ) n x = n! x!(n x)! som innbærer at vi i beregningen av hver binomialkoeffisient må beregne verdier av fakultetsfunksjonen tre ganger. Lager vi oss funksjoner som utfører disse deloppgavene på en generell måte kan vi altså spare oss for mye arbeid. La oss først lage en funksjon som beregner n! = 1 2 n. Dette kan vi gjøre ved å lage en vektor av tallene fra 1 til n med uttrykket 1:n og så beregne produktet av elementene i vektoren med et kall til funksjonen prod (tilsvarer funksjonen sum). En definisjon av hele funksjonen vil kunne være fac <- function(n) { resultat <- prod(1:n) return(resultat) Tester vi funksjonen ser vi at den virker slik den skal: > fac(4) [1] 24 Når vi har løst denne deloppgaven kan vi lett definere en funksjon for å beregne binomialkoeffisienten: binomcoef <- function(n,x) { fac(n)/(fac(x)*fac(n-x)) Til sist definerer vi en funksjon som beregner hele punktsannsynligheten i en gitt verdi X = x, p X (x) gitt ved (1): pgenfordeling <- function(x,n=50,m=15,n=20) { binomcoef(m,x)*binomcoef(n-m,n-x)/binomcoef(n,n) 4 (2)

Ved å spesifisere default-verdier i funksjonsdefinisjonen slipper vi å oppgi modellparameterene i kall til funksjonen. Vi kan nå beregne, f.eks. p X (3), sannsynligheten for at 3 av de 20 oksene etter bestandsreduksjonen vil bære genet: > pgenfordeling(3) [1] 0.04380708 Oppgaven er nå løst ved vi har definert funksjonen pgenfordeling som gjør tre kall til til funksjonen binomcoef som tilsammen gjør tre ganger tre kall til funksjonen fac. 2 If-setninger 2.1 Eksempel La oss fortsette eksempelet fra del 1.3. Forsøker vi å beregne sannsynligheten for at genvarianten blir helt borte, altså p X (0) = P (X = 0) får vi > pgenfordeling(0) [1] Inf Dette er åpenbart feil, en punktsannsynlighet i en diskret modell kan ikke ta verdier som går mot uendelig. Etter litt mer testing av de funksjonene vi har laget finner vi at vår fakultetsfunksjon fac returnerer følgende for 0!: > fac(0) [1] 0 hvilket jo er feil i og med at 0! er definert lik 1. Ser vi på verdiene uttrykkene i funksjonen fac får om vi bruker 0 som argument ser vi følgende > 1:0 [1] 1 0 > prod(1:0) [1] 0 Løsningen er å bruke en såkalt if-setning som gjør at vi kan håndtere spesialtilfeller som dette. Vi skriver om funksjonen til følgende: fac <- function(n) { if (n==0) resultat <- 1 else 5

resultat <- prod(1:n) return(resultat) En if-setning består generellt av et logisk uttrykk etterfulgt av et eller to uttrykk hvorav et av disse beregnes avhengig av om verdien av det logiske uttrykket har verdi TRUE eller FALSE. I vår modifiserte definisjon av funksjonen fac vil uttrykket n==0 få verdi TRUE dersom argumentet n er lik 0 og i slike tilfeller vil tilordningsuttrykket resultat <- 1 utføres, i motsatt fall utføres uttrykket resultat <- prod(1:n). Til siste returnes verdien av den lokale variabelen resultat. Med denne modifikasjonen begynner ting å fungerer: > fac(0) [1] 1 > fac(4) [1] 24 > pgenfordeling(0) [1] 6.891571e-05 Vi ser at det er temmelig usannsynlig at genvarianten forsvinner helt men ikke helt umulig. Om vi antar at genvarianten i utgangspunktet er mer skjelden, la oss si tilstede i bare m = 5 kopier, får vi at sannsynligheten for at det forsvinner blir langt større: > pgenfordeling(0,m=5) [1] 0.06725915 Unntakshåndtering slik som i dette eksempelet er en ganske vanlig bruk av if-setninger men if-setninger kan selvsagt også brukes til en rekke andre formål. Generellt kan de to alternative uttrykkene i en if-setning være såkalt sammensatte uttrykk. Ett sammensatt uttrykk kan skrives på formen {uttrykk1; uttrykk2; uttrykk3 eller { uttrykk1 uttrykk2 uttrykk3 Sammensatte uttrykk brukes også i definisjoner av funksjoner, slik vi har sett for eksempel i del 1.2, og i andre programstrukturer. 6

3 Løkker 3.1 Eksempel Vi har allerede sett på hvordan vi mange funksjoner kan operere elementvis på vektorer, f.eks. vil logaritmefunksjonen beregne logaritmer elementvis for vektoren som vi oppgir som argument: > weight [1] 60 72 57 90 95 72 > log(weight) [1] 4.094345 4.276666 4.043051 4.499810 4.553877 4.276666 Hvorvidt en funskjon kan operere elementvis på vektorer som er oppgitt som argument vil avhenge av hvordan funksjonen virker internt. Ser vi på vår funksjon pgenfordeling ser vi at den ikke håndterer vektorer som sitt x argument: > pgenfordeling(0:15) [1] 6.891571e-05 Warning messages: 1: the condition has length > 1 and only the first element will be used in: if (n == 0) return(1) else return(prod(1:n))... Slik vi har programmert vår funksjonen beregnes i tilfelle over bare p X (x) for x = 0 i tillegg til at vi får en rekke feilmeldinger. Skal vi beregne la oss si en vektor av sannsynlighetene p X (0), p X (1),..., p X (15) må vi derfor tilordne verdiene til resultatvektoren eksplisitt. Vi kunne ha gjort dette på følgende måte: > pvektor<-rep(0,16) > pvektor[0]<-pgenfordeling(0) > pvektor[1]<-pgenfordeling(1) > pvektor[2]<-pgenfordeling(2) Meningen med for-løkker er å forenkle slike operasjoner. I stedet for alle linjene i koden over kan vi utføre det samme ved å bruke en såkalt for-løkke: > pvektor<-rep(0,16) > for (i in 0:15) pvektor[i+1] <- pgenfordeling(i) 7

Det som her skjer er at uttrykket pvektor[i] <- pgenfordeling(i) utføres et antall ganger. Ved hver enkelt utførelse av uttrykket vil løkke-variabelen i ha elementer hentet fra vektoren 0:15 som verdi. Resultatet er at alle elementene i vektoren pvektor blir tilordnet riktige verdier (sannsynlighetene for at 0, 1, 2 kopier av genvarianten o.s.v. er tilstede i populasjonen etter bestandsreduksjonen): > pvektor [1] 1.292170e-03 1.010933e-02 4.380708e-02 1.175874e-01 2.069539e-01 [6] 2.463737e-01 2.015785e-01 1.139356e-01 4.430831e-02 1.169739e-02 [11] 2.044999e-03 2.272221e-04 1.498168e-05 5.166095e-07 6.888127e-09 [16] 0.000000e+00 Vi kan nå lage et plot av resultatet: > plot(0:15,pvektor,type="h",xlab="antall genkopier x",ylab="sannsynlighet") Argumentet type= h spesifiserer at plottet skal være av type histogram. Default-verdien til argument type er p. Resultatet blir som i figur 1 0 5 10 15 antall genkopierx sannsynlighet 0.00 0.10 0.20 Figur 1: Resultatet av kallet til plot funksjonen Generellt er for-løkker på formen 8

for (var in vektor {sammensatt uttrykk 9