4.2 Tabulární textové soubory

Základní způsob výměny dat jsou textové tabulární formáty, kde jednotlivé řádky odpovídají pozorováním a kde jsou sloupce (proměnné) odděleny nějakým oddělovačem, např. mezerou, čárkou, středníkem nebo dvojtečkou. Velká výhoda těchto formátů je, že je možné je načíst téměř do každého software, který pracuje s daty a stejně tak je z něj i vypsat. Zároveň jsou data “čitelná lidmi” a pokud se něco pokazí, je často možné data nějak zachránit. Nevýhodou je, že tyto formáty mohou obsahovat pouze tabulární data (tabulky), nemohou obsahovat metadata (např. atributy), jejich načítání může trvat dlouho (pokud jsou data velká) a že data v těchto formátech nejsou komprimovaná, takže na disku zabírají hodně místa (to je však relativní, viz dále).

4.2.1 Načítání dat

K načítání dat v textových tabulárních formátech slouží v R funkce read.table(), která vrací datovou struktur data.frame. Tato funkce má velké množství parametrů (přečtěte si dokumentaci!). Mezi základní parametry těchto funkcí patří:

  • file = jméno souboru nebo spojení (connection), viz dále
  • header = logická proměnná, zda soubor obsahuje na prvním řádku jména proměnných (sloupců)
  • skip = počet řádků, které se mají na začátku přeskočit
  • sep = řetězec obsahující znak, který odděluje jednotlivé sloupce
  • quote = řetězec obsahující znak, který se používá jako uvozovky k označení textů
  • dec = řetězec obsahující znak, který odděluje celá čísla a desetiny
  • comment.char = řetězec obsahující znak, který označuje komentáře
  • na.string= vektor obsahující řetězce, které se mají nahradit hodnotou NA
  • col.names = vektor názvů sloupců
  • row.names = vektor názvů řádků
  • nrows = maximální počet řádků, které má R načíst
  • colClasses = vektor, který určí, jaký datový typ nebo třídu mají jednotlivé sloupce
  • stringsAsFactors = logická proměnná, která určí, zda se řetězce mají převést na faktory; implicitně TRUE, doporučuji vypnout!

Pro speciální případy (jako je např. formát CSV) nabízí R wrappery nad touto funkcí, zejména funkce read.csv() a read.csv2(); ty však jen nastavují hodnoty některých parametrů v základní funkci read.table().

Předpokládejme, že chcete načíst data, která byla exportována z LibreOffice Calcu. Soubor se jmenuje “bmi_data.csv” a vypadá takto:

id,height,weight,bmi
1,153,55,23.4952368747
2,207,97,22.6376344839
3,173,83,27.7322997761
4,181,92,28.0821708739
5,164,112,41.6418798334

Protože se jedná o klasický CSV soubor s hlavičkou v prvním řádku, lze jej načíst takto:

bmi_data <- read.csv("nacitani_a_ukladani_dat_stuff/bmi_data.csv", stringsAsFactors = FALSE)
bmi_data
##   id height weight      bmi
## 1  1    153     55 23.49524
## 2  2    207     97 22.63763
## 3  3    173     83 27.73230
## 4  4    181     92 28.08217
## 5  5    164    112 41.64188

RStudio má pro načítání dat v textových tabulárních formátech šikovné “udělátko”: v záložce Environment je klikátko Import Dataset. Vyberte From Local File.... Nástroj odhadne většinu potřebných informací a zbytek je možné konfigurovat.

Načtená data si můžete snadno prohlédnout v záložce Environment. Definované proměnné jsou rozdělené do různých kategorií. Kategorie Data zahrnuje datasety. Kliknutím na jméno datasetu se otevře prohlížeč dat. V něm si můžete data prohlédnout, třídit a pomocí ikony “nálevky” i filtrovat. Kliknutím na ikonu “šipky” (vlevo vedle jména datasetu) se zobrazí struktura dat (podobně, jako to dělá funkce str()). Po otevření datasetu pomocí klikátka Import Dataset se prohlížeč data otevře automaticky.

4.2.2 Načítání velkých souborů

Načítání velkých souborů funguje stejně jako načítání malých souborů – se dvěma specifiky: trvá déle a zabírá více operační paměti počítače. R dokáže pracovat pouze s proměnnými, které má v operační paměti. Pokud se pokusíte načíst data, která se do paměti počítače nevejdou, R spadne.

Pomoci mohou tyto triky:

  • zjistěte si, kolik řádků má váš data set (v Linuxu vám pomůže prográmek wc), kolik má sloupců a jaký mají datový typ (v Linuxu můžete vypsat první řádky datasetu prográmkem head), a spočítejte si, kolik paměti budete potřebovat
  • pokud v souboru nejsou žádné komentáře, nastavte comment.char = ""
  • řekněte funkci read.table() jakého typu jsou jednotlivé sloupce pomocí parametru colClasses, velmi výrazně to zrychlí načítání
  • řekněte funkci read.table(), kolik řádků má váš datový soubor pomocí parametru nrows (můžete mírně nadhodnotit počet řádků, které máte), ušetří to spoustu operační paměti

Roger Peng radí následující trik, jak strojově odhadnout typ jednotlivých sloupců datasetu:

sample_dataset <- read.table("dataset.txt", nrows = 100)  # načte 100 řádků
classes <- sapply(sample_dataset, class)  # do vektoru uloží třídy sloupců datasetu
# načte celý dataset s danými datovými typy
full_dataset <- read.table("dataset.txt", colClasses = classes)

Další tipy a triky jsou v dokumentaci k funkci read.table().

Naštěstí pro vás, valná většina dat, se kterou budete v blízké budoucnosti pracovat, je tak malá, že nic z těchto triků nebudete muset používat. Například tabulka s milionem řádků a 20 sloupci, které všechny obsahují reálná čísla bude v paměti počítač zabírat 1 000  000 \(\times\) 20 \(\times\)\(=\) 160 000 000 bytů, tj. asi jen 153 MB.

4.2.3 Ukládání dat

K zapsání dat do tabulárních formátů slouží funkce write.table() (a její wrappery write.csv() a write.csv2(). Detaily jsou v dokumentaci.

4.2.4 Spojení (connections)

Když R čte nebo zapisuje data, nezapisuje přímo do souborů, ale do “spojení” (connections). Spojení zobecňuje myšlenku souboru – spojení může být lokální soubor, soubor komprimovaný algoritmem gzip a bzip (nikoli obvyklý PK Zip), URL a další. Funkce read.table() a její wrappery vytváří spojení pro čtení dat automaticky.

Pokud je datový soubor komprimovaný algoritmem gzip, není třeba jej před načtením rozbalovat:

bmi_data <- read.csv("nacitani_a_ukladani_dat_stuff/bmi_data.csv.gz", stringsAsFactors = FALSE)
bmi_data
##   id height weight      bmi
## 1  1    153     55 23.49524
## 2  2    207     97 22.63763
## 3  3    173     83 27.73230
## 4  4    181     92 28.08217
## 5  5    164    112 41.64188

Podobně je možné načíst i data z internetu, stačí nahradit jméno souboru jeho URL:

country_codes <- read.csv(
    "http://www.correlatesofwar.org/data-sets/cow-country-codes/cow-country-codes",
    stringsAsFactors = FALSE)
head(country_codes)
##   StateAbb CCode                 StateNme
## 1      USA     2 United States of America
## 2      CAN    20                   Canada
## 3      BHM    31                  Bahamas
## 4      CUB    40                     Cuba
## 5      CUB    40                     Cuba
## 6      HAI    41                    Haiti

RStudio umožňuje stahovat textová tabulární data z webu pomocí jednoduchého formuláře. Je dostupný v záložce Environment v rámci klikátka Import Dataset.

Pokud chcete uložit data pomocí spojení (např. do komprimovaného souboru), je potřeba spojení deklarovat přímo:

gfile <- gzfile("moje_data.csv.gz")
write.csv(bmi_data, file = gfile)

Víc detailů ke spojením najdete např. v Spector: Data Manipulation with R, s. 23–25 nebo Peng: R Programming for Data Science, s. 33–35.

4.2.5 Balík readr

Balík readr poskytuje funkce k načítání textových tabulárních datových souborů, které jsou rychlejší než standardní R-kové funkce popsané výše a mají i některé další výhody. Prakticky stačí balík načíst a nahradit standardní funkce funkcemi read_table(), read_csv(), read_csv2() apod. Je však lepší specifikovat typ jednotlivých sloupců, viz viněta.