2  Proměnné

Málo kdy pracujeme s daty přímo jako s čísly. V případě velkých dat by to ani nebylo možné. Místo toho svá data uložíme do proměnných a dále pracujeme s těmito proměnnými. Kromě usnadnění práce to má ještě jednu výhodu: naše skripty jsou tak obecnější. Můžeme např. napsat analytický kód s pomocí dat z pilotního průzkumu, a pak jej spustit znovu ve chvíli, kdy doběhl celý sběr dat, s novými daty. Vyměníme jen datový soubor a jinak nemusíme svůj kód vůbec měnit.

V této kapitole se naučíte

2.1 K čemu slouží proměnné

Koncept proměnné znáte z matematiky. Tam je proměnná “krycí název” pro nějakou hodnotu, např. pro číslo 5. Krása proměnných spočívá v tom, že umožňují počítat zcela obecně. Pokud např. označíme délku trasy v kilometrech písmenem \(s\) a rychlost jízdy v kilometrech za hodinu písmenem \(v\), pak víme, že vzdálenost \(s\) ujedeme za \(s/v\) hodin. Tento výsledek platí bez ohledu na to, jak daleko a jak rychle jedeme. Jak už naznačuje název proměnná, můžeme hodnotu proměnné měnit, a výraz \(s/v\) vyhodnotit pokaždé znovu. Pro jednoduchý výpočet, který jsme právě uvažovali, nemusí být takové zobecnění příliš užitečné, ale při složitých výpočtech nad velkými daty je zavedení proměnných velká pomoc. V počítači plní proměnné stejnou úlohu jako v matematice: uchovávají nějakou hodnotu. Můžeme počítači říct, co má s touto hodnotou dělat, bez toho, abychom přesně věděli, jaká tato hodnota je.

I když to technicky není přesné, můžeme si proměnnou představit jako krabičku, do které se vloží nějaká hodnota. Každá proměnná může v jednom okamžiku obsahovat vždy jen jednu hodnotu. Pokud do proměnné uložíme novou hodnotu, stará hodnota se ztratí. Slovo “hodnota” je však třeba brát volně: “hodnota” může být stejně dobře jedno číslo jako složitá struktura složená z čísel, textů a jiných objektů. (Technicky přesnější je říct, že proměnná je jméno, které se odkazuje na nějakou oblast v paměti počítače, kde jsou uložena naše data. Aby počítač věděl, jak s daným kusem paměti zacházet, musí vědět, jakého typu jsou uložená data, např. zda se jedná o celá čísla nebo o text, a v jaké datové struktuře jsou data uložena, např. ve vektoru.) R je volně typovaný jazyk. To znamená, že typ proměnné nemusíte nijak deklarovat a R jej samo odhadne podle vložené hodnoty. Do proměnné můžete v jedné chvíli uložit číslo a později toto číslo nahradit třeba kusem textu. R si s tím poradí. (Proměnná bude prostě nejdříve odkazovat na jedno místo v paměti počítače, a pak na jiné. Nepoužívanou oblast paměti R samo uvolní.)

2.2 Jména proměnných

Jména proměnných musí splňovat určité vlastnosti. Jméno proměnné se může skládat jen z písmen, číslic, teček a podtržítek a musí začínat písmenem nebo tečkou, za kterou nenásleduje číslice. Jména a, a2, myNumber, my_number, .my.way nebo i jen . jsou přípustná. Naproti tomu jména jako 2way, .2way nebo my-number nejsou povolená. Stejně tak nejsou povolená rezervovaná slova: if, else, repeat, while, function, for, in, next, break, TRUE, FALSE, NULL, Inf, NaN, NA, NA_integer_, NA_real_, NA_complex_ a NA_character_. Ve jménech proměnných záleží na velikosti písmenem, takže a a A jsou dvě různé proměnné.

Jméno proměnné by ideálně mělo být stručné a mělo by výstižně popisovat, jakou hodnotu proměnná obsahuje. Pokud se jméno skládá z více slov, slova se historicky oddělovala tečkami (např. pv.of.bond). V současné době se to nedoporučuje, protože tečky se používají i k oddělení generické a specifické části jmen objektových metod, viz kapitola 8. Místo toho se doporučuje používat podtržítka (pv_of_bond) nebo případně tzv. “Camel Case” standard (pvOfBond), který však v R není příliš obvyklý.

Někdy je potřeba pracovat s proměnnou, jejíž jméno není v R povoleno. (Taková situace nejčastěji vznikne při importu dat z jiného softwaru.) Proměnnou s nelegálním jménem můžete použít, pokud její jméno uzavřete mezi dva zpětné apostrofy (“backticks”). Jméno proměnné nemůže obsahovat (mimo jiné) mezeru. Pomocí zpětných apostrofů však můžete pracovat i s proměnnou, jejíž jméno mezeru obsahuje:

`ahoj lidičky!` <- 5
2 * `ahoj lidičky!`
[1] 10

I když je možné používat i “nedovolená” jména proměnných, je téměř vždy lepší se tomu vyhnout a proměnné přejmenovat.

2.3 Přiřazení hodnoty do proměnné

Hodnoty se do proměnných přiřazují pomocí “šipky” <-, která se skládá ze dvou znaků: < a -. (V RStudiu lze šipku vložit pomocí klávesové zkratky Alt-.) Šipka vždy ukazuje ke jménu proměnné, zatímco na druhé straně je výraz, který má R vyhodnotit. (Funguje i šipka -> otočená opačným směrem. Tuto kuriozitu však výrazně nedoporučujeme používat, protože ztěžuje čtení kódu: co se s daným výrazem stane, zjistíte až na konci možná velmi dlouhé konstrukce.)

x <- (2 + 3) * 4  # x má nyní hodnotu 20
x  # jak se vzápětí přesvědčíme
[1] 20

Někteří lidé používají k přiřazení do proměnné i symbol rovnítka (=). To rovněž nedoporučujeme. Rovnítko v některých kontextech funguje jako synonymum šipky, zatímco v jiných ne (tam rovnítko znamená něco jiného). Použití rovnítka k přiřazení je tak matoucí. Detaily najdete na https://goo.gl/Tnu8Q5.

2.4 Vypsání hodnoty proměnné do konzoly

Při přiřazení hodnoty do proměnné se výsledek nevypíše. Pokud jej chcete vypsat, musíte o to R požádat. To můžete udělat třemi způsoby: 1) explicitně vypsat obsah proměnné pomocí funkce print(), 2) implicitně vypsat obsah proměnné tak, že napíšete její jméno do konzoly (R volá implicitně funkci print() za vás) nebo 3) tak, že celý výraz přiřazení zabalíte do závorek.

x <- "This is some text."  # hodnota se přiřadí, nic se nevypíše
x         # implicitní vypsání hodnoty proměnné x
[1] "This is some text."
print(x)  # explicitní vypsání hodnoty proměnné x
[1] "This is some text."
(y <- 2)  # výraz se vyhodnotí a hodnota implicitně vypíše 
[1] 2

Implicitní forma vypsání obsahu proměnné je vhodná pro interaktivní práci v konzoli, nemusí však fungovat uvnitř funkcí a skriptů, protože ve skutečnosti jen žádáte R o vrácení hodnoty proměnné. Podle kontextu může být vrácená proměnná využita různě. V konzoli se využije tak, že konzola na hodnotu zavolá funkci print(). Uvnitř funkce však může být vrácená hodnota použitá funkcí jinak. Uvnitř funkcí a podobných struktur je tedy třeba obsah proměnné vypsat explicitně pomocí funkce print().

To, jak R vypíše obsah proměnné, se může lišit od skutečného obsahu dané proměnné. R totiž pro různé objekty volá různé varianty (metody) funkce print() přizpůsobené těmto objektům a může vypsat více nebo méně informací, než je jich v dané proměnné obsaženo. To, jak vypisuje data pro základní datové typy a struktury se dozvíte v následujících dvou kapitolách.

Někdy proměnná obsahuje mnoho hodnot (např. dlouhý vektor, tabulku s mnoha řádku apod.) a my ji nechceme vypsat celou, nýbrž z ní chceme získat jen nějakou ukázku, typicky několik prvních nebo posledních hodnot. Několik prvních hodnot vrací funkce head(), posledních hodnot funkce tail(). Obě vrací implicitně 6 hodnot (prvků vektoru, řádků matice apod.); tento počet lze změnit nastavením parametru n:

x <- matrix(1:1200, ncol = 3)  # vytvoří matici se 400 řádky
head(x)                        # vypíše 6 prvních řádků matice
     [,1] [,2] [,3]
[1,]    1  401  801
[2,]    2  402  802
[3,]    3  403  803
[4,]    4  404  804
[5,]    5  405  805
[6,]    6  406  806
head(x, n = 3)                 # vypíše 3 první řádky matice
     [,1] [,2] [,3]
[1,]    1  401  801
[2,]    2  402  802
[3,]    3  403  803
tail(x)                        # vypíše 6 posledních řádků matice
       [,1] [,2] [,3]
[395,]  395  795 1195
[396,]  396  796 1196
[397,]  397  797 1197
[398,]  398  798 1198
[399,]  399  799 1199
[400,]  400  800 1200

Pokud pracujete v RStudiu, můžete použít k zobrazení obsahu proměnné i funkci View(). Tato funkce otevře novou záložku a zobrazí obsah proměnné. Způsob zobrazení závisí na datové struktuře. Atomické vektory, matice a tabulky zobrazí ve formě interaktivní tabulky, která umožňuje hodnoty třídit a filtrovat. Seznamy a objekty postavené nad seznamy se zobrazí podobně, jako je vypisuje funkce str(). Funkci View() je možné vyvolat i pomocí myši tak, že v záložce Environment kliknete na ikonku tabulky (tabulární pohled) nebo trojúhelníku vedle jména proměnné. Pozor: seznam proměnných musí být v režimu “List”.

2.5 Atributy (metadata)

Proměnné v R obsahují kromě vlastních hodnot také metadata (informace o datech). V R se metadata nazývají atributy.

Funkce attributes() vypíše seznam všech atributů dané proměnné.

x <- c(a = 1, b = 2, c = 3)  # vektor s pojmenovanými prvky
x
a b c 
1 2 3 
attributes(x)
$names
[1] "a" "b" "c"
X <- matrix(1:12, nrow = 3)  # matice má počet řádků a sloupců
X
     [,1] [,2] [,3] [,4]
[1,]    1    4    7   10
[2,]    2    5    8   11
[3,]    3    6    9   12
attributes(X)
$dim
[1] 3 4

Atributy proměnných mohou zahrnovat třídu objektu, dimenze proměnných (počet řádků, sloupců a případně dalších rozměrů objektu), jména řádků, sloupců, jednotlivých prvků vektorů a případně další informace.

Hodnotu jednoho atributu je možné získat funkcí attr(); tuto funkci je zároveň možné použít i ke změně hodnoty atributu (ve skutečnosti se volá jiná funkce, syntaxe však vypadá stejně):

attr(x, "names")
[1] "a" "b" "c"
attr(x, "names") <- c("Ahoj", "Bum", "Cak")
attr(x, "names")
[1] "Ahoj" "Bum"  "Cak" 
x
Ahoj  Bum  Cak 
   1    2    3 

Pokud se zeptáte na hodnotu atributu, který není v proměnné přítomen, funkce attr() vrací hodnotu NULL:

attr(x, "coriandr")
NULL

Atribut zrušíte tak, že do něj přiřadíte hodnotu NULL.

attr(x, "names") <- NULL
x
[1] 1 2 3

2.6 Smazání proměnné

Ke smazání proměnné z aktuálního prostředí slouží funkce rm():

rm(x)  # smaže proměnnou x
rm(x, y, z)  # smaže proměnné x, y a z
rm(list = ls())  # smaže všechny proměnné z aktuálního prostředí

V RStudiu můžete proměnné mazat i myší. V záložce Environment k tomu slouží ikonka koštěte. Pokud máte proměnné zobrazené v režimu Grid, můžete vybrat, které proměnné budou smazány. V režimu List budou smazány všechny proměnné.

Někdy je však potřeba vyčistit paměť R důkladněji. Smazání všech proměnných totiž stále zanechá v R mnoho změn: načtené balíky, změněné cesty apod. Nejdůkladnější vyčištění pracovního prostředí přestavuje restart R. V RStudiu je to možné udělat v menu Session\(\rightarrow\)Restart R nebo pomocí klávesové zkratky Ctrl-Shift-F10. Pokud si chcete ověřit, že váš skript běží spolehlivě, vždy byste jej měli vyzkoušet v čistém prostředí R, tj. po jeho restartu.

2.7 Aplikace: výpočet dojezdové vzdálenosti

Jako příklad práce s proměnnými vytvoříme jednoduchý skript, který spočítá, za jak dlouho dorazíme do cíle. Nejdříve si vyčistíme pracovní prostředí smazáním všech dříve vytvořených proměnných (což je velmi užitečný zvyk). Následně vytvoříme proměnné vzdálenost a rychlost, pak vypočteme dobu jízdy a vypíšeme ji. Náš skript bude tedy vypadat takto:

rm(list = ls())
vzdalenost <- 1079  # vzdálenost z Brna do Dubrovniku v km
rychlost <- 90  # očekávaná průměrná rychlost v km / h
doba_jizdy <- vzdalenost / rychlost
print(doba_jizdy)

Pokud jste svůj skript napsali do nového okna editoru v RStudiu, spustíte jej jednoduše stisknutím tlačítka Source. Výsledkem by mělo být, že pojedete necelých 12 hodin. To byste mohli mnohem jednodušeji zjistit i s pomocí obyčejné kalkulačky. Skript vám však umožní zjistit i to, co se stane, pokud pojedete rychleji nebo pomaleji: stačí jen změnit rychlost na třetím řádku a skript spustit znovu. Podobně můžete změnit i vzdálenost na druhém řádku a zjistit, jak dlouho pojedete do jiné destinace. (V kapitole Kapitola 7) se naučíte proces, který vám umožní snadno měnit parametry výpočtu jako jsou rychlost a vzdálenost ještě více automatizovat pomocí tvorby vlastních funkcí.)