Programování v R 2.3 Konverze různých typů objektů Při psaní programuje velmi často třeba konvertovat jeden typ objektu na druhý. V R existuje řada funkcí pro tento účel: as.numeric (x) as.character (x) as.expression (x) as.matrix (x) as.data.frame (x) data.matrix (x) Posledně uvedené tři funkce konvertují objekt x na matici nebo data frame. O něco přívětivější možnost převedení data framu na matici představuje funkce data. matrix , která konvertuje všechny proměnné data framu x na numerické a pak je spojí jako sloupce jediné matice. is.numeric (x) is.character (x) is.logical (x) is.matrix (x) is.data.frame (x) Testují typ daného objektu x 2.4 Vstup/výstup print (x) Zobrazí hodnotu vybraného objektu jazyka R. cat(..., file="", sep="") Funkce cat () zobrazí jeden nebo více objektů výrazně primitivnějším způsobem než print (), umožňuje však mnohem větší kontrolu nad způsobem zobrazování. Tato funkce sama o sobě neodřádkovává, pro nový řádek je potřeba explicitně uvést řetězec „\n". Např. ^2/9 > x<-5.8 > cat("Výsledek je ",x," N/m. \n") Výsledek je 5.8 N/m. Této funkce lze použít i pro zapisování dat do souboru na disk — viz dokumentace k R. readline () Používá se ke vstupu dat z klávesnice. > x<-readline("Zadej hodnotu x:\n") Zadej hodnotu x: 5.8 > x [1] "5.8" Z tohoto příkladu je jasné, že vstup dat je vždy ve formě textového řetězce, a že hodnota numerické proměnné musí být případně konvertována následující funkcí: > x<-as.numeric(x) > x [1] 5.8 data.entry (x) Vyvolá zabudovaný editor, který lze použít pro vložení/editaci dat v jednoduchém spreadsheetu. Příkaz může být volán s parametrem x, specifikujícím objekt určený k editaci. 2.5 Podmíněné příkazy Podmíněné provádění příkazů se provádí pomocí funkce: if (podmínka) vyrazí else výraz2 Pokud je splněna podmínka, provádí se instrukce ve výrazul, v opačném případě ve výrazu2 . Složitější výrazy vyžadují použití složených závorek: if (x>2 & y=l!\n") } 2.6 Příkazy cyklu I když v R— na rozdíl od jazyků BASIC nebo PASCAL — se tomu lze obvykle vyhnout, je možné i zde používat příkazů cyklu. for (proměnná in výraz!) výraz2 Výraz2 se provádí pro hodnoty proměnné postupně definované pomocí výrazul. Složitější výrazy je třeba uzavřít do složených závorek. 2/10 Kupříkladu kód: for (f in (1:5)) { cat("Druha mocnina",f) cat(" je",fA2,"\n") } Dává výstup: Druha mocnina 1 je 1 Druha mocnina 2 je 4 Druha mocnina 3 je 9 Druha mocnina 4 je 16 Druha mocnina 5 je 25 while (podmínka) výraz výraz se bude provádět dokud je splněna podminka repeat (podmínka) výraz Poznámka: snažte se příkazům cyklu pokud možno vyhýbat — jejich provádění v R znatelně zpomaluje provádění programu. Cvičení 2.4 o pomocí cyklu a funkce par (mfrow=) napište krátký program, který najednou zobrazí šest Harkerových diagramů (binárních diagramů SÍO2 vs.další oxidy hlavních prvků) podle Vaší volby. Použijte souboru s daty pro sázavskou suitu. Nezapomeňte na správný popis os. > WR<-read.table("sazava.data",sep="\t") > WR<-as.matrix(WR[,-1]) > windows() > par(mfrow=c(2,3)) > ee<-c("A1203","FeO","Fe203","MgO","CaO", "K20") > for (f in ee){ > plot(WR[,"Si02"],WR[,f],xlab="Si02",ylab=f,pch=WR[,"Symbol"]) > } Nyní můžeme napsat o něco sofistikovanější formu programu, která bude využívat možnosti anotací pomocí funkce expression. Nejprve musíme ale znát, že konverze character vektoru x na výraz (angl. expression) se provádí funkcí parse: > parse(text=as.expression(x)) and then the modified part of the code will be: > lab<-c("Al[2]*0[3]","FeO","Fe[2]*0[3]","MgO","CaO","K[2]*0") > for (f in 1:length(ee)){ > plot(WR[,"Si02"],WR[,ee[f]],xlab=expression(SiO[2]), ylab=parse(text=as.expression(lab[f])),pch=WR[,"Symbol"]) > } > # Obr. 2.8 oř 2/n 50 55 60 65 70 50 55 60 65 70 50 55 60 65 70 Obr. 2.8. Vybrané Harkerovy diagramy pro sázavskou suitu (Cvičení 2.4) 2.7 Uživatelské funkce jméno<- function {argumentl, argument!, ...) výraz Posledním příkazem v těle definice uživatelské funkce by měl být return (x) , s argumentem upřesňujícím jméno proměnné, kterou má funkce vracet. Jinak se bere ta, jíž byla naposledy přiřazena nějaká hodnota. 7=1 11 ): Příklad použití — funkce pro výpočet směrodatné odchylky (podle vzorce S- odchylka<-function(x){ z<-sqrt(sum((x-mean(x))A2)/length(x)) return(z) # funkce vraci hodnotu proměnné z } Důležité je si uvědomit, že proměnné použité ve funkci (v našem příkladu x a z) jsou lokální, tedy mimo ni neznámé. Pokud načteme do paměti soubor sazava. data, můžeme pomocí funkce odchylka () spočítat třeba směrodatnou odchylku pro SÍO2: 2/12 > WR<-read.table("sazava.data",sep="\t") > WR<-as.matrix(WR[,-1]) > odchylka(WR[,"Si02"]) [1] 7.462887 Cvičení 2.5 V anglosaských zemích se teploty stále hojně vyjadřují ve stupních Fahrenheita. o navrhněte funkci, která bude konvertovat stupně Fahrenheita na stupně Celsia o vyzkoušejte si, jak funkce pracuje, na předcházejícím diagramu — kolik je ve stupních Celsia -40, 98.6 a 212 °F? o vypište konverzní tabulku Fahrenheit —► Celsius pro 0, 10, .. .220 °F a zobrazte data graficky Fahrenheit -40° Freezing 32° Human body temperature 98.6° Boiling 212° 0 1 40° 80° 1 1 120° 160° 200° I I I 1 -20° 1 20° III 40° 60° 80° -40° Celsius 37° 100c Obr. 2.9 Graficky vyjádřený vztah mezi Fahrenheitovou a Celsiovou stupnicí Fahrenheit2Celsius<-function(x){ a<-100/(212-32) b<-100-a*212 z<-a*x+b return(z) } > Fahrenheit2Celsius(c(-40,98.6,212)) [1] -40 37 100 > x<-seq(0,220,by=10) > y<-Fahrenheit2Celsius(x) > names(y)<-x Fahrenheit Obr. 2.10 Konverze Fahrenheit —> Celsius > y o -17.777778 70 21.111111 140 60 . 000000 210 98.888889 104.444444 10 -12 .222222 80 26 .666667 150 65.555556 220 20 —6.666667 90 32.222222 160 71.111111 30 .111111 100 .777778 170 76 .666667 -1 . 37 . 40 4.444444 110 43.333333 180 82 . 222222 50 10 .000000 120 190 87.777778 60 15.555556 130 54.444444 200 93.333333 > plot(x,y,xlab="Fahrenheit",ylab="Celsius",type="o") > # Obr. 2.10 CÍä 2/13 2.7.1 Argumenty funkcí Existují dva způsoby, jak specifikovat parametry funkce jazyka R. Buď je lze uvádět v pořadí stejném, jakém byly definovány, když byla funkce navržena. Nebo je možno používat pojmenované parametry ve formě "jméno. argumentu = hodnota", a ty lze pak uvádět v náhodném pořadí. Při psaní uživatelských funkcí lze uvádět implicitní hodnoty, jako v následujícím případě: > my.plot<-function(x,y,pch="+",col="red"){ > ...tělo funkce... > } a potom může být taková funkce volána řadou způsobů, například: > my.plot(x,y) # plots data as red crosses > my.plot(x,y,"o") # plots data as red circles > my.plot(x,y,col="blue") # plots data as blue crosses pak je také zřejmé, že příkaz: > my.plot(x,y,"blue") nebude fungovat správně. Dobré je si uvědomit, že v R má většina argumentů funkcí přiřazeny nějaké rozumné implicitní hodnoty. Ty obvykle stačí pro většinu aplikací a běžný uživatel nemusí o jejich existenci vůbec vědět. Když je třeba, příkaz args vypíše všechny argumenty dané funkce: args (jméno_funkce) kde jméno_f unkce odkazuje na existující funkci, například: > args("my.plot") function (x, y, pch = "+", col = "red") 2.7.2 Přiřazení ve funkcích Důležité je si uvědomit, že všechny proměnné definované v rámci uživatelské funkce (v příkladu funkce pro výpočet směrodatné odchylky to byly x a z) jsou lokální. To znamená, že všechna přiřazení jsou jen přechodné povahy, a po opuštění funkce jsou ztracena. Proto taky je třeba rozlišovat proměnné, byť se stejným jménem, ve funkci a v prostředí, z kterého byla funkce volána. Ve (vzácných) případech kdy je třeba měnit hodnotu globální proměnné, lze použít operátor "«-": > x«-"Hello"