Než začneme načítat soubory - příprava

Adresář na cvičení je v proměnné cesta_k_souboru v následujícím úryvku kódu.

Odkud se berou načítací funkce

Základní dělící čára v načítání souborů vede mezi načtenou tabulkou a načteným textem. Když se něco má načíst jako tabulka, musí být rozpoznatelný počet sloupců. Na druhou stranu, tabulkový soubor si klidně můžeme načíst jako text, kdybychom chtěli. V první části této lekce se budeme zabývat načítáním tabulek, i z textového formátu.

Jinak u tabulky záleží, jestli je v tzv. flat formátu (.csv, .tsv), nebo z excelové tabulky (.xls, .xlsx). (O tabulkách z jiného statistického softwaru, např. SPSS, STATA, SAS, ani o relačních databázích mluvit nebudeme.)

Další rozdělení funkcí pro načítání souborů je podle balíčku, z kterého si funkci bereme. Základní funkce jsou v balíčku utils, který se instaluje zároveň s R. Další hodně používané balíčky jsou:

  • readr
  • data.table
  • readxl, xlsx (název napovídá, že tyto balíčky se specializují na excelové soubory)
  • rio

a jistě existují i mnohé další a další budou přibývat. Proč jich je tolik?

  • Základní funkce z balíčku utils načítají velká data pomalu.
  • Základní funkce si neporadí s excelovými soubory.

Vadilo to mnoha vývojářům naráz. Zatím se neprosadil jeden balíček, který by všechny sjednotil a nahradil. Vyzkoušejte si sami, co vám nejlépe vyhovuje. Není nutné používat celou paletu možností, ale je dobré vědět, že existují, protože někdy člověk dostane divně formátovaná data, která kladou odpor, zatímco s funkcí z jiného balíčku se můžou otevřít napoprvé a bez problémů. Když už je tabulka jednou načtená, tak se z ní nijak nepozná, jakou funkcí byla načtena, všechno je to data.frame se záhlavím nebo bez, nějak nastaveným použitím uvozovek, desetinného znaménka, záhlaví, znakových vektorů ve sloupcích jako faktorech, atd. Napřed probereme funkce z balíčku utils a pak se krátce seznámíme s jejich protějšky v ostatních balíčcích.

Načítáme soubory

Načtení souboru .RData

Pracovní prostředí nebo objekty mají příponu .RData. Načteme je pouhým zavoláním funkce load. Tato funkce se od ostatních liší tím, že nezakládá novou proměnnou. Všimněte si dál, že všechny ostatní načítací funkce načítají obsah nějakého souboru do nové proměnné!

load("austen.lower.v.RData", verbose = TRUE)
## Loading objects:
##   austen.lower.v

V pracovním prostředí přibyla proměnná, která byla uložená v tomto souboru. Náhodou se jmenuje stejně jako ten soubor, protože jsme ji tak pojmenovali, ale mohla by se jmenovat jakkoli. Její název zjistíme, když nastavíme parametr verbose na hodnotu TRUE. Defaultně je FALSE.

head(austen.lower.v)
## [1] "chapter 1"                                                            
## [2] "the family of dashwood had long been settled in sussex.  their estate"
## [3] "was large, and their residence was at norland park, in the centre of" 
## [4] "their property, where, for many generations, they had lived in so"    
## [5] "respectable a manner as to engage the general good opinion of their"  
## [6] "surrounding acquaintance.  the late owner of this estate was a single"

Bohužel nelze hned vyrobit novou proměnnou z té staré, protože se do té nové proměnné pouze uloží název té vyvolané proměnné

a <- load("austen.lower.v.RData")
a
## [1] "austen.lower.v"

Import tabulky ze souborů .csv

Základním načítacím příkazem pro soubory .csv je (v balíčku utils, který se nemusí zvlášť otvírat) funkce read.table(). Na jeho výstupu je tabulka typu data.frame. Funkce read.table() má mnoho parametrů, z toho většina má defaultní nastavení. Je to “matka všech funkcí, které načítají tabulky” (Filip Schouwenaars, www.Datacamp.com, “Importing Data into R”).

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)

Nutně potřebujeme název souboru, druh separátoru a správné nastavení header kvůli načtení záhlaví tabulky jako záhlaví a ne jako prvního řádku dat. Pokud tabulku načítáme pro bezprostřední statistickou analýzu s kvalitativními proměnnými, máme správně nastavené načtení textových sloupců jako faktorů místo prostých znakových vektorů a R je díky tomu schopno efektivně počítat s kvalitativními proměnnými. Tato vlastnost je ale velmi obtěžující, pokud tabulku před statistickou analýzou chceme nějak editovat. Když víme, že tabulku budeme napřed editovat, rovnou si ji načteme tak, aby se z textových sloupců nestaly faktory: stringsAsFactors = FALSE.

Chceme si načíst soubor s číselným hodnocením vzájemné podobnosti dvou českých slov v páru. První dva sloupce tvoří první a druhý člen slovního páru, do třetího sloupce anotátor vyplnil do záhlaví svoje jméno a pak přiděloval číselná skóre 0-10. Mohl používat i desetinná čísla.

Proměnnou cesta k souboru použijeme místo názvu souboru při jeho načítání.

Předtím jsme si ho prohlédli v textovém editoru, takže víme, jak je uspořádaný:

slovo_1.v;slovo_2.v;Silvie Cinková
dohoda;ubytování;5
planeta;měsíc;7
šálek;artikl;6
šálek;hmota;6

Důležité postřehy

Soubor má tři sloupce oddělené středníky. Na prvním řádku je záhlaví. Ŕádky jména nemají. Dva sloupce jsou textové, text není obklopen uvozovkami. Nevíme, jaké se používá desetinné znaménko. Neviděli jsme žádnou nevyplněnou hodnotu. Soubor je kódován v UTF-8.

jedna_anotace <- read.table(cesta_k_souboru, header = TRUE, sep = ";", nrows = 3 )
head(jedna_anotace)
##   slovo_1.v   slovo_2.v Silvie.CinkovĂ.
## 1    dohoda ubytování               5
## 2   planeta     měsíc               7
## 3   šálek      artikl               6

Na Windows to rozhodně chce upravit kódování:

To se udělá takhle:

jedna_anotace <- read.table(cesta_k_souboru, header = TRUE, sep = ";" , fileEncoding = "UTF-8")
head(jedna_anotace)
##   slovo_1.v slovo_2.v Silvie.Cinková
## 1    dohoda ubytování              5
## 2   planeta     měsíc              7
## 3     šálek    artikl              6
## 4     šálek     hmota              6
## 5     cesta   výprava              9
## 6     droga  zneužití              8

Ekvivalenty v jiných balíčcích

Pozor, funkce, které si odpovídají napříč balíčky, se lišívají v defaultních nastaveních některých parametrů, nejsou tedy úplně zaměnitelné a je stejně potřeba vědět, jaké hodnoty parametů chcete!

Funkce read.table() má v balíčku readr tento protějšek: read_delim(). Pozor, neplést s funkcí read.delim() ze základního balíčku utils, která načítá tabulky ve formátu .tsv.

Funkce read.csv() má v balíčku readr tento protějšek: read_csv().

Obě funkce mají v balíčku data.table tento protějšek: fread(). Pozor, balíček data.table je velmi rozsáhlý a mnohostranný nástroj na zpracování tabulek, je to takový skoro “dialekt” v rámci základního R. Má mnohem víc funkcí než jen načítání souborů! Tento balíček si zakládá na tom, že funkce pracují rychle. Hodí se tedy pro opravdu velká data (třeba tabulka o milionu řádků). Výhodou funkce fread() je, že se jí většinou nemusí říct nic dalšího kromě názvu souboru. Soubor si prohlédne a zákonitosti odhalí sama. Všechno se tam ale dá nastavit i ručně a parametry jsou podobné jako u read.table. Mohla by to být funkce druhé volby, když nechce správně pracovat read.table().

library(data.table)
a <- fread(cesta_k_souboru, encoding = "UTF-8")
a
##      slovo_1.v  slovo_2.v Silvie Cinková
##   1:    dohoda  ubytování               5
##   2:   planeta      měsíc               7
##   3:     šálek     artikl               6
##   4:     šálek      hmota               6
##   5:     cesta    výprava               9
##  ---                                     
## 630:    riziko  pojištění               7
## 631:     mnich   věštírna               0
## 632:     vodka     brandy               8
## 633:  moralita důležitost               0
## 634:  vybavení    výrobce               6

Když zlobí uvozovky v textech

Tabulkové soubory z korpusu, kde v jednom sloupci je levý kontext, v prostředním je KWIC a v pravém sloupci je pravý kontext, se můžou načítání do tabulky vzpírat, protože můžou obsahovat text, který vypadá jako formátování tabulky. Typicky jsou to čárky, středníky, uvozovky a apostrofy v textu. Neprůstřelné bývá si vstupní soubor uložit tak, aby obsahoval uvozovky kolem textu každého sloupce, protože pak se všechny ostatní uvnitř ošetří escapovacími značkami (zpětnými lomítky). Zároveň ponechat defaultní nastavení parametru quote = "\"".

cesta_konkordance <- file.path("data", "soubory_k_nacteni_cviceni", "KONK_abolish.csv")
tabulka_konkordance <- read.table(cesta_konkordance, sep = ";" , quote = "\"", nrows = 1, header = TRUE)
head(tabulka_konkordance)
##   ref
## 1 A03
##                                                                                                                                                                                                                                                                                                                                                                         LEFT
## 1 communications be sent to the prisoner . TUNISIA Hamadi Jebali : a 51-year-old newspaper editor from Sousse , he was sentenced by the military court in Tunis on 31 January 1991 to one year 's imprisonment for publishing an article calling for the abolition of military courts . The article , entitled ` When will military courts , serving as special courts , be 
##          KWIC
## 1  ABOLISHED 
##                                                                                                                                                                                                                                                                                                                                                                    RIGHT
## 1  ? ' and written by a Tunisian lawyer , was published in 27 October 1990 in Al-Fajr ( Dawn ) , the official newspaper of the non-recognized Islamic group Hizb al-Nahda ( Renaissance ) . Hamadi Jebali was charged with defamation of a judicial institution under the Tunisian Press Code , under which prior authorization by the Ministry of Interior is required 
##                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        SENTENCE
## 1 communications be sent to the prisoner . TUNISIA Hamadi Jebali : a 51-year-old newspaper editor from Sousse , he was sentenced by the military court in Tunis on 31 January 1991 to one year 's imprisonment for publishing an article calling for the abolition of military courts . The article , entitled ` When will military courts , serving as special courts , be   ABOLISHED   ? ' and written by a Tunisian lawyer , was published in 27 October 1990 in Al-Fajr ( Dawn ) , the official newspaper of the non-recognized Islamic group Hizb al-Nahda ( Renaissance ) . Hamadi Jebali was charged with defamation of a judicial institution under the Tunisian Press Code , under which prior authorization by the Ministry of Interior is required

Funkce read.csv a read.csv2

Když soubory vypadají standardně a není třeba si moc hrát s jejich nastavováním, dají se použít odvozeniny read.csv a read.csv2. To první se používá na americký formát .csv a to druhé na evropský formát .csv. Tabulky .csv mají sloupce standardně oddělené čárkami (proto ta přípona, znamená “comma-separated values”). Jako zkratka pro načtení takových souborů se používá funkce read.csv() - je to jako read.table, ale má defaultně nastavené parametry tak, aby snadno načetla správně americky formátovaný soubor .csv : header = TRUE, sep = ",", stringsAsFactors = FALSE, dec = ".". (Desetinná tečka, ne čárka). Pro evropsky formátovaná csv s desetinnou čárkou a oddělovačem středníkem je tu funkce read.csv2.

Import tabulky ze souborů .txt

Základní funce R v balíčku utils

Další taková funkce: read.delim()(americká) a read.delim2 (evropská), ta má zase přednastavený jako separátor tabelátor a podle světadílu desetinnou tečku/čárku. Tyto funkce se hodí na tabulky uložené jako .txt.

mazlicci_read.delim <- read.delim("data/soubory_k_nacteni_cviceni/mazlicci.txt", encoding = "UTF-8")
mazlicci_read.delim
##   X.U.FEFF.morče       kanár    malý.pes   X1.5
## 1          morče      potkan     rybičky   5.36
## 2          želva     rybičky střední pes   8.00
## 3          kočka    papoušek       želva   0.20
## 4       malý pes   velký pes      křeček   0.00
## 5          osmák   chameleón         had   9.00
## 6         potkan       kočka    malý pes  69.00
## 7       malý pes střední pes   velký pes 222.40

Kdyby se v datech používala desetinná čárka, bylo by třeba použít funkci read.delim2, nebo ručně přenastavit parametr v read.delim. Nešlo použít parametr fileEncoding, muselo se použít encoding, protože se někde vytvářel “invalid input”.

Funkce read_tsv() v balíčku readr

library(readr)
mazlicci_read_tsv <-  read_tsv("data/soubory_k_nacteni_cviceni/mazlicci.txt", col_names = FALSE)
mazlicci_read_tsv
##              X1          X2          X3     X4
## 1 <U+FEFF>morče       kanár    malý pes   1.50
## 2         morče      potkan     rybičky   5.36
## 3         želva     rybičky střední pes   8.00
## 4         kočka    papoušek       želva   0.20
## 5      malý pes   velký pes      křeček   0.00
## 6         osmák   chameleón         had   9.00
## 7        potkan       kočka    malý pes  69.00
## 8      malý pes střední pes   velký pes 222.40
str(mazlicci_read_tsv)
## Classes 'tbl_df', 'tbl' and 'data.frame':    8 obs. of  4 variables:
##  $ X1: chr  "<U+FEFF>morče""| __truncated__ "morče" "želva" "kočka" ...
##  $ X2: chr  "kanár" "potkan" "rybičky" "papoušek" ...
##  $ X3: chr  "malý pes" "rybičky" "střední pes" "želva" ...
##  $ X4: num  1.5 5.36 8 0.2 0 ...

Funkce fread v balíčku data.table

library(data.table)
mazlicci_fread <- fread("data/soubory_k_nacteni_cviceni/mazlicci.txt", encoding = "UTF-8") #tady parametr encoding na Windows zafungoval
mazlicci_fread
##               V1          V2          V3     V4
## 1: <U+FEFF>morče       kanár    malý pes   1.50
## 2:         morče      potkan     rybičky   5.36
## 3:         želva     rybičky střední pes   8.00
## 4:         kočka    papoušek       želva   0.20
## 5:      malý pes   velký pes      křeček   0.00
## 6:         osmák   chameleón         had   9.00
## 7:        potkan       kočka    malý pes  69.00
## 8:      malý pes střední pes   velký pes 222.40
str(mazlicci_fread)
## Classes 'data.table' and 'data.frame':   8 obs. of  4 variables:
##  $ V1: chr  "<U+FEFF>morče""| __truncated__ "morče" "želva" "kočka" ...
##  $ V2: chr  "kanár" "potkan" "rybičky" "papoušek" ...
##  $ V3: chr  "malý pes" "rybičky" "střední pes" "želva" ...
##  $ V4: num  1.5 5.36 8 0.2 0 ...
##  - attr(*, ".internal.selfref")=<externalptr>
library(rio)
mazlicci_rio <- import("data/soubory_k_nacteni_cviceni/mazlicci.txt", encoding = "UTF-8")
mazlicci_rio
##              V1          V2          V3     V4
## 1 <U+FEFF>morče       kanár    malý pes   1.50
## 2         morče      potkan     rybičky   5.36
## 3         želva     rybičky střední pes   8.00
## 4         kočka    papoušek       želva   0.20
## 5      malý pes   velký pes      křeček   0.00
## 6         osmák   chameleón         had   9.00
## 7        potkan       kočka    malý pes  69.00
## 8      malý pes střední pes   velký pes 222.40
str(mazlicci_rio)
## 'data.frame':    8 obs. of  4 variables:
##  $ V1: chr  "<U+FEFF>morče""| __truncated__ "morče" "želva" "kočka" ...
##  $ V2: chr  "kanár" "potkan" "rybičky" "papoušek" ...
##  $ V3: chr  "malý pes" "rybičky" "střední pes" "želva" ...
##  $ V4: num  1.5 5.36 8 0.2 0 ...

U funkcí z pokročilých balíčků narážíme na různé problémy s kódováním. Buď to nefunguje vůbec a diakritika se pokazí, nebo se to bez zjevného důvodu po dalším spuštění načte správně, ale první sloupec v prvním řádku má před sebou takovou divnou preambuli <U+FEFF>.

Problematické parametry u načítání tabulek, jejichž použití se nevyhneme

Parametr stringsAsFactors

U všech funkcí k načítání souborů z balíčku utils, který je rovnou zabudován v distribuci R, má tento parametr defaultní hodnotu TRUE. To znamená, že všechny sloupce, které obsahují znaky, se stanou faktory. Pokud tuto vlastnost chceme zakázat, musíme to udělat explicitní volbou stringsAsFactors = FALSE. Proč se znakové vektory ve sloupcích defaultně načítají jako faktory? Mnoho statistických analytických a grafických funkcí potřebuje mít přehled, jakého druhu je proměnná v kterém sloupci. Faktory jsou vyjádřením kategoriální nebo ordinální proměnné. Například tím, že u faktoru lze tuto informaci nastavit, zatímco u obyčejného znakového vektoru nikoli. Faktory jsou tedy optimální reprezentace kvalitativních proměnných pro statistickou analýzu v R. Na druhou stranu, editovat faktory je mnohem složitější než editovat znakové vektory. Pokud tedy načítáme data, o kterých víme, že je ještě budeme nějak upravovat, než je pustíme do nějaké statistické funkce, je rozhodně lepší si je načíst bez faktorů. Až si data vyčistíme, můžeme si je uložit do souboru a ten pak načíst s faktory.

Parametry fileEncoding a encoding

Tyto dva parametry nejsou synonymní. Nápověda mi není srozumitelná. Domnívám se, že encoding je kódovací procedura kdesi v hlubinách stroje a že viditelné a předvídatelné výsledky přináší spíš fileEncoding. Parametr encoding může nabývat jenom hodnot unknown, Latin-1 a UTF-8. Do fileEncoding se dá napsat snad jakékoli kódování. R je anglo-centrické a diakritická kódování v něm občas mají problém. Jako laikům nám zbývá postupovat metodou pokus-omyl, googlit kódovací balíčky (stringi!) a případně se smířit s tím, že některé velmi pěkné balíčky se občas s kódováním neobtěžují a my jejich funkce nemůžeme na znaky mimo ASCII nebo západní znakovou sadu použít.

Další funkce na načítání tabulkových souborů do tabulkových datových struktur

Základní načítací funkce R pracují pomalu a nenačtou excelové tabulky ve formátech .xls a .xlsx. Proto bylo vyvinuto několik balíčků, které načítání provedou rychleji. Často se taky více snaží odhadnout formát tabulky samy a nemusí se tolik nastavovat. Na druhou stranu je do nich “hůř vidět”, názvy jich samotných a jejich parametrů se pletou s těmi základními a můžou mít větší potíže s kódováním na Windows (vyzkoušeno).

Nejznámějšími balíčky na načítání dat jsou readr, data.table a rio. U rio je přitažlivé, že má jen dvě funkce, které by se měly o všechno postarat samy: import a export. Jenže import si (zatím?) neporadí s UTF-8 na Windows. Možnou výhodou readr je, že se textové sloupce v tabulkách nenačítají jako faktory. Jinak má jiné defaultní nastavení parametrů, např. header je TRUE. Když mu nastavíme FALSE, pojmenuje si sloupce písmenky a čísly. Když mu dáme znakový vektor správné délky, pojmenuje sloupce v tabulce podle elementů toho vektoru.

library(readr)

anotace_readr_read_delim <- read_delim(cesta_k_souboru, delim = ";")
head(anotace_readr_read_delim,2)
##   slovo_1.v slovo_2.v Silvie Cinková
## 1    dohoda ubytování              5
## 2   planeta     měsíc              7
str(anotace_readr_read_delim)
## Classes 'tbl_df', 'tbl' and 'data.frame':    634 obs. of  3 variables:
##  $ slovo_1.v     : chr  "dohoda" "planeta" "šálek" "šálek" ...
##  $ slovo_2.v     : chr  "ubytování" "měsíc" "artikl" "hmota" ...
##  $ Silvie Cinková: int  5 7 6 6 9 8 5 7 6 8 ...

Funkce read_delim z balíčku readr má ještě další výhodu: umožňuje vybrat si sloupce, které budou načteny. Základní funkce (v balíčku utils, který se nainstaluje zároveň s R) tohle neumějí. Když chceme načíst jenom nějakou část souboru, musíme napřed načíst všechno a pak si požadovaný subset uložit do další proměnné. To vybírání sloupců předem při načtení se dělá tak, že se vyplní parametr col_types, za každý sloupec zkratka typu, jak se má načíst, a když se nemá načíst, tak podtržítko. Načteme jenom ten číselný sloupec a z něj jenom prvních pět řádků:

anotace_readr_read_delim_treti_sloupec <- read_delim(cesta_k_souboru, delim = ";", col_types = "__d", col_names = TRUE, n_max = 5)
anotace_readr_read_delim_treti_sloupec
##   Silvie Cinková
## 1              5
## 2              7
## 3              6
## 4              6
## 5              9

Zkratky pro typy vektorů jsou

    c = character
    d = double (jakékoli číslo)
    i = integer (celé číslo)
    l = logical
    _ = skip

Import tabulky z Microsoft Excelu (soubory .xls a .xlsx)

library(readxl)
mazlicci_read_excel <- read_excel("data/soubory_k_nacteni_cviceni/mazlicci.xlsx", col_names = FALSE, sheet = 1)
mazlicci_read_excel
##         X0          X1          X2     X3
## 1    morče       kanár    malý pes   1.50
## 2    morče      potkan     rybičky   5.36
## 3    želva     rybičky střední pes   8.00
## 4    kočka    papoušek       želva   0.20
## 5 malý pes   velký pes      křeček   0.00
## 6    osmák   chameleón         had   9.00
## 7   potkan       kočka    malý pes  69.00
## 8 malý pes střední pes   velký pes 222.40
library(xlsx)
## Loading required package: rJava
## Loading required package: xlsxjars
mazlicci_read.xlsx <- read.xlsx("data/soubory_k_nacteni_cviceni/mazlicci.xlsx", 1, as.data.frame = TRUE, header = FALSE, encoding = "UTF-8")
mazlicci_read.xlsx
##         X1          X2          X3     X4
## 1    morče       kanár    malý pes   1.50
## 2    morče      potkan     rybičky   5.36
## 3    želva     rybičky střední pes   8.00
## 4    kočka    papoušek       želva   0.20
## 5 malý pes   velký pes      křeček   0.00
## 6    osmák   chameleón         had   9.00
## 7   potkan       kočka    malý pes  69.00
## 8 malý pes střední pes   velký pes 222.40

Dále je možné zpracovat celý excelový “workbook” s mnoha listy do seznamu tabulek a mnoho jiných věcí, jakož i potom zapisovat zpátky do excelového souboru, ale až tam se pouštět nebudeme.

Import textu ze souborů .txt pomocí funkce scan()

Hlavní funkcí pro načítání textů je asi funkce scan(). Je to takový textový protějšek funkce read.table(). Má parametry na vynechání počtu počátečních řádků, zobrazení počtu řádků, různého vynechávání prázdných řádků, záznamů hodnot NA. Kromě lineárních textů v řádcích umí taky načítat matice a tabulky, ale na rozdíl od read.table je načítá do vektorů a seznamů. Je třeba vždy vyplnit parametr what, který uvádí, jakého druhu bude výsledný vektor, případně že výsledkem bude seznam. My budeme typicky používat scan na čtení lineárního textu, takže parametr what u nás vždy bude character. Další přípustné hodnoty jsou: logical, integer, numeric, complex, raw a list.

muj.korpus <- scan("data/plainText/melville.txt", what = "character", sep = "\n", nmax = 3) # tři řádky
muj.korpus
## [1] "The Project Gutenberg EBook of Moby Dick; or The Whale, by Herman Melville"
## [2] "This eBook is for the use of anyone anywhere at no cost and with"          
## [3] "almost no restrictions whatsoever.  You may copy it, give it away or"
muj.korpus <- scan("data/plainText/melville.txt", what = "character", nmax = 3) # tři slova (defaultní separátor je mezera)
muj.korpus
## [1] "The"       "Project"   "Gutenberg"
#muj.korpus <- scan(file.choose(), what = "character", sep = "\n") 

Zkusíme si jen pro zajímavost načíst tabulku mazlíčci (z .txt) jako seznam. Pro připomenutí, takhle vypadá výchozí soubor:

    morče   kanár   malý pes    1.5
    morče   potkan  rybičky 5.36
    želva   rybičky střední pes 8
    kočka   papoušek    želva   0.2
    malý pes    velký pes   křeček  0
    osmák   chameleón   had 9
    potkan  kočka   malý pes    69
    malý pes    střední pes velký pes   222.4

Je to tabulka se čtyřmi sloupci oddělenými tabelátorem, řetězce ve třech sloupcích obsahují mezery a nejsou v uvozovkách. Poslední sloupec obsahuje čísla s desetinnými tečkami.

Parametr what funkce scan bude mít hodnotu list, ale pozor! Píše se to jinak než ostatní hodnoty tohoto parametru. Není v uvozovkách a za tím povinně následuje výčet všech sloupců tabulky

mazlicci_scan <- scan("data/soubory_k_nacteni_cviceni/mazlicci.txt",  sep = "\t", what = list("zvířátka v 1. A" = character(0), "zvířátka v 1.B" = character(0), "zvířátka v 1.C" = character(0), "průměrný věk" = numeric(0)), encoding = "UTF-8")
str(mazlicci_scan)
## List of 4
##  $ zvířátka v 1. A: chr [1:8] "<U+FEFF>morče""| __truncated__ "morče" "želva" "kočka" ...
##  $ zvířátka v 1.B : chr [1:8] "kanár" "potkan" "rybičky" "papoušek" ...
##  $ zvířátka v 1.C : chr [1:8] "malý pes" "rybičky" "střední pes" "želva" ...
##  $ průměrný věk   : num [1:8] 1.5 5.36 8 0.2 0 ...
mazlicci_scan
## $`zvířátka v 1. A`
## [1] "<U+FEFF>morče" "morče"    "želva"    "kočka"    "malý pes" "osmák"   
## [7] "potkan"   "malý pes"
## 
## $`zvířátka v 1.B`
## [1] "kanár"       "potkan"      "rybičky"     "papoušek"    "velký pes"  
## [6] "chameleón"   "kočka"       "střední pes"
## 
## $`zvířátka v 1.C`
## [1] "malý pes"    "rybičky"     "střední pes" "želva"       "křeček"     
## [6] "had"         "malý pes"    "velký pes"  
## 
## $`průměrný věk`
## [1]   1.50   5.36   8.00   0.20   0.00   9.00  69.00 222.40

Zrovna tady nešlo použít fileEncoding = "UTF-8", protože to rozhodilo sloupce. Zřejmě se v nějakém řádku něco kódovalo jako \t a pak se to naparsovalo jako další sloupec, takže počet sloupců přestal souhlasit a tabulku nešlo vytvořit… Tento skript byl laděn na Windows 7, různé kombinace a přítomnost/nepřítomnost informace o kódování je třeba vyzkoušet na vlastním počítači. Další parametry pracovního nastavení počítače, kde skript vznikl: české locale, globální nastavení RStudia je na UTF-8.

Odkud načítat? Parametry file a text

muj.korpus <- scan("data/plainText/melville.txt", what = "character", sep = "\n", nmax = 3) #tři řádky
muj.korpus
## [1] "The Project Gutenberg EBook of Moby Dick; or The Whale, by Herman Melville"
## [2] "This eBook is for the use of anyone anywhere at no cost and with"          
## [3] "almost no restrictions whatsoever.  You may copy it, give it away or"
muj.korpus <- scan("data/plainText/melville.txt", what = "character", nmax = 3) #tři slova (defaultní separátor je mezera)
muj.korpus
## [1] "The"       "Project"   "Gutenberg"
#muj.korpus <- scan(file.choose(), what = "character", sep = "\n") 

Soubor, odkud se má číst, se zadává jako první, nebo na libovolné pozici explicitně uvedený jako hodnota parametru file. Místo parametru file lze použít parametr text. Do uvozovek se tam dá napsat nebo odněkud zkopírovat vlastní text. To se (prý) často využívá k načtení excelového souboru, když není příliš veliký:

muj.korpus <- scan(what = "character", text = "bla bla bla", sep = " ") 
muj.korpus
## [1] "bla" "bla" "bla"
moje.tabulka  <- scan(what = list("zvířátka v 1. A" = character(0), "zvířátka v 1.B" = character(0), "zvířátka v 1.C" = character(0), "průměrný věk" = numeric(0)), sep = "\t", dec = "," , text = "
morče   kanár   malý pes    1,50
morče   potkan  rybičky 5,36
želva   rybičky střední pes 8,00
kočka   papoušek    želva   0,20
malý pes    velký pes   křeček  0,00
osmák   chameleón   had 9,00
potkan  kočka   malý pes    69,00
malý pes    střední pes velký pes   222,40") 

moje.tabulka
## $`zvířátka v 1. A`
## [1] "morče"    "morče"    "želva"    "kočka"    "malý pes" "osmák"   
## [7] "potkan"   "malý pes"
## 
## $`zvířátka v 1.B`
## [1] "kanár"       "potkan"      "rybičky"     "papoušek"    "velký pes"  
## [6] "chameleón"   "kočka"       "střední pes"
## 
## $`zvířátka v 1.C`
## [1] "malý pes"    "rybičky"     "střední pes" "želva"       "křeček"     
## [6] "had"         "malý pes"    "velký pes"  
## 
## $`průměrný věk`
## [1]   1.50   5.36   8.00   0.20   0.00   9.00  69.00 222.40
str(moje.tabulka)
## List of 4
##  $ zvířátka v 1. A: chr [1:8] "morče" "morče" "želva" "kočka" ...
##  $ zvířátka v 1.B : chr [1:8] "kanár" "potkan" "rybičky" "papoušek" ...
##  $ zvířátka v 1.C : chr [1:8] "malý pes" "rybičky" "střední pes" "želva" ...
##  $ průměrný věk   : num [1:8] 1.5 5.36 8 0.2 0 ...

Načítání textu ze souboru pomocí funkce readLines()

Načítá soubor jako text po řádcích. Místo parametru file má parametr con jako connection. Connection je nadřazený termín souboru, tj.soubor je jeden z možných druhů connections. Další connections můžou být třeba zazipované soubory, hypertextové odkazy, atp.

Načteme si pět řádků z románu od J. Austen.

muj.korpus <- readLines(con = "data/plainText/austen.txt", n = 5)
muj.korpus
## [1] "The Project Gutenberg EBook of Sense and Sensibility, by Jane Austen"
## [2] ""                                                                       
## [3] "This eBook is for the use of anyone anywhere at no cost and with"       
## [4] "almost no restrictions whatsoever.  You may copy it, give it away or"   
## [5] "re-use it under the terms of the Project Gutenberg License included"

Vytiskne se toto:

  [1] "The Project Gutenberg EBook of Sense and Sensibility, by Jane Austen" ""                                                                       
  [3] "This eBook is for the use of anyone anywhere at no cost and with"        "almost no restrictions whatsoever.  You may copy it, give it away or"   
  [5] "re-use it under the terms of the Project Gutenberg License included"    
  

Tady ještě slovo ke kódování: když se načte s neznámým kódováním, na začátku se objeví divný znak. To je nějaký neviditelný textový znak pro kódování UTF. Něco podobného už kazilo naše tabulky s texty s českou diakritikou. Když se kódování explicitně nastaví na UTF-8, v konzoli se vše ukáže správně. Ale v markdownu je to pořád špatně. Neumím to vysvětlit ani napravit.

muj.korpus <- readLines(con = "data/plainText/austen.txt", n = 5, encoding = "UTF-8")
muj.korpus
## [1] "<U+FEFF>The Project Gutenberg EBook of Sense and Sensibility, by Jane Austen"
## [2] ""                                                                    
## [3] "This eBook is for the use of anyone anywhere at no cost and with"    
## [4] "almost no restrictions whatsoever.  You may copy it, give it away or"
## [5] "re-use it under the terms of the Project Gutenberg License included"

Řádky jsou tu trochu divné, člověk by čekal nový řádek u konce odstavce. V originálním textovém souboru ale vidíme konce řádků na libovolných místech ve větě, zřejmě na místech, kde byl pravý okraj tiskové strany. Rozhodně nejde o rozdíl mezi funkcí scan() a readLines().

Další způsoby načítání textu do proměnné - ne ze souboru - pomocí funkce scan()

Import textu z uživatelova přímého vstupu přes klávesnici

Toto je podobná procedura jako použití parametr text, ale ukládá se po jednotlivých elementech. Je to interaktivnější postup. Používá se třeba k vyplňování elektronických formulářů. Každá proměnná reprezentuje jedno formulářové pole. Jsou přece i taková pole, kam se vyplňuje více hodnot, například: “Osoby žijící ve společné domácnosti”.

# a <- scan(file = "", what = "character", sep = "\n")
  > a <- scan(file = "", what = "character", sep = "\n")
  1: dddd
  2: ddds
  3: tttt
  4: eeee
  5: 
  Read 4 items

Jakmile se řádek s tímto kódem spustí, v konzoli se objeví jednička s dvojtečkou. R čeká na první vstup od uživatele z klávesnice. Konec zadávání prvního vstupu: Enter. Úplný konec zadávání: dvojitý Enter. V kódu výše je vidět, co se stane po dvojitém stisknutí Enter na pátém řádku: vstup je ukončen a načetly se ty čtyři neprázdné položky předtím.

I pro zadávání z klávesnice platí všechny ostatní zákonitosti funkce scan(), takže se nesmí zapomenout na parametr what!

Import z textu předem zadaného ve skriptu

Viz parametr text u funkce scan().

Import ze schránky

Podobně jako parametr text je možné použít i samotný parametr file. Do schránky si zkopírujeme text, který chceme načíst do R datového objektu (Ctrl+c, Ctrl+v), a do parametru file vyplníme hodnotu "clipboard" i s těmi uvozovkami.

Aktuální obsah stránky v příkladu:

    morče   kanár   malý pes    1,50
    morče   potkan  rybičky 5,36
    želva   rybičky střední pes 8,00
    kočka   papoušek    želva   0,20
    malý pes    velký pes   křeček  0,00
    osmák   chameleón   had 9,00
    potkan  kočka   malý pes    69,00
    malý pes    střední pes velký pes   222,40

Načtení obsahu schránky. Pozor, když je to excelová tabulka jako tady a má se načíst jako seznam, je třeba řádně popsat a pojmenovat sloupce a určit separátor. Tady navíc máme jiné desetinné znaménko, takže ho musíme explicitně definovat, jinak by R chtělo tato čísla načíst jako text, což by se ale nezdařilo, protože v parametru list má pro tento sloupec určeno, že k němu má přistupovat jako k číslům, a skript by spadl. Na druhou stranu není potřeba řešit kódování (aspoň při konfiguraci PC na počítači, kde skript vzniká).

#moje.tabulka  <- scan(file = "clipboard", what = list("zvířátka v 1. A" = character(0), "zvířátka v 1.B" = character(0), "zvířátka v 1.C" = character(0), "průměrný věk" = numeric(0)), sep = "\t", dec = ",") 

#moje.tabulka
#str(moje.tabulka)

Kód je zakomentovaný, protože při spuštění na jiném počítači a s jiným nebo žádným obsahem stránky by markdown spadl.

Vrátí se toto:

    > moje.tabulka  <- scan(file = "clipboard", what = list("zvířátka v 1. A" = character(0), "zvířátka v 1.B" = character(0), "zvířátka v 1.C" = character(0), "průměrný věk" = numeric(0)), sep = "\t", dec = ",")
    Read 8 records
    > moje.tabulka
    $`zvířátka v 1. A`
    [1] "morče"    "morče"    "želva"    "kočka"    "malý pes" "osmák"    "potkan"   "malý pes"
    
    $`zvířátka v 1.B`
    [1] "kanár"       "potkan"      "rybičky"     "papoušek"    "velký pes"   "chameleón"   "kočka"       "střední pes"
    
    $`zvířátka v 1.C`
    [1] "malý pes"    "rybičky"     "střední pes" "želva"       "křeček"      "had"         "malý pes"    "velký pes"  
    
    $`průměrný věk`
    [1]   1.50   5.36   8.00   0.20   0.00   9.00  69.00 222.40
    

Jen pro Windows! Funkce readClipboard()

Data z jiné aplikace se dají přenést ze schránky do vektoru pomocí funkce readClipboard. Ta má dva parametry - format a raw. Default je format = 1 a raw = FALSE. Když se se znakovými daty nakládá jako raw, znamená to, že se znaky převedou na bajty (bytes), kde každý bajt je pár hexadecimálních čísel, takže je to formát pro člověka nečitelný. Někdy je lépe stravitelný pro převody kódování mezi sebou atd. Parametr format je pochopitelnější - v nápovědě funkce readClipboard je seznam možných formátů (text, obrázky, audio…). Text je v defaultním nastavení 1 (bez uvozovek).

Aktuálním obsahem stránky je excelová tabulka s mazlíčky. Takto funkce pracuje v defaultním nastavení.

# a <- readClipboard()
# a
    > a
    [1] "morče\tkanár\tmalý pes\t1,50"             "morče\tpotkan\trybičky\t5,36"             "želva\trybičky\tstřední pes\t8,00"        "kočka\tpapoušek\tželva\t0,20"             "malý pes\tvelký pes\tkřeček\t0,00"       
    [6] "osmák\tchameleón\thad\t9,00"              "potkan\tkočka\tmalý pes\t69,00"           "malý pes\tstřední pes\tvelký pes\t222,40"

Každý řádek se načetl jako element vektoru, mezi sloupce se vložily tabelátory (\t)

Aktuálním obsahem stránky je teď volný text z konsole:

# a <- readClipboard()
# a
[1] "Type 'demo()' for some demos, 'help()' for on-line help, or"     "'help.start()' for an HTML browser interface to help."           "Type 'q()' to quit R."                                          
[4] ""                                                                "[Workspace loaded from C:/Seafile/Silvie_R/R_VYUKA_2016/.RData]"
> 

Data z webu - stahování nebo/a přímý import do proměnné

Základní funkce z balíčku utils umí načíst soubor do proměnné přímo z webu, aniž by ho stahovaly. URL se napíše do uvozovek jako hodnota parametru file. Balíček readxl to ale pro excelové tabulky ještě neumí. Když se nedá soubor z webu rovnou načíst, ale musí se stáhnout, dá se to stahování a ukládání zařídit z příkazové řádky. Takhle se dá stáhnout z webu jakýkoli soubor:

library(readxl)
url <- "http://www.msmt.cz/file/36143_1_1/" 
dest_path <- file.path("data", "soubory_k_nacteni_cviceni", "ministersky_dokument.xls")
download.file(url, dest_path, mode = "wb")
read_excel(dest_path)
##                Název organizace:       NA    NA             NA
## 1   Název vzdělávacího programu:     <NA>  <NA>           <NA>
## 2         Termín a místo konání:     <NA>  <NA>           <NA>
## 3  Počet proškolených účastníků:     <NA>  <NA>           <NA>
## 4                ČÍSLO OSVĚDČENÍ PŘÍJMENÍ JMÉNO DATUM NAROZENÍ
## 5                           <NA>     <NA>  <NA>           <NA>
## 6                           <NA>     <NA>  <NA>           <NA>
## 7                           <NA>     <NA>  <NA>           <NA>
## 8                           <NA>     <NA>  <NA>           <NA>
## 9                           <NA>     <NA>  <NA>           <NA>
## 10                          <NA>     <NA>  <NA>           <NA>
## 11                          <NA>     <NA>  <NA>           <NA>
## 12                          <NA>     <NA>  <NA>           <NA>
##                 NA         NA
## 1             <NA>       <NA>
## 2             <NA>       <NA>
## 3             <NA>       <NA>
## 4  ADRESA BYDLIŠTĚ ORGANIZACE
## 5             <NA>       <NA>
## 6             <NA>       <NA>
## 7             <NA>       <NA>
## 8             <NA>       <NA>
## 9             <NA>       <NA>
## 10            <NA>       <NA>
## 11            <NA>       <NA>
## 12            <NA>       <NA>

Mělo by se vrátit toto a v daném adresáři přibýt soubor “ministersky_dokument.xls”

    > library(readxl)
    > url <- "http://www.msmt.cz/file/36143_1_1/"
    > dest_path <- file.path("data", "soubory_k_nacteni_cviceni", "ministersky_dokument.xls")
    > download.file(url, dest_path, mode = "wb")
    trying URL 'http://www.msmt.cz/file/36143_1_1/'
    Content type 'application/vnd.ms-excel' length 18944 bytes (18 KB)
    downloaded 18 KB
    
    > read_excel(dest_path)
                   Název organizace:       NA    NA             NA              NA         NA
    1   Název vzdělávacího programu:     <NA>  <NA>           <NA>            <NA>       <NA>
    2         Termín a místo konání:     <NA>  <NA>           <NA>            <NA>       <NA>
    3  Počet proškolených účastníků:     <NA>  <NA>           <NA>            <NA>       <NA>
    4                ČÍSLO OSVĚDČENÍ PŘÍJMENÍ JMÉNO DATUM NAROZENÍ ADRESA BYDLIŠTĚ ORGANIZACE
    5                           <NA>     <NA>  <NA>           <NA>            <NA>       <NA>
    6                           <NA>     <NA>  <NA>           <NA>            <NA>       <NA>
    7                           <NA>     <NA>  <NA>           <NA>            <NA>       <NA>
    8                           <NA>     <NA>  <NA>           <NA>            <NA>       <NA>
    9                           <NA>     <NA>  <NA>           <NA>            <NA>       <NA>
    10                          <NA>     <NA>  <NA>           <NA>            <NA>       <NA>
    11                          <NA>     <NA>  <NA>           <NA>            <NA>       <NA>
    12                          <NA>     <NA>  <NA>           <NA>            <NA>       <NA>
    > 
    

Dokument má mít tolik prázdných políček, je to šablona formuláře. Parametr mode = "wb" - ve webovém tutorialu se neobjevil, ale mně to bez něj nefungovalo. Rada ze StackOverflow.

Zkusíme ještě stáhnout a přečíst wordový dokument:

library(qdapTools)
## 
## Attaching package: 'qdapTools'
## The following object is masked from 'package:data.table':
## 
##     shift
url <- "http://www.msmt.cz/file/36346_1_1/"
dest_path <- file.path("data", "soubory_k_nacteni_cviceni", "ministersky_dokument_doc.doc")
download.file(url, dest_path, mode = "wb")
#read_docx(dest_path)    
    > library(qdapTools)
    > url <- "http://www.msmt.cz/file/36346_1_1/"
    > dest_path <- file.path("data", "soubory_k_nacteni_cviceni", "ministersky_dokument_doc.doc")
    > download.file(url, dest_path, mode = "wb")
    trying URL 'http://www.msmt.cz/file/36346_1_1/'
    Content type 'application/msword' length 124928 bytes (122 KB)
    downloaded 122 KB
    
    > read_docx(dest_path)
    Error: XML content does not seem to be XML: 'C:\Users\cinkova\AppData\Local\Temp\RtmpWY9MOK\file13d0ae272ad/word/document.xml'
    >       
            

Wordové dokumenty prý čte balíček qdapTools. Download pomocí download.file() se podařil, lokální soubor vznikl a šel otevřít Wordem. Ale do R načíst nešel.

Balíček RCurl

Balíček RCurl slouží k načítání souborů přímo z webu. Má široké možnosti, my se podíváme jenom na načtení textového souboru. Pozor, textový soubor se načte jako jeden velký element znakového vektoru.

library(RCurl)
## Loading required package: bitops
## 
## Attaching package: 'RCurl'
## The following object is masked from 'package:rJava':
## 
##     clone
 #oho <- getURL(x, userpwd ="login:password", httpauth = 1L)   
 text.v <- getURL(url = "http://www.gutenberg.org/cache/epub/2701/pg2701.txt")
 str(text.v )
##  chr "<U+FEFF>The Project Gutenberg EBook of Moby Dick; or The Whale, by Herman Melville\r\n\r\nThis eBook is for the use of anyone a"| __truncated__