Uppgifter till lektion 1 Statistisk Programmering Använda R Göran Broström gb@stat.umu.se 1. Hur många MB RAM behövs för att lagra en 1000 1000 matris i dubbel precision? 2. Skriv en R-funktion som omvandlar (positiva hel-)tal från binärt till decimalt. 3. Skriv en R-funktion som omvandlar (positiva hel-)tal från decimalt till binärt. Statistiska institutionen Umeå universitet 901 87 Umeå Statistisk Programmering, hösten 2002 p.1/32 Statistisk Programmering, hösten 2002 p.2/32 Programmeringsspråk Kompilerande språk nivåordnade från låg till hög. Maskinkod. Nödvändigt, men vi använder det inte direkt. C/C++. Finns tillgängligt, kan länkas till R. Både lågoch högnivå. Många operativsystem och kompilatorer(!) är skrivna i C. FORTRAN. Inte lika lågnivåigt som C. Framför allt ett naturvetenskapligt, matematiskt beräkningsspråk. R. Högsta nivå. Är skrivet i framför allt C, men delvis också i FORTRAN. C och FORTRAN är kompilerande språk: hela programmet omvandlas till maskinkod innan det kan köras. Kompilatorn kan hitta formella fel i programmet. Väl kompilerat är det snabbt. Statistisk Programmering, hösten 2002 p.3/32 Statistisk Programmering, hösten 2002 p.4/32
Tolkande språk R är ett tolkande ( interpreterande ) språk. Vanligt för interaktiva miljöer. Programmet tolkar (översätter till maskinkod) en rad i taget och utför omedelbart. Man slipper kompileringssteget. Men långsammare än kompilerad kod. > 2 + 2 [1] 4 R som (förvuxen) räknedosa > exp(-2) [1] 0.1353353 > rnorm(9) [1] -0.63944411 0.19445486 0.06718542 [4] 1.35989592-1.11763370 1.58923022 [7] -1.32153729 0.40863900-0.57155763 Statistisk Programmering, hösten 2002 p.5/32 Statistisk Programmering, hösten 2002 p.6/32 > x <- 2 gör flera saker på en gång: Tilldelning Reserverar 8 bytes minne för x i dubbel precision. Uppdaterar adresskatalogen med adressen till minnesplatsen för x. Kopierar värdet 2 till denna minnesplats. Tilldelningsoperatorversioner: <- är tilldelningsoperator i R. = är tilldelningsoperator i C och FORTRAN. := är tilldelningsoperator i Pascal. > x <- sqrt(2)ˆ2 > x [1] 2 > x == 2 [1] FALSE Vad händer?? Avrundningsfel!! > options(digits = 17) > x [1] 2.0000000000000004 Jämförelse Använd all.equal(x, 2). Tillåter avrundningsfel. För integer och character är == OK! Statistisk Programmering, hösten 2002 p.7/32 Statistisk Programmering, hösten 2002 p.8/32
Logiska operatorer Dataobjekt Jämförelse R och C FORTRAN Exakt likhet ==.eq. Exakt olikhet!=.ne. Mindre än <.lt. Mindre än eller lika med <=.le. Större än >.gt. Större än eller lika med >=.ge. Allt i R är objekt! Alla objekt har ett tillstånd (mode) och en längd. Dataobjekt har tillstånd som numeric complex character logical Statistisk Programmering, hösten 2002 p.9/32 Statistisk Programmering, hösten 2002 p.10/32 Språkobjekt Vektorer, matriser Språkobjekt (language objects) har tillstånd som function expression name Alla enkla dataobjekt är vektorer. Inga skalärer i R. Attributet dim bestämmer om en vektor är en matris. > x <- c(1, 2, 3, 4, 5, 6) > dim(x) <- c(2, 3) > x [,1] [,2] [,3] [1,] 1 3 5 [2,] 2 4 6 Enklare (?): x <- matrix(x, nrow = 2, ncol = 3) Statistisk Programmering, hösten 2002 p.11/32 Statistisk Programmering, hösten 2002 p.12/32
Lista (list) Databas (data.frame) I en vektor är alla element av samma typ. En lista är en vektor där elementen får vara av godtycklig typ, t.o.m. andra listor. Liknar en structure i C, men är mer flexibel. lista <- list() x <- c(1,2,3) lista[["age"]] <- x lista$age <- x lista$age <- NULL En lista med variabler av samma längd, men möjligen av olika typ, t.ex. numeric, factor, character, logical, > library(mass); data(painters) > painters Comp Draw Col Expr School Da Udine 10 8 16 3 A Da Vinci 15 16 4 14 A > data <- read.table( Statistisk Programmering, hösten 2002 p.13/32 Statistisk Programmering, hösten 2002 p.14/32 Indexering, vektorer x[ind], där ind är Vektor med positiva heltal, 1 <= tal <= length(x). ind kan vara hur lång som helst. Logisk vektor. Måste vara av samma längd som x. Plockar ut de element i x som svarar mot TRUE i ind. Vektor med negativa heltal. Anger element som ska tas bort. Vektor med textsträngar. För namngivna vektorer. Matriser och databaser > x <- matrix(1:6, ncol = 3) > x 1 3 5 2 4 6 is.matrix(x[, 1]) [1] FALSE > is.matrix(x[, 1, drop = FALSE]) [1] TRUE En data.frame kan indexeras som om den vore en matris. Se upp med drop-ing! Statistisk Programmering, hösten 2002 p.15/32 Statistisk Programmering, hösten 2002 p.16/32
Litteratur Funktioner, klassiska språk Läs An Introduction to R. Dalgaard (2002): Introductory Statistics with R, Springer. Venables & Ripley (2002): Modern Applied Statistics with S, Fourth Edition. Springer. Venables & Ripley (2000): S Programming. Springer. (i stigande svårighetsgrad ). HUVUDPROGRAM program gb integer k, len double precision x(100), 1 y(100), z do k = 1, len x(k) = k y(k) = len - k + 1 end do call inner(len, x, y, z) end FUNKTION subroutine inner(n, x1, x2, y) integer n double precision x1(n), 1 x2(n), y integer k y = 0.d0 do k = 1, 10 y = y + x1(k) * x2(k) end do return end Statistisk Programmering, hösten 2002 p.17/32 Statistisk Programmering, hösten 2002 p.18/32 Funktioner i matematiken Definition: En funktion f från en mängd X till en mängd Y är en regel, som till varje x X knyter precis ett element y Y. Vi skriver: y = f(x), x X, y Y. Funktioner i R En funktion f saknar sidoeffekter om > y <- f(x) endast ändrar/skapar y. Önskvärd egenskap, oftast. y <- sin(x) # men y <- plot(x) # för sidoeffekten! Statistisk Programmering, hösten 2002 p.19/32 Statistisk Programmering, hösten 2002 p.20/32
Funktioner i R Lexical scoping HUVUDFUNKTION gb <- function(){ x <- 1:10 y <- 10:1 z <- inner(x, y) FUNKTION inner <- function(x1, x2){ # Kolla indata: if (!is.numeric(x1)) stop("x1 ",) sum(x1 * x2) ## = svaret Enda sättet att returnera ett värde från funktionen är via sista raden. I huvudfunktionen får z värdet sum(x1 * x2) från funktionen inner. Obs: I R vet vektorer hur långa de är! I R vet funktioner var de är definierade, och de har tillgång till objekt definierade där! gb <- function(){ inner <- function() sum(x * y) x <- 1:10 y <- 10:1 inner() Var letas en variabel? Jo, 1. Lokal variabel. 2. I argumentlistan. 3. Den definierande miljön. Statistisk Programmering, hösten 2002 p.21/32 Statistisk Programmering, hösten 2002 p.22/32 Grafik Vitt brus Läs dokumentationen om par and plot! För att importera grafik i ett L A T E X-dokument, I R: > par(bg = "white") ## För vit bakgrund. > plot(1:100, rnorm(100), type = "l", + xlab = "time", main = "white noise") > dev.copy2eps(file="wn.eps") och i L A T E X: \begin{center \begin{figure\label{fig:vitt \epsfig{file = wn.eps, width = \textwidth \caption{simulerat vitt brus \end{figure \end{center rnorm(100) 2 1 0 1 2 3 white noise 0 20 40 60 80 100 time Figure 1: Simulerat vitt brus Statistisk Programmering, hösten 2002 p.23/32 Statistisk Programmering, hösten 2002 p.24/32
Flödeskontroll, while Flödeskontroll, repeat Newtons metod för rotutdragning : square.root <- function(y){ if (y < 0) stop("negative values no-no") x <- y / 2 while (abs(x*x-y) > 1e-10) x <- (x+y/x)/2 x Det kan hända att en while-loop inte genomlöps någon gång. square.root <- function(y){ x if (y < 0) stop("negative values no-no") x <- y / 2 repeat{ x <- (x+y/x)/2 if (abs(x*x-y) < 1e-10) break repeat-loopen genomlöps minst en gång. Statistisk Programmering, hösten 2002 p.25/32 Statistisk Programmering, hösten 2002 p.26/32 Flödeskontroll, for Sammansatta uttryck > x <- seq(0, 1,.05) > plot(x, x, ylab = "y", type = "l", + main = "Power curves") > for (j in 2:8) lines(x, xˆj) y 0.0 0.4 0.8 Power curves 0.0 0.2 0.4 0.6 0.8 1.0 I repeat-exemplet repeat{ x <- (x+y/x)/2 if (abs(x*x-y) < 1e-10) break är två uttryck sammanbuntade inom {. Kallas ett sammansatt uttryck. Värdet är värdet av sista uttrycket. Rekommendation: Använd alltid { i samband med for, while och repeat! x Statistisk Programmering, hösten 2002 p.27/32 Statistisk Programmering, hösten 2002 p.28/32
Villkorliga uttryck, if Villkorliga uttryck, ifelse appr.eq <- function(x, y){ identical(all.equal(x, y), TRUE) if (appr.eq(x, y)){ do.something else if (x < y){ do.something.else else{ stop("y can t be smaller than x") x <- ifelse(x < 0, 0, x) ersätter alla negativa värden i vektorn x med 0 (noll). Vektoriserad version av if. Också for (i in 1:length(x)){ if (x[i] < 0){ x[i] <- 0 x <- pmax(x, 0) ger önskat resultat. Statistisk Programmering, hösten 2002 p.29/32 Statistisk Programmering, hösten 2002 p.30/32 Kategoriska variabler, factor Uppgifter, lektion 2 En faktor har nivåer (level). Exempel: > pain <- c(0, 3, 2, 2, 1) > f.pain <- factor(pain, levels = 0:3) > levels(f.pain) <- + c("none", "mild", "medium", "severe") En användbar funktion är relevel, som väljer (ny) referenskategori. > f.pain <- relevel(f.pain, ref = "medium") 1. order och sort: I databasen painters (MASS) är målarna sorterade efter School. Bilda en ny databas där målarna istället är sorterade i bokstavsordning (dvs hela databasen ska vara sorterad på samma sätt). 2. För painters, gör en scatterplot av Expression mot Composition, men så att alla punkter med Colour högst 9 får blå färg, medan punkter med Colour över 9 blir röda. Välj lämplig text på x- och y-axel, etc. 3. Samla alla dina lösningar, gamla och kommande, i ett L A T E X-dokument, som ska lämnas in till mig i god tid före den sjätte dagen (lektionen)! Statistisk Programmering, hösten 2002 p.31/32 Statistisk Programmering, hösten 2002 p.32/32