Používaných externích zdrojů dat je mnoho; tři nejčastější používané jsou:

  • csv soubory
  • soubory Microsoft Excel
  • relační databáze

Postupně předvedeme použití všech tří.

Začneme inicializací – načtením tidyverse a stažením podkladových souborů, pokud lokálně neexistují.

library(tidyverse)

# pokud soubory neexistují lokálně – stahnout!
if (!file.exists('./data/potraviny.csv')) {
  curl::curl_download("https://www.jla-data.net/sample/R4SU-potraviny.csv", 
                      "./data/potraviny.csv")
}

if (!file.exists('./data/potraviny_excel.xlsx')) {
  curl::curl_download("https://www.jla-data.net/sample/R4SU-potraviny_excel.xlsx",
                      "./data/potraviny_excel.xlsx")
}

if (!file.exists('./data/encoding.txt')) {
  curl::curl_download("https://www.jla-data.net/sample/R4SU-encoding.txt",
                      "./data/encoding.txt")
}

CSV soubory

Formát CSV (comma separated values) je nejčastěji používaný formát pro výměnu tabulkových dat napříč systémy.

Má dvě základní mutace

  • hodnoty oddělené čárkami (s desetinným oddělovačem tečkou – používána zejména v USA) a
  • hodnoty oddělené středníkem (s desetinným oddělovačem čárkou – používané v ČR a dalších evropských zemích).

Pro načtení dat s oddělovačem čárka platí funkce read.csv() v base R, a readr::read_csv() z širšího tidyverse, kterou doporučuji.

Pro načtení dat s oddělovačem středník platí funkce read.csv2() v base R, a readr::read_csv2() z širšího tidyverse, kterou doporučuji.

V obou případech se jedná o specifickou úpravu obecné funkce (utils::read.table() a readr::read_delim()).

Tabulka potraviny pochází z Českého statistického úřadu, a používá českou konvenci (tj. oddělovač středník, a desetinná čárka = načtení pomocí funkce s dvojkou na konci).

library(readr)       # čte csv

potraviny_csv <- read_csv2("./data/potraviny.csv")

glimpse(potraviny_csv)
## Rows: 108,249
## Columns: 11
## $ idhod       <dbl> 770241512, 770242182, 770243168, 770243839, 770244763, 77…
## $ hodnota     <dbl> 21.35, 21.43, 21.46, 21.45, 21.39, 21.28, 21.48, 21.37, 2…
## $ stapro_kod  <dbl> 6137, 6137, 6137, 6137, 6137, 6137, 6137, 6137, 6137, 613…
## $ reprcen_cis <dbl> 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 50…
## $ reprcen_kod <chr> "0111101", "0111101", "0111101", "0111101", "0111101", "0…
## $ obdobiod    <date> 2006-01-02, 2006-01-09, 2006-01-16, 2006-01-23, 2006-01-…
## $ obdobido    <date> 2006-01-08, 2006-01-15, 2006-01-22, 2006-01-29, 2006-02-…
## $ uzemi_cis   <dbl> 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 9…
## $ uzemi_kod   <dbl> 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 1…
## $ uzemi_txt   <chr> "Česká republika", "Česká republika", "Česká republika", …
## $ reprcen_txt <chr> "Rýže loupaná dlouhozrnná [1 kg]", "Rýže loupaná dlouhozr…

Excel (.xls a .xlsx)

Microsoft Excel se používá prakticky všude, a mnoho tabulkových dat je uloženo v tomto formátu.

Excel nevynucuje konzistenci tabulkových dat, což uživatelům vyhovuje. Využívají možnosti slučování buněk a nepovinných hlavičkových sloupců. Excelové soubory proto zpravidla vyžadují před načtením do R určitou úpravu.

Je více možností načtení excelových tabulek (včetně mezikroku přes csv), doporučuji readxl::read_excel(). Zvláštní pozornost zasluhuje možnost omezit oblast (range) dat k importu. Tak je možné vyloučit problematické partie (typicky sloučené buňky).

library(readxl)      # čte xls a xlsx

potraviny_xls <- read_excel("./data/potraviny_excel.xlsx", 
                            range = "METAINFORMACE!B12:F26") # konkrétní oblast (range) metodikou Excelu

glimpse(potraviny_xls)
## Rows: 14
## Columns: 5
## $ `Kód číselníku` <dbl> 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503…
## $ `Kód položky`   <chr> NA, "0111201", "0111301", "0111303", "0112206", "0114…
## $ Název           <chr> "Číselník reprezentantů pro oblast spotřebitelských c…
## $ Definice        <chr> "Číselník reprezentantů pro oblast spotřebitelských c…
## $ Platnost        <chr> "01.01.1900 - 09.09.9999", "01.01.1900 - 09.09.9999",…

Relační databáze

Databáze jsou standardním úložištěm tabulkových dat v podnikovém prostředí. Pro přístup k datům v nich zpravidla volíme techniky jazyka SQL.

R má několik metod přístupu k datům v SQL; doporučuji obecnou knihovnu DBI ve spojení s konkrétními knihovnami pro danou databázi. Zde RPostgreSQL pro Postgres. Obecné ODBC je v packagi odbc.

Důležitá věc u databází je, že před samotným importem je potřeba inicializovat připojení (connection object) pomocí uživatelského jména a hesla, a na závěr připojení ukončit. Na to se často zapomíná, a u administrátorů s tím bývá mrzení…

library(DBI)         # interface z R do relačních databází obecně
library(RPostgreSQL) # implementace DBI pro Postgres konkrétně


con <- dbConnect(dbDriver('PostgreSQL'),
                 host = "db.jla-data.net",
                 port = 5432,
                 dbname = "R4SU",
                 user = "R4SU",     # uživatel s právem pouze select ...
                 password = "R4SU") # ... a tak jeho heslo nemusím tolik řešit :)

potraviny_sql <- dbGetQuery(con, "select * 
                                  from potraviny 
                                  where obdobiod >= date '2018-12-01'")

dbDisconnect(con) # uklidit po sobě je slušnost...
## [1] TRUE
glimpse(potraviny_sql)
## Rows: 405
## Columns: 11
## $ idhod       <dbl> 801136762, 801136747, 801136792, 801136807, 801136777, 80…
## $ hodnota     <dbl> 36.21, 11.10, 24.74, 45.34, 47.22, 223.08, 115.60, 68.22,…
## $ stapro_kod  <int> 6137, 6137, 6137, 6137, 6137, 6137, 6137, 6137, 6137, 613…
## $ reprcen_cis <int> 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 503, 50…
## $ reprcen_kod <chr> "0111101", "0111201", "0111301", "0111303", "0111602", "0…
## $ obdobiod    <date> 2018-12-10, 2018-12-10, 2018-12-10, 2018-12-10, 2018-12-…
## $ obdobido    <date> 2018-12-16, 2018-12-16, 2018-12-16, 2018-12-16, 2018-12-…
## $ uzemi_cis   <int> 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, 9…
## $ uzemi_kod   <int> 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 1…
## $ uzemi_txt   <chr> "Česká republika", "Česká republika", "Česká republika", …
## $ reprcen_txt <chr> "Rýže loupaná dlouhozrnná [1 kg]", "Pšeničná mouka hladká…

Pár slov k češtině

Erko je aplikace, běží na konkrétním operačním systému (zejména Windows, macOS a Linux). Ten (a nikoliv erko samo) se má primární zodpovědnost za kódování textu (tj. češtinu). Rozhraní mezi erkem a systémem je obecně zranitelné místo, ne vždy se od něj daří uživatele odstínit na pozadí. Tehdy se hodí konverzní funkce.

Pro práci s mezinárodními znaky používáme knihovnu stringi, dvě důležité funkce jsou:

  • stri_detect() se pokusí z textu odhadnout kódování
  • stri_encode() převede text z jednoho kódování do druhého
library(stringi)     # převody kódování (strings international)

asdf <- readLines("./data/encoding.txt")[1] # načtu první řádek ze souboru

asdf # toto bude rozsypaný čaj
## [1] "P\xf8\xedli\xb9 \xbelu\xbbou\xe8k\xfd k\xf9\xf2 \xfap\xecl \xef\xe1belsk\xe9 \xf3dy. P\xe4\xbbt\xfd\xbed\xf2ov\xe9 v\xe5\xe8at\xe1 nerv\xf3zne \xb9tekaj\xfa na m\xf4jho \xefat\xb5a v t\xe0n\xed."
stri_enc_detect(asdf) # zjistím nejpravděpodobnější kódování
## [[1]]
##     Encoding Language Confidence
## 1 ISO-8859-2       cs       0.18
## 2 IBM420_ltr       ar       0.11
## 3   UTF-16BE                0.10
## 4   UTF-16LE                0.10
## 5 ISO-8859-1       it       0.06
## 6 ISO-8859-9       tr       0.03
stri_encode(asdf, from = "ISO-8859-2", to = "UTF-8") # takhle to dává větší smysl
## [1] "Příliš žluťoučký kůň úpěl ďábelské ódy. Päťtýždňové vĺčatá nervózne štekajú na môjho ďatľa v tŕní."

Z opatrnosti radím: nepoužívejte non-ASCII znaky ve vlastním kódu (textové řetězce jsou OK) a v názvech souborů, pokud pro to nemáte opravdu vážný důvod.

Dále radím: vždy, když si můžete vybrat, volte pro text kódování Unicode (UTF-8).

Další čtení / reference