Afdeling for Teoretisk Statistik STATISTIK 2 Institut for Matematiske Fag Jørgen Granfeldt Aarhus Universitet 24. september 2003 Hermed en udvidet udgave af Jens Ledet Jensens introduktion til R. 1 Start og afslutning. Help. Regne- og tegneprogrammet R findes på serveren durin. I skal derfor starte med i et terminalvindue at skrive xlogin durin så bliver der automatisk åbnet et nyt terminalvindue, hvor I er logget på serveren durin. I det nye terminalvindue skriver I R hvorved I starter programmet. Programmet er klart, når der kommer > på skærmen. Når en ordre er indtastet og afsluttet med return, må man vente på at > kommer frem, før man kan give en ny ordre. Programmet afsluttes ved at skrive q() Man vil så blive spurgt, om man ønsker at gemme de variable, man har for øjeblikket. R har en online manual, hvor man kan få forklaring på forskellige R-ordrer. For eksempel vil help(sum) give en beskrivelse af hvordan sum virker. Man kommer ud af manualen ved at taste q. Når man i R tildeler en variabel en værdi gøres dette ved at bruge det sammensatte symbol <- eller simpelthen et =. Man kunne også bruge understregning _, men det symbol er på vej ud af sproget. Ordren x <- 7 tildeler x værdien 7. Decimaltal angives ved hjælp af punktum: en halv skrives således som 0.5. ADVARSEL: Brug aldrig q eller c som navn på egne variable. Når man kører R, er det en god ide, at man skriver sine ordrer i en editor og så kopierer dem over i terminalvinduet med musen, når de skal udføres. Man må gerne kopiere flere linier med ordrer på én gang. 2 Vektorer - simple beregninger. Jeg vil bruge ordet vektor for en række tal med angivelse af en rækkefølge. Hvis en vektor har længde 3 kan jeg således tale om første, anden og tredje indgang i vektoren. Hvis første indgang indeholder tallet 7, anden indgang indeholder tallet 1, og trejde indgang indeholder tallet 4, skriver jeg vektoren som (7, 1,4). R er vektorbaseret, hvilket nok er en af de vigtigste egenskaber ved programmet. Dette betyder at hvis man lægger to vektorer, af samme længde, sammen, vil hver indgang blive lagt sammen for sig, og resultatet er igen en vektor. Hvis man lægger et tal til en vektor vil tallet blive lagt til alle indgangene i vektoren. Man kan danne vektorer i R ved hjælp af kommandoen c: 1
x <- c(7,-1,4) danner vektoren (7, 1,4) og denne har fået navnet x. Funktionen c binder elementer sammen i en vektor. Hvis jeg ønsker at danne vektoren y = (1,2,3,4,5) kan jeg skrive y <- c(1:5) istedet for y <- c(1,2,3,4,5) Jeg kan også få y frem ved y <- c(c(1:3),4,5) y Hvis man vil se indholdet af en variabel skriver man blot den pågældene variabels navn: giver som resultat: [1] 1 2 3 4 5 Her er [1] en meddelelse om, at det er element nummer 1, der følger lige efter. Dette gør det nemmere at overskue, når y fylder mere en én linie. Det i te element i vektoren x har navn x[i]. Man kan lave en delvektor af en vektor ved at angive de indgange der skal med. Hvis x = (7, 1,4,3,3) vil y <- x[c(1,3,4)] tildele y værdien (7,4,3). Vektorer kan også genereres ved hjælp af rep kommandoen: a <- rep(c(1:4),3) danner en vektor a af længde 12, hvor tallene 1,2,3,4 gentages 3 gange. Hvis vi i stedet skriver a <- rep(c(1:4),c(3,3,3,3)) får vi vektoren (1,1,1,2,2,2,3,3,3,4,4,4). Hvis man har to vektorer x, y af samme længde, vil de sædvanlige regneoperationer blive udført elementvis. Således vil ordren z <- x*y medføre at første indgang i x ganges med første indgang i y, anden indgang i x ganges med anden indgang i y, og så videre. Resultatet lægges ind i den nye vektor z. Ordren z <- 2.3*y ganger tallet 2.3 på alle indgangene i vektoren y. Ordren z <- log(y) tager logaritmen (den naturlige) til hver enkelt indgang i y. Ordren z<- y^2 kvadrerer elementerne i y og er således det samme som z<- y*y Mere specialiserede R kommandoer vil dog ikke nødvendigvis have en vektor som resultat. Ordren sum(x) 2
vil udregne summen af elementerne i x, og vil returnere et tal. Ordren length(x) vil beregne længden af x, altså antallet af indgange i x. Af tilsvarende kommandoer kan nævnes min(x) max(x) mean(x) som udregner henholdsvis det mindste element i x, det største element i x, og gennemsnittet af elementerne. Vi kan ordne elementerne i x efter størrelse med ordren sort(x) 3 Simple plots. Hvis vi har to vektorer x og y af samme længde, kan vi afsætte punkterne (x[i],y[i]) med ordren plot(x,y) Hvis vi blot skriver plot(x) vil dette være ækvivalent med plot(c(1:length(x)),x) Nye punkter kan tilføjes et allerede eksisterende plot. Hvis a og b er to vektorer af samme længde vil ordren points(a,b) tilføje punkterne (a[i],b[i]). Hvis vi i stedet havde skrevet lines(a,b) ville de tilføjede punkter være forbundet med liniestykker. Hvis vi i stedet for plot skriver plot(x,y, type="l") vil punkterne blive forbundet med liniestykker. En ret linie der skærer y-aksen i 2.3 og har hældning 1.4 kan indsættes med ordren abline(2.3,1.4) Ved brug af plot-kommandoen udregner R selv et passende område for første- og andenaksen. Hvis man selv vil styre dette, kan man skrive plot(c(0,0,100,100),c(-10,10,-10,10),xlab="x-akse",ylab="y-akse",type="n") som opretter et koordinatsystem, hvor førsteaksen løber fra 0 til 100, og andenaksen løber fra -10 til 10. Beskeden type = "n" angiver, at der ikke skal indsættes punkter. Desuden er der angivet at akserne har navnene x-akse og y-akse. De mange mulige ordre til at styre udseendet af et plot kan findes under par i manualen. Her nævner jeg blot en enkelt. Ordren par(mfrow = c(2,3)) vil bevirke, at plot-vinduet opdeles i 6 områder, arrangeret i 2 rækker med 3 områder i hver, og de efterfølgende 6 plots placeres i disse 6 områder. R har også et antal mere avancerede plot kommandoer. For eksempel vil kommandoen 3
hist(x) lave et histogram af data i vektoren x Man kan kontrollere forskellige træk ved histogrammet ved at tilføje parametre kommandoen. Se manualen. Endnu en nyttig kommando er qqnorm(x) som giver et fraktildiagram til kontrol for normalfordeling af data i vektoren x. Et fraktildiagram kan også laves med kommandoen plot(sort(x), qnorm((c(1:length(x))-0.5)/length(x))) Funktionen qnorm, der bruges her, giver fraktiler (engelsk: quantile) for standard normalfordelingnen. Man kan udskrive et plot til en postscript fil med navnet mitplot.ps med ordren dev.print(file="mitplot.ps") eller man kan sende plottet til en printer (her H2) med kommandoen dev.print(file=" lp -dh2") 4 Fordelinger En række af de vigtigste fordelinger findes i R: Binomial, Poisson, normal, Gamma, Beta, F, χ 2 og t. Man har adgang til tæthed, fordelingsfunktion, invers fordelingsfunktion (fraktiler) samt en funktion til at simulere stikprøver fra fordelingen. De fire forskellige muligheder opnås med skelnes med prefixene d, p, q og r. For eksempel giver ordren pnorm(-3+0.1*c(0:60) værdierne af fordelingsfunktionen for standard normalfordelingen i punkterne 3.0, 2.9,..., 2.9, 3.0. 5 Funktioner Det er muligt at lave brugerdefinerede funktioner is R. For eksempel definerer kommandoen g <- function() { x <- rnorm(10) sum(x)/10 } en funktion g, som når den kaldes med g() giver gennemsnittet af 10 simulerede observationer fra en standard normalfordeling. Alternativt kunne man definere g med en parameter n g <- function(n) { x <- rnorm(n) sum(x)/n } og så skrive g(10) Hvis vi ønsker at bruge funktionen mange gange kan vi benytte lapply. Hvis vi for eksempel vil beregne g(11), g(12),...,g(20) kan dette gøres med lapply(c(11:20)),g) 4
6 Matricer I R kan man også lave beregninger med matricer. Kommandoen m <- matrix(c(c(1:10),c(21:30)),10,2) gør m til en matriks med 10 rækker og to søjler. I første søjle er tallene 1,2,...,10 og i anden søjle er tallene 21, 22,..., 30. Hvis man derimod skriver m <- matrix(c(c(1:10),c(21:30)),10,2,byrow=t) fås igen en 10 2 matriks, hvor rækkerne fyldes op først. Det kan kontrolles ved at taste m: > m [,1] [,2] [1,] 1 2 [2,] 3 4 [3,] 5 6 [4,] 7 8 [5,] 9 10 [6,] 21 22 [7,] 23 24 [8,] 25 26 [9,] 27 28 [10,] 29 30 Man kan referere til rækker og søjler i en matriks i R, som det også fremgår af udskriften ovenfor. Anden række læses ind i variablen row2 med row2 <- m[2,] og tilsvarende læses anden søjle ind i col2 med col2 <- m[,2] 7 Multipel regression Dette afsnit er taget med som et eksempel på nogle af de mere avancerede ordrer i R. Vi betragter modellen Y i N(α + β 1 z i1 + β 2 z i2 + + β p z ip,σ 2 ), i = 1,...,n. For at estimere parametrene i denne model i R indsætter vi først data i en vektor y <- c(y1,...,yn) og dernæst de forklarende variable i en matiks z <- matrix(c(z11,z21,...,zn1,z12,...,znp),n,p) I de ovenstående to ordrer betyder prikkerne at vi skriver alle y-værdierne, henholdsvis alle z-værdierne. Se også Afsnit 8 for andre muligheder for indlæsning af data i y og z. Med ordren res <- lsfit(z,y) får vi estimeret modellen og resultatet lægges over i res. Hvis vi skriver res$coef får vi estimaterne ˆα, ˆβ, og hvis vi skriver res$residuals får vi residualerne y i ˆα ˆβ 1 z i1 ˆβ p z ip. 5
8 Indlæsning af data Data kan indlæses fra en fil med ordren scan. Hvis filen datafil indeholder en række tal vil ordren data <- scan("datafil") danne en vektor data, der indeholder tallene fra datafil i den rækkefølge hvori de står i filen. Her kan "datafil" indeholde filnavn såvel som den absolutte sti til filen. Også når R kører under Windows anvendes Unix konventionen for at angive stier. Hvis der er et lige antal tal i datafil og vi ønsker at placere hvert andet tal, startende med det første, i x, og hvert andet, startende med det andet, i y, kan vi skrive x <- data[2*c(1:(length(data)/2))-1] og y <- data[2*c(1:(length(data)/2))] Betragt som eksempel filen datafil med følgende data data y 1 y 2 y n z 11 z 21 z n1.... z 1p z 2p z np Vi ønsker at læse disse data og lægge y-værdierne ind i en vektor y og at lægge z-værdierne i en n p matriks z. Først læser vi data ind i vektoren data med data <- scan("datafil") og derefter læser vi y-værdierne ind i y med y <- data[1:n] og endelig læser vi z-værdierne ind i z i en p p matriksstruktur med z <- matrix(data[(n+1):(n*(p+1))],n,p) Hvis derimod datafil har indholdet kan vi bruge y 1 z 11 z 12 z 1p y 2 z 21 z 22 z 2p..... y n z n1 z n2 z np data <- matrix(scan("datafil"),n,(p+1),byrow=t) til at læse data ind i n (p + 1) matricen data og derefter give y værdierne i første søjle med y <- data[,1] og derefter lade z være p p matricen af z er med z <- data[,2:(p+1)] 6
9 Opgaver Opgave 1. Lav en xlogin til durin og start R. Konstruer vektoren x = (1,4,9,16). Tag kvadratroden (hedder sqrt i R) til x og placer denne i y. Udskriv indholdet af y. Konstruer vektoren z = (1, 1) og tag kvadratroden af denne (I får her en protest fra programmet). Forlad R. Opgave 2. Læs manualindgangen for c. Prøv ordren c(1:5, 10.5, "next") Indholdet mellem to "opfattes af R som en tekststreng. Prøv ordren hel p(sin) Opgave 3. Funktionen sum Hvis x er en vektor vil ordren sum(x) udregne summen af elementerne i x. Hvis for eksempel x = (1.3,7.2,4.6) vil sum(x) give værdien 13.1. Lav en vektor x som indeholder tallene 1,2,3,4,5. Find summen 1 + 2 + 3 + 4 + 5. Find summen 1 + 4 + 9 + 16 + 25 = 1 2 + 2 2 + 3 2 + 4 2 + 5 2. Opgave 4. Funktionen cumsum Hvis x er en vektor vil ordren cumsum(x) danne en ny vektor hvor første indgang er x[1], anden indgang er x[1] + x[2], trejde indgang er x[1] + x[2] + x[3], og så videre. Lad x = (1,2,3,4,5,6,7,8,9,10). Udregn cumsum(x). Udregn også x (x + 1)/2. Opgave 5. Lad x = (1,2,3,4,5,6,7,8,9,10) og lad y = (2.6,4.1,6.8,7.6,8.2,11.9,9.0,11.8,11.9,15.6). Lav et plot af de 10 punkter (x[i],y[i]). Indsæt linien med skæring 3 og hældning 1. Opgave 6. Lav et plot af sinus-funktionen i intervallet fra 0 til 2π. Hjælp: ordren x <- c(0:1000)*2*pi/1000 laver en vektor med 1000 tal i intervallet fra 0 til 2π. Opgave 7. Store tals lov Hvis vi kaster en mønt får vi enten plat eller krone hver med sandsynlighed 1 2. Vi repræsenterer plat med 0 og krone med 1. I R kan vi generere et tilfældigt 0 eller 1 med ordren ifelse(runif(1)<0.5,0,1) Hvis jeg vil generere 100 tilfældige møntkast"og placere disse i vektoren x100 skriver jeg x100 <- ifelse(runif(100)<0.5,0,1) Intuitivt forventer jeg at frekvensen af krone"i x100 er cirka 0.5. Frekvensen kan udregnes som sum(x100)/100 Lav 1000 møntkast"og indsæt disse i en vektor y. Lad z være cumsum af y, og lad p være z divideret med vektoren bestående af tallene 1,2 op til 1000. Lav et plot af p og indsæt linien med skæring 0.5 og hældning 0. 7