Hlavní navigace

Programovací jazyk R: seznamy a datové rámce

22. 9. 2020
Doba čtení: 28 minut

Sdílet

 Autor: R Core Team
Posledními dvěma datovými typy, s nimiž se seznámíme, jsou seznamy a datové rámce. V praxi jsou důležité především datové rámce, které připomínají například databázové tabulky – jejich sloupce mohou mít různý typ.

Obsah

1. Programovací jazyk R: seznamy a datové rámce

2. Přístup k prvkům seznamů s využitím celočíselných indexů

3. Přístup k prvkům seznamů pomocí jejich jména

4. Spojení seznamů

5. Modifikace obsahu seznamů

6. Vytvoření nového seznamu ze sekvence

7. Vytvoření nového seznamu z vektoru

8. Vytvoření seznamu z jednodimenzionálního pole

9. Vytvoření seznamu z dvojdimenzionálního pole

10. Vytvoření seznamu z matice

11. Datové rámce – struktura používaná nejenom při statistických výpočtech

12. Konstrukce datového rámce

13. Hlídání délky vstupních dat

14. Neexistující hodnoty ve vstupních datech

15. Získání jmen sloupců a řádků datového rámce

16. Nastavení jmen sloupců a řádků

17. Přečtení prvních n či naopak posledních n řádků z datového rámce

18. Obsah následující části seriálu

19. Repositář s demonstračními příklady

20. Odkazy na Internetu

1. Programovací jazyk R: seznamy a datové rámce

Na popis datových typů programovacího jazyka R, jemuž jsme se věnovali v předchozích článcích, dnes navážeme a celé (relativně rozsáhlé) téma zakončíme. Nejprve si popíšeme seznamy (list) a posléze velmi důležitý datový typ nazvaný datový rámec (data frame). Nejprve začněme popisem seznamů. Seznamy mohou obsahovat sekvenci hodnot libovolných typů, což znamená, že se (na rozdíl od vektorů nebo matic) nejedná o homogenní datový typ. Do seznamů lze prvky přidávat či naopak odebírat. Prvky seznamu jsou přístupné buď přes jejich celočíselný index nebo pomocí jména, samozřejmě za předpokladu, že jsou prvky pojmenovány (takový seznam pak připomíná svým chováním spíše slovník, dokonce i tím, že si lze zvolit, jestli mají být prvky podle jména setříděny či nikoli).

Poznámka: jazyk R se vyvinul z programovacího jazyka S, mezi jehož předky patří mj. i Scheme. Proto lze v R pracovat i s takzvanou tečka dvojicí typickou pro prakticky všechny lispovské jazyky.

Pro vytvoření seznamu je možné použít několik konstruktorů, zejména konstruktor nazvaný list, dále převodní funkci pojmenovanou as.list atd. Všechny tyto funkce jsou pochopitelně popsány v nápovědě, o čemž se můžeme velmi snadno přesvědčit:

help(list)
 
list                   package:base                    R Documentation
 
Lists - Generic and Dotted Pairs
 
Description:
 
     Functions to construct, coerce and check for both kinds of R
     lists.
 
Usage:
 
     list(...)
     pairlist(...)
 
     as.list(x, ...)
     ## S3 method for class 'environment'
     as.list(x, all.names = FALSE, sorted = FALSE, ...)
     as.pairlist(x)
 
     is.list(x)
     is.pairlist(x)
 
     alist(...)
 
Arguments:
 
     ...: objects, possibly named.
 
       x: object to be coerced or tested.
 
all.names: a logical indicating whether to copy all values or (default)
          only those whose names do not begin with a dot.
 
  sorted: a logical indicating whether the ‘names’ of the resulting
          list should be sorted (increasingly).  Note that this is
          somewhat costly, but may be useful for comparison of
          environments.
Poznámka: tečka v názvu funkce nemá v tomto případě žádný zvláštní význam – jedná se o oddělovač stejně, jako bychom použili podtržítko v jiných programovacích jazycích.

Vyzkoušejme si nyní základní konstruktor seznamu představovaný funkcí list. Této funkci se předávají prvky seznamu, které jsou zařazeny v takovém pořadí, v jakém jsou zapsány:

lst <- list(1, 2, 3, 4)
print(lst)

Funkce print vytiskne jednotlivé prvky seznamu a před každým prvkem je uveden jeho selektor (v podstatě zápis indexu prvku):

[[1]]
[1] 1
 
[[2]]
[1] 2
 
[[3]]
[1] 3
 
[[4]]
[1] 4
Poznámka: jak je v R zvykem, jsou prvky seznamu považovány za jednoprvkové vektory.

Ukažme si, že seznam může obsahovat i řetězce:

lst <- list("foo", "bar", "baz")
print(lst)

Výsledek:

[[1]]
[1] "foo"
 
[[2]]
[1] "bar"
 
[[3]]
[1] "baz"

A konečně poslední seznam obsahuje pojmenované prvky, což znamená, že k prvkům lze přistupovat nejenom pomocí indexu, ale i jejich jména:

lst <- list(name="Fred", wife="Mary", no.children=3, child.ages=c(4,7,9))
print(lst)
Poznámka: povšimněte si, že prvky tohoto seznamu mají rozdílné typy hodnot.

Tisk celého seznamu:

$name
[1] "Fred"
 
$wife
[1] "Mary"
 
$no.children
[1] 3
 
$child.ages
[1] 4 7 9
Poznámka: povšimněte si, jak jsou prvky pojmenovány – před jménem se nachází znak dolaru. Toto využijeme později při přístupu k prvkům.

2. Přístup k prvkům seznamů s využitím celočíselných indexů

Přístup k prvkům seznamu (s využitím selektoru) může být zpočátku poněkud matoucí, protože se používají dva způsoby zápisu s rozdílným chováním. Nejprve vytvořme seznam pro otestování:

lst <- list("foo", "bar", "baz")

Dále se pokusme přistoupit k prvnímu prvku seznamu, a to tak, že index prvku zapíšeme do jednoduché hranaté závorky:

print(lst[1])

Výsledek bude následující:

[[1]]
[1] "foo"

Sice to tak nemusí vypadat, ale výsledkem předchozí selekce je jednoprvkový seznam, tedy nikoli samotný prvek:

print(class(lst[1]))
 
[1] "list"

Získání skutečné hodnoty prvního prvku musí vypadat nepatrně odlišně:

print(lst[[1]])

S výsledkem:

[1] "foo"

Který je typu:

print(class(lst[[1]]))
 
[1] "character"

Podobným způsobem lze získat i všechny prvky kromě prvního atd.:

print(lst[-1])
 
[[1]]
[1] "bar"
 
[[2]]
[1] "baz"

Výsledkem této operace je tedy nový seznam, s nímž je možné pracovat jako s jakýmkoli jiným seznamem:

lst <- list("foo", "bar", "baz")
 
print("lst[[-1]][1]")
print(lst[-1][1])

Po spuštění tohoto příkladu se zobrazí:

[1] "lst[[-1]][1]"
[[1]]
[1] "bar"
Poznámka: právě rozdíl mezi zápisy [index] a [[index]] může způsobit při práci se seznamy mnoho chyb.

3. Přístup k prvkům seznamů pomocí jejich jména

V úvodní kapitole jsme si řekli, že prvky seznamu mohou být pojmenovány, čímž se z klasických seznamů vytváří obdoba slovníků (dictionary). K těmto prvkům lze pochopitelně přistoupit právě i s použitím tohoto jména a dokonce jsou povoleny dva zápisy zvýrazněné v následujícím demonstračním příkladu:

lst <- list(name="Fred", wife="Mary", no.children=3, child.ages=c(4,7,9))
 
print(lst["name"])
print(lst[["name"]])
print(lst$name)

Podívejme se na výsledky získané po spuštění tohoto demonstračního příkladu:

$name
[1] "Fred"
 
[1] "Fred"
[1] "Fred"

Z vytištěných výsledků je patrné, že prvním zápisem jsme získali nový jednoprvkový seznam a druhé dva zápisy vedly k přečtení stejného prvku seznamu. Prostřední zápis použijeme tehdy, pokud je jméno prvku uloženo v nějaké proměnné, poslední zápis pak při „ručním“ přístupu k prvku, protože použití jména seznamu, dolaru a jména prvku se zapíše rychleji, než indexovací závorky a klíč v uvozovkách.

V případě, že je výsledkem výběru vektor či další seznam, lze indexování v této datové struktuře zapsat do vlastních hranatých závorek, tedy naprosto stejným způsobem, jako je tomu i v dalších programovacích jazycích:

lst <- list(name="Fred", wife="Mary", no.children=3, child.ages=c(4,7,9))
 
print(lst["child.ages"][1])
print(lst[["child.ages"]][2])
print(lst$child.ages[2])

Výsledky budou nyní vypadat následovně:

$child.ages
[1] 4 7 9
 
[1] 7
[1] 7
Poznámka: vidíme, že první výběr je proveden odlišně – snažíme se vybrat první prvek z datového typu „seznam“.

4. Spojení seznamů

Pro spojení seznamů použijeme nám již známou funkci nazvanou c, jejíž jednopísmenné označení vychází z názvu cons popř. v tomto případě přesněji concatenate popř. combine. V následujícím demonstračním příkladu jsou nejprve vytvořeny dva seznamy, které jsou následně spojeny funkcí c do seznamu jediného. Povšimněte si odlišných typů prvků i toho, že v prvním seznamu jsou prvky pojmenovány, kdežto ve druhém nikoli:

lst1 <- list(name="Fred", wife="Mary", no.children=3, child.ages=c(4,7,9))
lst2 <- list(1, 2, 3, 4)
 
lst <- c(lst1, lst2)
 
print(lst)

S výsledkem:

$name
[1] "Fred"
 
$wife
[1] "Mary"
 
$no.children
[1] 3
 
$child.ages
[1] 4 7 9
 
[[5]]
[1] 1
 
[[6]]
[1] 2
 
[[7]]
[1] 3
 
[[8]]
[1] 4

Pokus o spojení seznamů, které mají stejně pojmenované prvky:

lst1 <- list(name="Fred", wife="Mary", no.children=3, child.ages=c(4,7,9))
lst2 <- list(name="Mary", husband="Mary", no.children=3, child.ages=c(4,7,9))
 
lst <- c(lst1, lst2)
 
print(lst)

Ve výsledném seznamu se objeví prvky se stejným jménem (což je jeden z rozdílů oproti klasickým slovníkům):

$name
[1] "Fred"
 
$wife
[1] "Mary"
 
$no.children
[1] 3
 
$child.ages
[1] 4 7 9
 
$name
[1] "Mary"
 
$husband
[1] "Mary"
 
$no.children
[1] 3
 
$child.ages
[1] 4 7 9

5. Modifikace obsahu seznamů

Seznamy jsou měnitelné datové struktury, takže jejich prvky můžeme měnit, a to běžným přiřazením. Podívejme se na příklad:

lst1 <- list(name="Fred", wife="Mary", no.children=3, child.ages=c(4,7,9))
lst2 <- list(1, 2, 3, 4)
 
print(lst1)
print(lst2)
print("----------------------------")
 
lst1["name"] = "XXX"
print(lst1)
 
lst2[2] = 100
print(lst2)
Poznámka: namísto = můžete v tomto případě použít přiřazovací operátor ← (což je pro jazyk R více idiomatické):
lst1 <- list(name="Fred", wife="Mary", no.children=3, child.ages=c(4,7,9))
lst2 <- list(1, 2, 3, 4)
 
print(lst1)
print(lst2)
print("----------------------------")
 
lst1["name"] <- "XXX"
print(lst1)
 
lst2[2] <- 100
print(lst2)

Výsledky budou v obou případech totožné:

$name
[1] "Fred"
 
$wife
[1] "Mary"
 
$no.children
[1] 3
 
$child.ages
[1] 4 7 9
 
[[1]]
[1] 1
 
[[2]]
[1] 2
 
[[3]]
[1] 3
 
[[4]]
[1] 4
 
[1] "----------------------------"
$name
[1] "XXX"
 
$wife
[1] "Mary"
 
$no.children
[1] 3
 
$child.ages
[1] 4 7 9
 
[[1]]
[1] 1
 
[[2]]
[1] 100
 
[[3]]
[1] 3
 
[[4]]
[1] 4

6. Vytvoření nového seznamu ze sekvence

V předchozích kapitolách jsme si ukázali použití konstruktoru nazvaného list. Tomuto konstruktoru se předávají jednotlivé prvky seznamu, ovšem každá takto předaná hodnota je – nezávisle na svém obsahu – skutečně chápána jako jediný prvek, což může být matoucí. Příkladem může být pokus o vytvoření seznamu ze sekvence:

s <- seq(1, 10)
print(class(s))
 
lst <- list(s)
 
print(lst)
print(length(lst))
print(class(lst))

Výsledkem bude seznam obsahující jediný prvek, který je typu „vektor celých čísel“:

[1] "integer"
[[1]]
 [1]  1  2  3  4  5  6  7  8  9 10
 
[1] 1
[1] "list"

Pokud potřebujeme ze sekvence vytvořit seznam tak, aby se každý prvek sekvence vložil jako samostatný prvek do seznamu, musíme použít konverzi as.list:

s <- seq(1, 10)
print(class(s))
 
lst <- as.list(s)
 
print(lst)
print(length(lst))
print(class(lst))

Nyní je výsledkem seznam s deseti prvky (každý prvek je jednoprvkovým vektorem):

[1] "integer"
[[1]]
[1] 1
 
[[2]]
[1] 2
 
[[3]]
[1] 3
 
[[4]]
[1] 4
 
[[5]]
[1] 5
 
[[6]]
[1] 6
 
[[7]]
[1] 7
 
[[8]]
[1] 8
 
[[9]]
[1] 9
 
[[10]]
[1] 10
 
[1] 10
[1] "list"

7. Vytvoření nového seznamu z vektoru

Stejným způsobem můžeme vytvořit jednoprvkový seznam z tříprvkového vektoru:

v <- c("foo", "bar", "baz")
print(class(v))
 
lst <- list(v)
 
print(lst)
print(length(lst))
print(class(lst))

Výsledek:

[1] "character"
[[1]]
[1] "foo" "bar" "baz"
 
[1] 1
[1] "list"

Či naopak tříprvkový seznam z tříprvkového vektoru:

v <- c("foo", "bar", "baz")
print(class(v))
 
lst <- as.list(v)
 
print(lst)
print(length(lst))
print(class(lst))

Výsledek bude v tomto případě odlišný:

[1] "character"
[[1]]
[1] "foo"
 
[[2]]
[1] "bar"
 
[[3]]
[1] "baz"
 
[1] 3
[1] "list"
Poznámka: v naprosté většině případů požadujeme chování ukázané ve druhém demonstračním příkladu.

8. Vytvoření seznamu z jednodimenzionálního pole

Seznam je pochopitelně možné vytvořit i z pole, ale platí zde stejná pravidla, jaká jsme si uvedli u vektorů – pokud použijeme konstruktor list, kterému celé pole předáme, vznikne jednoprvkový seznam. Pro konverzi typu „prvek po prvku“ je nutné použít funkci as.list. Uveďme si nejdříve první příklad:

data <- c(1, 2, 3, 4, 5, 6)
dimension1 <- c(6)
 
a <- array(data, dim=dimension1)
 
print(class(a))
 
lst <- list(a)
 
print(lst)
print(length(lst))
print(class(lst))

Opět můžeme vidět, že se sice vytvoří seznam, který však bude obsahovat jediný prvek, který je typu pole:

[1] "array"
[[1]]
[1] 1 2 3 4 5 6
 
[1] 1
[1] "list"

Druhý demonstrační příklad ukazuje konverzi jednodimenzionálního pole na seznam s využitím funkce pojmenované as.list:

data <- c(1, 2, 3, 4, 5, 6)
dimension1 <- c(6)
 
a <- array(data, dim=dimension1)
 
print(class(a))
 
lst <- as.list(a)
 
print(lst)
print(length(lst))
print(class(lst))

Nyní je z pole vytvořen seznam se šesti prvky:

[1] "array"
 
 
[[1]]
[1] 1
 
[[2]]
[1] 2
 
[[3]]
[1] 3
 
[[4]]
[1] 4
 
[[5]]
[1] 5
 
[[6]]
[1] 6
 
[1] 6
[1] "list"

Při převodu se použijí jména sloupců, pokud jsou samozřejmě v poli deklarovány:

data <- 1:4
dimension <- c(4)
 
row.names <- c("row1", "row2", "row3", "row4")
 
a1 <- array(data, dim=dimension, dimnames=list(row.names))
print(a1)
 
lst <- as.list(a1)
 
print(lst)
print(length(lst))
print(class(lst))

Výsledek:

row1 row2 row3 row4
   1    2    3    4
 
 
 
$row1
[1] 1
 
$row2
[1] 2
 
$row3
[1] 3
 
$row4
[1] 4
 
[1] 4
[1] "list"
Poznámka: jedná se o velmi užitečné chování, protože jména sloupců jsou převedena na jména prvků, které ovšem můžeme či nemusíme použít (stále totiž existují celočíselné indexy prvků seznamu).

9. Vytvoření seznamu z dvojdimenzionálního pole

Seznam lze zkonstruovat i s využitím dvojdimenzinálního pole s prvky, které se mají do seznamu vložit. První příklad ukazuje použití konstruktoru list, který – jak již víme – vytvoří jednoprvkový seznam:

data <- c(1, 2, 3, 4, 5, 6)
dimension1 <- c(2, 3)
 
a <- array(data, dim=dimension1)
 
print(class(a))
 
lst <- list(a)
 
print(lst)
print(length(lst))
print(class(lst))

Výsledek ukazuje, že se skutečně vytvořil jednoprvkový seznam:

[1] "matrix"
 
 
[[1]]
     [,1] [,2] [,3]
[1,]    1    3    5
[2,]    2    4    6
 
[1] 1
[1] "list"

Dále, což bude zajímavější, se pokusíme o převod 2D pole na (jednodimenzionální) seznam:

data <- c(1, 2, 3, 4, 5, 6)
dimension1 <- c(2, 3)
 
a <- array(data, dim=dimension1)
 
print(class(a))
 
lst <- as.list(a)
 
print(lst)
print(length(lst))
print(class(lst))

Výsledek může být překvapující: seznam bude obsahovat šest prvků získaných z pole 2×3 prvky. To znamená, že pole bylo „nataženo“ do jedné dimenze:

[1] "matrix"
 
 
[[1]]
[1] 1
 
[[2]]
[1] 2
 
[[3]]
[1] 3
 
[[4]]
[1] 4
 
[[5]]
[1] 5
 
[[6]]
[1] 6
 
[1] 6
[1] "list"
Poznámka: ve skutečnosti je i pole interně reprezentováno jednodimenzionální strukturou, ke které jsou přiřazeny metainformace o dimenzi, tedy o tom, jak má být pole prezentováno uživatelům a jak má být realizováno indexování prvků.

10. Vytvoření seznamu z matice

Poslední typ datové konverze, kterou si v dnešním článku ukážeme, je konverze matice na seznam. Samozřejmě můžeme opět použít konstruktor list s tím, že výsledný seznam bude obsahovat jediný prvek, kterým bude celá matice. Můžeme se o tom velmi snadno přesvědčit:

data <- 1:12
 
m1 <- matrix(data, nrow=1, ncol=12)
print(m1)
print(class(m1))
 
lst <- list(m1)
 
print(lst)
print(length(lst))
print(class(lst))

Po spuštění tohoto demonstračního příkladu se nejdříve vypíše obsah původní matice a následně pak jednoprvkový seznam s touž maticí:

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,]    1    2    3    4    5    6    7    8    9    10    11    12
[1] "matrix"
 
 
[[1]]
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,]    1    2    3    4    5    6    7    8    9    10    11    12
 
[1] 1
[1] "list"

Nyní se podívejme na chování konverzní funkce as.list:

data <- 1:12
 
m1 <- matrix(data, nrow=1, ncol=12)
print(m1)
print(class(m1))
 
lst <- as.list(m1)
 
print(lst)
print(length(lst))
print(class(lst))

Výsledkem bude v tomto případě seznam s dvanácti prvky (typu jednoprvkový vektor):

     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,]    1    2    3    4    5    6    7    8    9    10    11    12
[1] "matrix"
 
 
[[1]]
[1] 1
 
[[2]]
[1] 2
 
[[3]]
[1] 3
 
[[4]]
[1] 4
 
[[5]]
[1] 5
 
[[6]]
[1] 6
 
[[7]]
[1] 7
 
[[8]]
[1] 8
 
[[9]]
[1] 9
 
[[10]]
[1] 10
 
[[11]]
[1] 11
 
[[12]]
[1] 12
 
[1] 12
[1] "list"

Stejný výsledek ovšem dostaneme, i když budeme převádět matici s odlišným počtem řádků a sloupců – vždy se provede převod na lineární seznam:

data <- 1:12
 
m1 <- matrix(data, nrow=4, ncol=3)
print(m1)
print(class(m1))
 
lst <- as.list(m1)
 
print(lst)
print(length(lst))
print(class(lst))

Výsledek bude v tomto případě shodný s předchozím demonstračním příkladem:

     [,1] [,2] [,3]
[1,]    1    5    9
[2,]    2    6   10
[3,]    3    7   11
[4,]    4    8   12
[1] "matrix"
 
 
 
[[1]]
[1] 1
 
[[2]]
[1] 2
 
[[3]]
[1] 3
 
[[4]]
[1] 4
 
[[5]]
[1] 5
 
[[6]]
[1] 6
 
[[7]]
[1] 7
 
[[8]]
[1] 8
 
[[9]]
[1] 9
 
[[10]]
[1] 10
 
[[11]]
[1] 11
 
[[12]]
[1] 12
 
[1] 12
 
[1] "list"

11. Datové rámce – struktura používaná nejenom při statistických výpočtech

Ve druhé části dnešního článku si popíšeme základy práce s takzvanými datovými rámci (data frame). Jedná se o velmi důležitý datový typ používaný zejména (ale nejenom) při statistických výpočtech. Datové rámce se v určitém ohledu podobají tabulkám používaným v relačních databázích: jednotlivé sloupce jsou pojmenované a současně může být každý sloupec jiného datového typu (všechny prvky ve sloupci toto kritérium musí splňovat). Tato vlastnost odlišuje datové rámce jak od dvojdimenzionálních polí, tak i od matic. S datovými rámci se ovšem nepracuje pouze v jazyku R; nalezneme je například i v knihovně Pandas určenou pro programovací jazyk Python. Datové rámce a operace s nimi jsou pochopitelně popsány v dokumentaci programovacího jazyka R. Příkladem může být dokumentace ke konstruktoru datových rámců:

help(data.frame)
 
data.frame                package:base                 R Documentation
 
Data Frames
 
Description:
 
     The function ‘data.frame()’ creates data frames, tightly coupled
     collections of variables which share many of the properties of
     matrices and of lists, used as the fundamental data structure by
     most of R's modeling software.
 
Usage:
 
     data.frame(..., row.names = NULL, check.rows = FALSE,
                check.names = TRUE, fix.empty.names = TRUE,
                stringsAsFactors = default.stringsAsFactors())
 
     default.stringsAsFactors()

Datové rámce většinou nevznikají přímo z dat dostupných ve zdrojovém kódu, ale jsou načítány ze souborů. Uloženy mohou být v relativně velmi jednoduchém textovém formátu, ovšem lze použít i známý formát CSV apod. Podrobnostmi se budeme zabývat příště, ovšem příslušné funkce jsou pochopitelně popsány v nápovědě:

help(read.csv)
 
read.table                package:utils                R Documentation
 
Data Input
 
Description:
 
     Reads a file in table format and creates a data frame from it,
     with cases corresponding to lines and variables to fields in the
     file.
 
Usage:
 
     read.table(file, header = FALSE, sep = "", quote = "\"'",
                dec = ".", numerals = c("allow.loss", "warn.loss", "no.loss"),
                row.names, col.names, as.is = !stringsAsFactors,
                na.strings = "NA", colClasses = NA, nrows = -1,
                skip = 0, check.names = TRUE, fill = !blank.lines.skip,
                strip.white = FALSE, blank.lines.skip = TRUE,
                comment.char = "#",
                allowEscapes = FALSE, flush = FALSE,
                stringsAsFactors = default.stringsAsFactors(),
                fileEncoding = "", encoding = "unknown", text, skipNul = FALSE)
 
     read.csv(file, header = TRUE, sep = ",", quote = "\"",
              dec = ".", fill = TRUE, comment.char = "", ...)
 
     read.csv2(file, header = TRUE, sep = ";", quote = "\"",
               dec = ",", fill = TRUE, comment.char = "", ...)
 
     read.delim(file, header = TRUE, sep = "\t", quote = "\"",
                dec = ".", fill = TRUE, comment.char = "", ...)
 
     read.delim2(file, header = TRUE, sep = "\t", quote = "\"",
                 dec = ",", fill = TRUE, comment.char = "", ...)

Dnes si popíšeme pouze několik základních operací s datovými rámci; důležitější funkce budou popsány příště, samozřejmě společně s ukázkou, jakým způsobem lze datové rámce použít při tvorbě grafů (resp. naopak – jak může datový rámec sloužit jako zdroj dat pro grafy).

12. Konstrukce datového rámce

Již v předchozí kapitole jsme si naznačili, že konstruktorem datového rámce je funkce pojmenovaná dat.frame. Této funkci se předají data představující jednotlivé sloupce, společně s názvy sloupců. Data si tedy nejdříve připravíme, a to buď ve formě vektorů nebo seznamů. Zdrojem dat bude prvních devět položek ze známého (a možná i trochu přeceňovaného) Tiobe indexu (samotný jazyk R se přitom umístil na velmi pěkném devátém místě, což je pro DSL takřka neuvěřitelně dobrá pozice):

ids = c(1:9)
names = c("C", "Java", "Python", "C++", "C#", "Visual Basic", "JavaScript", "PHP", "R")
usages = c(15.95, 13.48, 10.47, 7.11, 4.58, 4.12, 2.54, 2.49, 2.37)
changes = c(0.74, -3.18, 0.59, 1.48, 1.18, 0.83, 0.41, 0.62, 1.33)
Poznámka: povšimněte si, že všechny vektory mají stejnou délku:
print(length(ids))
print(length(names))
print(length(usages))
print(length(changes))

S totožnými výsledky:

[1] 9
[1] 9
[1] 9
[1] 9

Datový rámec vytvoříme již zmíněným konstruktorem data.frame:

languages <- data.frame(
    ids,
    names,
    usages,
    changes
)
 
print(languages)

Obsah datového rámce:

  ids        names usages changes
1   1            C  15.95    0.74
2   2         Java  13.48   -3.18
3   3       Python  10.47    0.59
4   4          C++   7.11    1.48
5   5           C#   4.58    1.18
6   6 Visual Basic   4.12    0.83
7   7   JavaScript   2.54    0.41
8   8          PHP   2.49    0.62
9   9            R   2.37    1.33

Máme ovšem možnost si sloupce pojmenovat s využitím následující syntaxe:

languages <- data.frame(
    id = ids,
    name = names,
    usage = usages,
    change = changes
)
 
print(languages)

Nyní mají sloupce odlišné názvy:

  id         name usage change
1  1            C 15.95   0.74
2  2         Java 13.48  -3.18
3  3       Python 10.47   0.59
4  4          C++  7.11   1.48
5  5           C#  4.58   1.18
6  6 Visual Basic  4.12   0.83
7  7   JavaScript  2.54   0.41
8  8          PHP  2.49   0.62
9  9            R  2.37   1.33

Samozřejmě nám nic nebrání ve vytvoření datového rámce přímo s deklarací dat uvnitř volání konstruktoru:

languages <- data.frame(
    id = c(1:9),
    name = c("C", "Java", "Python", "C++", "C#", "Visual Basic", "JavaScript", "PHP", "R"),
    usage = c(15.95, 13.48, 10.47, 7.11, 4.58, 4.12, 2.54, 2.49, 2.37),
    change = c(0.74, -3.18, 0.59, 1.48, 1.18, 0.83, 0.41, 0.62, 1.33)
)
 
print(languages)

S výsledky:

  id         name usage change
1  1            C 15.95   0.74
2  2         Java 13.48  -3.18
3  3       Python 10.47   0.59
4  4          C++  7.11   1.48
5  5           C#  4.58   1.18
6  6 Visual Basic  4.12   0.83
7  7   JavaScript  2.54   0.41
8  8          PHP  2.49   0.62
9  9            R  2.37   1.33

13. Hlídání délky vstupních dat

Datový rámec tvoří de facto tabulku, což znamená, že vektory představující vstupní data by měly mít totožnou délku. Ve skutečnosti je tato vlastnost hlídána samotným konstruktorem, o čemž se můžeme přesvědčit při jeho zavolání s vektory různé délky:

languages <- data.frame(
    id = c(1:20),
    name = c("C", "Java", "Python", "C++", "C#", "Visual Basic", "JavaScript", "PHP", "R"),
    usage = c(15.95, 13.48, 10.47, 7.11, 4.58, 4.12, 2.54),
    change = c(0.74, -3.18, 0.59, 1.48, 1.18, 0.83)
)
 
print(languages)

Skutečnost, že vektory mají odlišnou délku, je detekována a vypíše se následující chybové hlášení:

Error in data.frame(id = c(1:20), name = c("C", "Java", "Python", "C++",  :
  arguments imply differing number of rows: 20, 9, 7, 6
Execution halted
Poznámka: to znamená, že datový rámec není vytvořen.

14. Neexistující hodnoty ve vstupních datech

Viděli jsme, že není možné vytvořit datový rámec z vektorů různé délky (což je ostatně logické). Ovšem mnoho vstupních dat neobsahuje vyplněné všechny položky (což v praxi můžeme vidět například zde) a jazyk R i s takovými daty musí nějakým způsobem pracovat. Neexistující (přesněji řečeno nedostupné) položky mohou být nahrazeny speciální hodnotou s identifikátorem NA, která je (velmi zjednodušeně řečeno) „beztypová“. Použití neexistujících položek si můžeme ukázat na nám již známých datech, v nichž některé původně známé položky nahradíme za NA:

ids = c(1:9)
names = c("C", "Java", "Python", "C++", "C#", "Visual Basic", NA, "PHP", "R")
usages = c(15.95, 13.48, 10.47, 7.11, 4.58, 4.12, NA, 2.49, 2.37)
changes = c(0.74, NA, 0.59, 1.48, 1.18, 0.83, 0.41, NA, 1.33)

Tato neúplná data jsou plně postačující pro vytvoření datového rámce:

languages <- data.frame(
   id = ids,
   name = names,
   usage = usages,
   change = changes
)
 
print(languages)

Výsledná tabulka bude vypadat následovně:

  id         name usage change
1  1            C 15.95   0.74
2  2         Java 13.48     NA
3  3       Python 10.47   0.59
4  4          C++  7.11   1.48
5  5           C#  4.58   1.18
6  6 Visual Basic  4.12   0.83
7  7         <NA>    NA   0.41
8  8          PHP  2.49     NA
9  9            R  2.37   1.33
Poznámka: povšimněte si, že nedostupná hodnota ve sloupci řetězců je zobrazena odlišně od nedostupné hodnoty v numerickém sloupci.

Tato hodnota se však chová jinak než například None z Pythonu, protože je ji například možné použít v aritmetických výrazech NA+3 atd. Blíže viz:

help(NA)
 
NA                    package:base                     R Documentation
 
'Not Available' / Missing Values
 
Description:
 
     ‘NA’ is a logical constant of length 1 which contains a missing
     value indicator.  ‘NA’ can be coerced to any other vector type
     except raw.  There are also constants ‘NA_integer_’, ‘NA_real_’,
     ‘NA_complex_’ and ‘NA_character_’ of the other atomic vector types
     which support missing values: all of these are reserved words in
     the R language.
 
     The generic function ‘is.na’ indicates which elements are missing.
 
     The generic function ‘is.na<-’ sets elements to ‘NA’.
 
     The generic function ‘anyNA’ implements ‘any(is.na(x))’ in a
     possibly faster way (especially for atomic vectors).
 
     ...
     ...
     ...

15. Získání jmen sloupců a řádků datového rámce

V této kapitole si ukážeme použití funkcí names(), colnames() a rownames(). Nejdříve si připravíme testovací data, která již velmi dobře známe:

languages <- data.frame(
   id = c(1:9),
   name = c("C", "Java", "Python", "C++", "C#", "Visual Basic", "JavaScript", "PHP", "R"),
   usage = c(15.95, 13.48, 10.47, 7.11, 4.58, 4.12, 2.54, 2.49, 2.37),
   change = c(0.74, -3.18, 0.59, 1.48, 1.18, 0.83, 0.41, 0.62, 1.33)
)

Nyní si můžeme nechat vypsat názvy sloupců resp. i ostatních názvů přiřazených do datového rámce:

print(names(languages))

S výsledkem:

[1] "id"     "name"   "usage"  "change"

Specifičtější je dotaz přímo na jména sloupců, a to funkcí pojmenovanou colnames:

print(colnames(languages))

S výsledkem:

[1] "id"     "name"   "usage"  "change"

Dotázat se můžeme i na názvy řádků, které budou v našem případě numerické:

print(rownames(languages))

Výsledkem je devítiprvkový vektor:

[1] "1" "2" "3" "4" "5" "6" "7" "8" "9"

16. Nastavení jmen sloupců a řádků

S využitím funkce colnames, s níž jsme se v krátkosti seznámili v předchozí kapitole, lze jména sloupců změnit (nastavit). Podívejme se na následující příklad, kde se výsledek funkce colnames nachází na levé straně přiřazovacího výrazu:

languages <- data.frame(
   id = c(1:9),
   name = c("C", "Java", "Python", "C++", "C#", "Visual Basic", "JavaScript", "PHP", "R"),
   usage = c(15.95, 13.48, 10.47, 7.11, 4.58, 4.12, 2.54, 2.49, 2.37),
   change = c(0.74, -3.18, 0.59, 1.48, 1.18, 0.83, 0.41, 0.62, 1.33)
)
 
print(languages)
 
colnames(languages) <- c("ID", "Language", "Usage 2020", "Change")
 
print("---------------------------------------")
 
print(languages)

Po spuštění tohoto příkladu se nejdříve zobrazí původní datový rámec a posléze datový rámec s totožnými daty, ovšem s přejmenovanými sloupci:

  id         name usage change
1  1            C 15.95   0.74
2  2         Java 13.48  -3.18
3  3       Python 10.47   0.59
4  4          C++  7.11   1.48
5  5           C#  4.58   1.18
6  6 Visual Basic  4.12   0.83
7  7   JavaScript  2.54   0.41
8  8          PHP  2.49   0.62
9  9            R  2.37   1.33
 
[1] "---------------------------------------"
 
  ID     Language Usage 2020 Change
1  1            C      15.95   0.74
2  2         Java      13.48  -3.18
3  3       Python      10.47   0.59
4  4          C++       7.11   1.48
5  5           C#       4.58   1.18
6  6 Visual Basic       4.12   0.83
7  7   JavaScript       2.54   0.41
8  8          PHP       2.49   0.62
9  9            R       2.37   1.33

Podobně lze přiřazením měnit i jména řádků datového rámce. V dalším demonstračním příkladu je přečíslujeme od devíti do jedné:

languages <- data.frame(
   id = c(1:9),
   name = c("C", "Java", "Python", "C++", "C#", "Visual Basic", "JavaScript", "PHP", "R"),
   usage = c(15.95, 13.48, 10.47, 7.11, 4.58, 4.12, 2.54, 2.49, 2.37),
   change = c(0.74, -3.18, 0.59, 1.48, 1.18, 0.83, 0.41, 0.62, 1.33)
)
 
print(languages)
 
rownames(languages) <- seq(9,1)
 
print("---------------------------------------")
 
print(languages)

S výsledky (původní datový rámec a rámec s přečíslovanými řádky):

  id         name usage change
1  1            C 15.95   0.74
2  2         Java 13.48  -3.18
3  3       Python 10.47   0.59
4  4          C++  7.11   1.48
5  5           C#  4.58   1.18
6  6 Visual Basic  4.12   0.83
7  7   JavaScript  2.54   0.41
8  8          PHP  2.49   0.62
9  9            R  2.37   1.33
 
[1] "---------------------------------------"
 
  id         name usage change
9  1            C 15.95   0.74
8  2         Java 13.48  -3.18
7  3       Python 10.47   0.59
6  4          C++  7.11   1.48
5  5           C#  4.58   1.18
4  6 Visual Basic  4.12   0.83
3  7   JavaScript  2.54   0.41
2  8          PHP  2.49   0.62
1  9            R  2.37   1.33

17. Přečtení prvních n či naopak posledních n řádků z datového rámce

Posledními dvěma funkcemi, s nimiž se dnes alespoň ve stručnosti seznámíme, jsou funkce pojmenované head a tail. Tyto funkce přečtou a vrátí začátek popř. konec datového rámce. Podobně jako stejně pojmenované unixové příkazy se implicitně zobrazí prvních deset řádků resp. posledních deset řádků, ovšem naše testovací data obsahují méně řádků, takže použijeme přídavný parametr určující, kolik prvních/posledních řádků se má získat. Nejprve zobrazíme prvních pět řádků datového rámce:

languages <- data.frame(
   id = c(1:9),
   name = c("C", "Java", "Python", "C++", "C#", "Visual Basic", "JavaScript", "PHP", "R"),
   usage = c(15.95, 13.48, 10.47, 7.11, 4.58, 4.12, 2.54, 2.49, 2.37),
   change = c(0.74, -3.18, 0.59, 1.48, 1.18, 0.83, 0.41, 0.62, 1.33)
)
 
print(head(languages, 5))

S výsledkem:

  id   name usage change
1  1      C 15.95   0.74
2  2   Java 13.48  -3.18
3  3 Python 10.47   0.59
4  4    C++  7.11   1.48
5  5     C#  4.58   1.18
Poznámka: funkce head vrátí nový datový rámec, o čemž se lze snadno přesvědčit:
print(class(head(languages, 5)))

Toto volání vrátí:

[1] "data.frame"

Podobným způsobem pracuje funkce tail, která ovšem pro změnu získá a vrátí posledních n řádků datového rámce (implicitně deset řádků):

languages <- data.frame(
   id = c(1:9),
   name = c("C", "Java", "Python", "C++", "C#", "Visual Basic", "JavaScript", "PHP", "R"),
   usage = c(15.95, 13.48, 10.47, 7.11, 4.58, 4.12, 2.54, 2.49, 2.37),
   change = c(0.74, -3.18, 0.59, 1.48, 1.18, 0.83, 0.41, 0.62, 1.33)
)
 
print(tail(languages, 5))

S výsledky:

  id         name usage change
5  5           C#  4.58   1.18
6  6 Visual Basic  4.12   0.83
7  7   JavaScript  2.54   0.41
8  8          PHP  2.49   0.62
9  9            R  2.37   1.33
Poznámka: jedná se o potenciálně velmi užitečné funkce umožňující rychle zjistit, zda pracujeme se správnými daty.

18. Obsah následující části seriálu

V navazující části seriálu o programovacím jazyku R nejprve dokončíme popis práce s datovými rámci (k dispozici je totiž velké množství zajímavých operací) a posléze si ukážeme, jak je možné (nejenom) datové rámce použít pro tvorbu různých typů grafů, protože právě práce s grafy je v programovacím jazyku R poměrně elegantní.

Příklad výpisu analýzy datového rámce popsané v navazujícím článku:

Root Docker

languages <- data.frame(
   id = c(1:9),
   name = c("C", "Java", "Python", "C++", "C#", "Visual Basic", "JavaScript", "PHP", "R"),
   usage = c(15.95, 13.48, 10.47, 7.11, 4.58, 4.12, 2.54, 2.49, 2.37),
   change = c(0.74, -3.18, 0.59, 1.48, 1.18, 0.83, 0.41, 0.62, 1.33)
)
 
print(str(languages))

S výsledkem:

'data.frame':   9 obs. of  4 variables:
 $ id    : int  1 2 3 4 5 6 7 8 9
 $ name  : Factor w/ 9 levels "C","C#","C++",..: 1 4 7 3 2 9 5 6 8
 $ usage : num  15.95 13.48 10.47 7.11 4.58 ...
 $ change: num  0.74 -3.18 0.59 1.48 1.18 0.83 0.41 0.62 1.33
NULL

19. Repositář s demonstračními příklady

Zdrojové kódy všech dnes použitých demonstračních příkladů byly uloženy do nového Git repositáře, který je dostupný na adrese https://github.com/tisnik/r-examples V případě, že z nějakého důvodu nebudete chtít klonovat celý repositář (ten je ovšem – alespoň prozatím – velmi malý, dnes má stále jen jednotky, maximálně desítky kilobajtů), můžete namísto toho použít odkazy na jednotlivé demonstrační příklady, které naleznete v následující tabulce:

# Příklad Stručný popis Cesta
1 01-list-constructor.R vytvoření seznamu s vektory celých čísel https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/01-list-constructor.R
2 02-list-constructor.R vytvoření seznamu s řetězci https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/02-list-constructor.R
3 03-list-constructor.R vytvoření seznamu s pojmenovanými prvky https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/03-list-constructor.R
4 04-indexing.R získání podseznamu ze seznamu https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/04-indexing.R
5 05-index-of-index.R získání konkrétního prvku ze seznamu https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/05-index-of-index.R
6 06-select-by-name-R přístup k prvkům seznamu s využitím jejich jména https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/06-select-by-name-R
7 07-select-by-name-and-index.R přístup k prvkům seznamu s využitím jejich jména, opakované indexování https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/07-select-by-name-and-index.R
8 08-indexing-problems.R možné problémy při indexování prvků v seznamu https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/08-indexing-problems.R
9 09-concatenate.R spojení dvou seznamů https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/09-concatenate.R
10 10-list-modify.R modifikace prvků seznamu https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/10-list-modify.R
11 11-from-seq.R vytvoření jednoprvkového seznamu ze sekvence https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/11-from-seq.R
12 12-from-seq.R vytvoření víceprvkového seznamu ze sekvence https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/12-from-seq.R
13 13-from-vector.R vytvoření jednoprvkového seznamu z vektoru https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/13-from-vector.R
14 14-from-vector.R vytvoření víceprvkového seznamu z vektoru https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/14-from-vector.R
15 15-from-1D-array.R vytvoření jednoprvkového seznamu z 1D pole https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/15-from-1D-array.R
16 16-from-1D-array.R vytvoření víceprvkového seznamu z 1D pole https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/16-from-1D-array.R
17 17-from-2D-array.R vytvoření jednoprvkového seznamu z 2D pole https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/17-from-2D-array.R
18 18-from-2D-array.R vytvoření víceprvkového seznamu z 2D pole https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/18-from-2D-array.R
19 19-from-matrix.R vytvoření jednoprvkového seznamu z matice https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/19-from-matrix.R
20 20-from-matrix.R vytvoření víceprvkového seznamu z matice https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/20-from-matrix.R
       
21 21-data-frame-constructor.R konstrukce datového rámce https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/21-data-frame-constructor.R
22 22-data-frame-constructor.R zkrácená konstrukce datového rámce https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/22-data-frame-constructor.R
23 23-data-frame-constructor-diff-length.R různé délky vstupních vektorů https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/23-data-frame-constructor-diff-length.R
24 24-data-frame-constructor-NA.R použití hodnot NA při konstrukci datového rámce https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/24-data-frame-constructor-NA.R
25 25-data-frame-names.R datové rámce a funkce names() https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/25-data-frame-names.R
26 26-data-frame-colnames.R datové rámce a funkce colnames() https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/26-data-frame-colnames.R
27 27-data-frame-rownames.R datové rámce a funkce rownames() https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/27-data-frame-rownames.R
28 28-data-frame-set-colnames.R nastavení jmen sloupců datového rámce https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/28-data-frame-set-colnames.R
29 29-data-frame-set-rownames.R nastavení jmen řádků datového rámce https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/29-data-frame-set-rownames.R
30 30-data-frame-head.R datové rámce a funkce head() https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/30-data-frame-head.R
31 31-data-frame-tail.R datové rámce a funkce tail() https://github.com/tisnik/r-examples/blob/master/05-lists-and-data-frames/31-data-frame-tail.R

20. Odkazy na Internetu

  1. The R Project for Statistical Computing
    https://www.r-project.org/
  2. An Introduction to R
    https://cran.r-project.org/doc/manuals/r-release/R-intro.pdf
  3. R (programming language)
    https://en.wikipedia.org/wi­ki/R_(programming_language)
  4. The R Programming Language
    https://www.tiobe.com/tiobe-index/r/
  5. R Markdown
    https://rmarkdown.rstudio.com/
  6. R Markdown: The Definitive Guide
    https://bookdown.org/yihui/rmarkdown/
  7. R Markdown Cheat Sheet
    https://rstudio.com/wp-content/uploads/2016/03/rmarkdown-cheatsheet-2.0.pdf
  8. Introduction to R Markdown
    https://rmarkdown.rstudio­.com/articles_intro.html
  9. R Cheat Sheets
    https://blog.sergiouri.be/2016/07/r-cheat-sheets.html
  10. R Cheat Sheet
    https://s3.amazonaws.com/quandl-static-content/Documents/Quandl±+R+Che­at+Sheet.pdf
  11. Base R Cheat Sheet
    https://rstudio.com/wp-content/uploads/2016/06/r-cheat-sheet.pdf
  12. PYPL PopularitY of Programming Language
    https://pypl.github.io/PYPL.html
  13. Tiobe index
    https://www.tiobe.com/tiobe-index/
  14. Stack Overflow: Most Loved, Dreaded & Wanted Programming Languages In 2020
    https://fossbytes.com/stack-overflow-most-loved-dreaded-wanted-programming-languages-in-2020/
  15. How to Install and Use R on Ubuntu
    https://itsfoss.com/install-r-ubuntu/
  16. R programming for beginners – Why you should use R
    https://www.youtube.com/wat­ch?v=9kYUGMg_14s
  17. GOTO 2012 • The R Language The Good The Bad & The Ugly
    https://www.youtube.com/wat­ch?v=6S9r_YbqHy8
  18. R vs Python – What should I learn in 2020? | R and Python Comparison
    https://www.youtube.com/wat­ch?v=eRP_J2yLjSU
  19. R Programming 101
    https://www.youtube.com/c/rpro­gramming101
  20. Seriál Tvorba grafů pomocí programu „R“
    https://www.root.cz/serialy/tvorba-grafu-pomoci-programu-r/
  21. Tvorba grafů pomocí programu „R“: úvod
    https://www.root.cz/clanky/tvorba-grafu-pomoci-programu-r-1/
  22. Tvorba grafů pomocí programu „R“: pokročilé funkce
    https://www.root.cz/clanky/tvorba-grafu-pomoci-programu-r-pokrocile-funkce/
  23. Tvorba grafů pomocí programu „R“: vkládání textu, čeština
    https://www.root.cz/clanky/grafy-pomoci-programu-r-vkladani-textu-cestina/
  24. Cesta erka: Krok nultý – instalace & nastavení – prostředí, projekty, package
    https://www.jla-data.net/r4su/r4su-environment-setup/
  25. Cesta erka: Krok první – operace a struktury – proměnné, rovnítka a dolary
    https://www.jla-data.net/r4su/r4su-data-structures/
  26. Cesta erka: Krok druhý – načtení externích dat – csvčka, excely a databáze
    https://www.jla-data.net/r4su/r4su-read-data/
  27. Cesta erka: Krok třetí – manipulace s daty – dplyr, slovesa a pajpy
    https://www.jla-data.net/r4su/r4su-manipulate-data/
  28. Cesta erka: Krok čtvrtý – podání výsledků – ggplot, geomy a estetiky
    https://www.jla-data.net/r4su/r4su-report-results/
  29. Cesta erka: Krok pátý – case study – případ piva v Praze
    https://www.jla-data.net/r4su/r4su-case-study-beer/
  30. V indexu popularity programovacích jazyků TIOBE překvapilo R, Go, Perl, Scratch a Rust
    https://www.root.cz/zpravicky/v-indexu-popularity-programovacich-jazyku-tiobe-prekvapilo-r-go-perl-scratch-a-rust/
  31. Is R Programming SURGING in Popularity in 2020?
    https://www.youtube.com/watch?v=Duwn-vImyXE
  32. Using the R programming language in Jupyter Notebook
    https://docs.anaconda.com/a­naconda/navigator/tutorial­s/r-lang/
  33. Using R on Jupyter Notebook
    https://dzone.com/articles/using-r-on-jupyternbspnotebook
  34. Graphics, ggplot2
    http://r4stats.com/examples/graphics-ggplot2/
  35. A Practice Data Set
    https://r4stats.wordpress­.com/examples/mydata/
  36. Shiny – galerie projektů
    https://shiny.rstudio.com/gallery/
  37. Seriál Programovací jazyk Julia
    https://www.root.cz/seria­ly/programovaci-jazyk-julia/
  38. Julia (front page)
    http://julialang.org/
  39. Julia – repositář na GitHubu
    https://github.com/JuliaLang/julia
  40. Julia (programming language)
    https://en.wikipedia.org/wi­ki/Julia_%28programming_lan­guage%29
  41. IJulia
    https://github.com/JuliaLan­g/IJulia.jl
  42. Introducing Julia
    https://en.wikibooks.org/wi­ki/Introducing_Julia
  43. Julia: the REPL
    https://en.wikibooks.org/wi­ki/Introducing_Julia/The_REPL
  44. Introducing Julia/Metaprogramming
    https://en.wikibooks.org/wi­ki/Introducing_Julia/Meta­programming
  45. Month of Julia
    https://github.com/DataWo­okie/MonthOfJulia
  46. Learn X in Y minutes (where X=Julia)
    https://learnxinyminutes.com/doc­s/julia/
  47. New Julia language seeks to be the C for scientists
    http://www.infoworld.com/ar­ticle/2616709/application-development/new-julia-language-seeks-to-be-the-c-for-scientists.html
  48. Julia: A Fast Dynamic Language for Technical Computing
    http://karpinski.org/publi­cations/2012/julia-a-fast-dynamic-language
  49. The LLVM Compiler Infrastructure
    http://llvm.org/
  50. Julia: benchmarks
    http://julialang.org/benchmarks/
  51. R Vector
    https://www.datamentor.io/r-programming/vector/
  52. .R File Extension
    https://fileinfo.com/extension/r
  53. Lineární regrese
    https://cs.wikipedia.org/wi­ki/Line%C3%A1rn%C3%AD_regre­se
  54. lm (funkce)
    https://www.rdocumentation­.org/packages/stats/versi­ons/3.6.2/topics/lm
  55. quit (funkce)
    https://www.rdocumentation­.org/packages/base/version­s/3.6.2/topics/quit
  56. c (funkce)
    https://www.rdocumentation­.org/packages/base/version­s/3.6.2/topics/c
  57. help (funkce)
    https://www.rdocumentation­.org/packages/utils/versi­ons/3.6.2/topics/help
  58. Shiny: Introduction to interactive documents
    https://shiny.rstudio.com/ar­ticles/interactive-docs.html
  59. R Release History 1997–2013
    http://timelyportfolio.git­hub.io/rCharts_timeline_r/
  60. R: atomic vectors
    https://renenyffenegger.ch/no­tes/development/languages/R/da­ta-structures/vector/
  61. 11 Best R Programming IDE and editors
    https://www.dunebook.com/best-r-programming-ide/
  62. CRAN – The Comprehensive R Archive Network
    https://cran.r-project.org/
  63. R – Arrays
    https://www.tutorialspoin­t.com/r/r_arrays.htm
  64. Array vs Matrix in R Programming
    https://www.geeksforgeeks.org/array-vs-matrix-in-r-programming/?ref=rp
  65. Online R Language IDE
    https://www.jdoodle.com/execute-r-online/
  66. Execute R Online (R v3.4.1)
    https://www.tutorialspoin­t.com/execute_r_online.php
  67. Snippets: Run any R code you like. There are over twelve thousand R packages preloaded
    https://rdrr.io/snippets/
  68. R Package Documentation
    https://rdrr.io/
  69. Data Reshaping in R – Popular Functions to Organise Data
    https://techvidvan.com/tutorials/data-reshaping-in-r/
  70. What is an R Data Frame?
    https://magoosh.com/data-science/what-is-an-r-data-frame/
  71. What's a data frame?
    https://campus.datacamp.com/cou­rses/free-introduction-to-r/chapter-5-data-frames?ex=1
  72. data.frame
    https://www.rdocumentation­.org/packages/base/version­s/3.6.2/topics/data.frame
  73. as.data.frame
    https://www.rdocumentation­.org/packages/base/version­s/3.6.2/topics/as.data.fra­me
  74. table
    https://www.rdocumentation­.org/packages/base/version­s/3.6.2/topics/table
  75. Python Pandas – DataFrame
    https://www.tutorialspoin­t.com/python_pandas/python_pan­das_dataframe.htm
  76. The Pandas DataFrame: Make Working With Data Delightful
    https://realpython.com/pandas-dataframe/
  77. Python | Pandas DataFrame
    https://www.geeksforgeeks.org/python-pandas-dataframe/

Autor článku

Pavel Tišnovský vystudoval VUT FIT a v současné době pracuje ve společnosti Red Hat, kde vyvíjí nástroje pro OpenShift.io.