1 Načtení balíčků

Balíčky můžeme načíst pomocí funkce library. Pokud některý z nich nemáte nainstalovaný, můžete jej naistalovat pomocí dialogového okna v RStudiu (vlevo dole přes Packages – Install) nebo pomocí funkce install.packages("nazev_balicku").

# Balíčky
library(tidyverse)
library(readr)
library(readxl)
library(haven)

2 Stažení datasetů z internetu

Pomocí funkce download.file() lze stáhnout soubory z internetu, a to následujícím způsobem. Stačí do ní vložit dva argumenty: html adresu souboru a cílovou adresu pro uložení souboru (i se jménem a příponou nově vytvořeného souboru)

download.file(
  url = "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/swimming_pools.csv",
  destfile = "data/swimming_pools.csv",
  method = "curl"
)

Takto bychom mohli stahovat soubory po jednom, ale bylo by to zbytečně pracné a náš kód by zahrnoval hodně opakování. I když trochu předbíháme, můžeme si vyzkoušet výhody iterace. Nejprve si vytvoříme vektor s jen názvy souborů (ale včetně přípon)

files <-  c("NfCCsousyp.csv", "NFC.xlsx", "lem.sav", "Yan_et_al.Rdata", 
            "eukids.rds", "titanic.sav", "titanic.rds", "games_sales.rds", 
            "eukids.sav", "rses_data.sav", "hotdogs_1.txt", "hotdogs_2.txt", 
            "swimming_pools.csv", "latitude.xlsx", "international.sav")

Poté si vytvoříme seznam url adres. Protože všechny datasety jsou ve stejné složce, začínají všechny adresy stejně:

https://is.muni.cz/auth/el/fss/podzim2022/PSYn5320/um/datasets/

Kompletní url adresy vytvořím pomocí funkce str_c(), která kombinuje prvky vektorů (pokud má jeden z prvků délku = 1, dojde k recyklaci tohoto prvku)

urls <- str_c(
  "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/",
  files
)
urls
#>  [1] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/NfCCsousyp.csv"    
#>  [2] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/NFC.xlsx"          
#>  [3] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/lem.sav"           
#>  [4] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/Yan_et_al.Rdata"   
#>  [5] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/eukids.rds"        
#>  [6] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/titanic.sav"       
#>  [7] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/titanic.rds"       
#>  [8] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/games_sales.rds"   
#>  [9] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/eukids.sav"        
#> [10] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/rses_data.sav"     
#> [11] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/hotdogs_1.txt"     
#> [12] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/hotdogs_2.txt"     
#> [13] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/swimming_pools.csv"
#> [14] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/latitude.xlsx"     
#> [15] "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/international.sav"

Podobně si vytvořím vektor s destinacemi pro ukládané soubory. Zde je nutné pracovat v rámci RProjektu, abyste mohli specifikovat jen cílovou podsložku (např. data) v rámci pracovního adresáře RProjektu (jinak by bylo nutné vypset kompletní cestu k souboru stylem C:/kompletní/cesta/pro/uložení/souboru)

# Vektor s cílovou složkou včetně názvů nových souborů
dest <- str_c("data/", files)
dest
#>  [1] "data/NfCCsousyp.csv"     "data/NFC.xlsx"          
#>  [3] "data/lem.sav"            "data/Yan_et_al.Rdata"   
#>  [5] "data/eukids.rds"         "data/titanic.sav"       
#>  [7] "data/titanic.rds"        "data/games_sales.rds"   
#>  [9] "data/eukids.sav"         "data/rses_data.sav"     
#> [11] "data/hotdogs_1.txt"      "data/hotdogs_2.txt"     
#> [13] "data/swimming_pools.csv" "data/latitude.xlsx"     
#> [15] "data/international.sav"

Pomocí funkce walk2() pak iterativně uplatníme funkci download.file(). Aby následující kód fungoval, je nutné nejdříve vytvořit v aktuálním pracovním adresáři (což by měl být také adresář vašeho RProjektu) podsložku data.

walk2(
  urls, # 1. argument: Vektor s url adresami stahovaných souborů
  dest, # 2. argument: Vektor s cílovými adresáři nových souborů
  ~download.file(
    url = .x, # placeholder pro 1. argument
    destfile = .y, # placeholder pro 1. argument
    method = "curl"
  )
)

Takto vlastně iterativně využijeme funkce download.file(), nejdříve do ní budou vloženy jako argumenty první z prvků vektorů urls a dest, poté druhé z prvků obou vektorů atd. (dokud nebudou použity všechny prvky).

3 Import flat files

Flat files jsou jednoduché databázové soubory uložené ve formě prostého textu Zkuste si nejdříve soubory swimming_pools.csv, hotdogs_1.txt a hotdogs_2.txt otevřít v notepadu nebo podobném textovém editoru

Funkce read_csv() se používá, pokud jsou hodnoty oddělené čárkou (a desetinná místa tečkou). Zkratka csv znamená comma separated values.

pools <- read_csv("data/swimming_pools.csv") 
#> Rows: 253 Columns: 8
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: ","
#> chr (7): Name, Address, Suburb, State, Business Category, LGA, Region
#> dbl (1): Postcode
#> 
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
glimpse(pools)
#> Rows: 253
#> Columns: 8
#> $ Name                <chr> "Aquabear AUSSI Masters", "Bairnsdale Amateur Swim…
#> $ Address             <chr> "La Trobe University Sports Centre", NA, "PO Box 1…
#> $ Suburb              <chr> "Bundoora", "Bairnsdale", "Ballarat", "Glenroy", "…
#> $ Postcode            <dbl> 3083, 3875, 3354, 3046, 3083, 3064, 3108, 3095, 31…
#> $ State               <chr> "VIC", "VIC", "VIC", "VIC", "VIC", "VIC", "VIC", "…
#> $ `Business Category` <chr> "Swimming Club", "Swimming Club", "Swimming Club",…
#> $ LGA                 <chr> "Whittlesea,Darebin,Banyule", "East Gippsland", "B…
#> $ Region              <chr> "North and West Metropolitan Region", "Gippsland",…

V českém prostředí se častěji oddělují desetinná místa čárkou, takže se jako oddělovat hodnot používá místo čárky středník (;). V případě, že se setkáme s takovýmto souborem, můžeme použít funkci read_csv2(), která má defaultně nastaven středník jako oddělovač hodnot a čárku jako oddělovač desetinných míst.

Funkce read_csv()`` (ale i ostatní funkce z balíčku readr) má mnoho dalších argumentů (Pro nápovědu k určité funkci stačí napsat?název_funkcenebohelp(název_funkce)`). Například si můžeme manuálně specifikovat typy sloupců pomocí argumentu col_types. Snadnější je to pomocí řetězce písmen takto:

pools <- read_csv(
  "data/swimming_pools.csv",
  col_types = "cccifccc" # typy sloupců
)

glimpse(pools)
#> Rows: 253
#> Columns: 8
#> $ Name                <chr> "Aquabear AUSSI Masters", "Bairnsdale Amateur Swim…
#> $ Address             <chr> "La Trobe University Sports Centre", NA, "PO Box 1…
#> $ Suburb              <chr> "Bundoora", "Bairnsdale", "Ballarat", "Glenroy", "…
#> $ Postcode            <int> 3083, 3875, 3354, 3046, 3083, 3064, 3108, 3095, 31…
#> $ State               <fct> VIC, VIC, VIC, VIC, VIC, VIC, VIC, VIC, VIC, VIC, …
#> $ `Business Category` <chr> "Swimming Club", "Swimming Club", "Swimming Club",…
#> $ LGA                 <chr> "Whittlesea,Darebin,Banyule", "East Gippsland", "B…
#> $ Region              <chr> "North and West Metropolitan Region", "Gippsland",…

Ale bezpečnější (méně nýchylné k nějaké chybě) je to takto:

pools <- read_csv(
  "data/swimming_pools.csv",
  col_types = cols(
    Name = col_character(),
    Address = col_character(),
    Suburb = col_character(),
    Postcode = col_integer(),
    State = col_factor(),
    `Business Category` = col_character(),
    LGA = col_character(),
    Region = col_character()
  )
)

glimpse(pools)
#> Rows: 253
#> Columns: 8
#> $ Name                <chr> "Aquabear AUSSI Masters", "Bairnsdale Amateur Swim…
#> $ Address             <chr> "La Trobe University Sports Centre", NA, "PO Box 1…
#> $ Suburb              <chr> "Bundoora", "Bairnsdale", "Ballarat", "Glenroy", "…
#> $ Postcode            <int> 3083, 3875, 3354, 3046, 3083, 3064, 3108, 3095, 31…
#> $ State               <fct> VIC, VIC, VIC, VIC, VIC, VIC, VIC, VIC, VIC, VIC, …
#> $ `Business Category` <chr> "Swimming Club", "Swimming Club", "Swimming Club",…
#> $ LGA                 <chr> "Whittlesea,Darebin,Banyule", "East Gippsland", "B…
#> $ Region              <chr> "North and West Metropolitan Region", "Gippsland",…

Zde je přehled možných specifikací typů sloupců:

Typ Delší zápis Kratší zápis
character col_character() c
integer col_integer() i
number col_number() n
double col_double() d
logical col_logical() l
factor col_factor() f
date col_date() D
datetime col_datetime() T
time col_time() t
(přeskočit) col_skip() _ nebo -

Dále můžeme argumentem name_repair “opravit” nestandardní názvy proměnných

pools <- read_csv(
  "data/swimming_pools.csv",
  col_types = "cccifccc",
  name_repair = "universal"
)
#> New names:
#> • `Business Category` -> `Business.Category`

glimpse(pools)
#> Rows: 253
#> Columns: 8
#> $ Name              <chr> "Aquabear AUSSI Masters", "Bairnsdale Amateur Swimmi…
#> $ Address           <chr> "La Trobe University Sports Centre", NA, "PO Box 170…
#> $ Suburb            <chr> "Bundoora", "Bairnsdale", "Ballarat", "Glenroy", "Bu…
#> $ Postcode          <int> 3083, 3875, 3354, 3046, 3083, 3064, 3108, 3095, 3199…
#> $ State             <fct> VIC, VIC, VIC, VIC, VIC, VIC, VIC, VIC, VIC, VIC, VI…
#> $ Business.Category <chr> "Swimming Club", "Swimming Club", "Swimming Club", "…
#> $ LGA               <chr> "Whittlesea,Darebin,Banyule", "East Gippsland", "Bal…
#> $ Region            <chr> "North and West Metropolitan Region", "Gippsland", "…

Nebo specifikovat názvy proměnných (sloupců) ručně pomocí argumentu col_names

pools <- read_csv(
  "data/swimming_pools.csv",
  col_types = "cccifccc",
  skip = 1,
  col_names = c("name", "address", "suburb", "postcode", "state",
                "business_cat", "lga", "region")
)

glimpse(pools)
#> Rows: 253
#> Columns: 8
#> $ name         <chr> "Aquabear AUSSI Masters", "Bairnsdale Amateur Swimming Cl…
#> $ address      <chr> "La Trobe University Sports Centre", NA, "PO Box 1709", "…
#> $ suburb       <chr> "Bundoora", "Bairnsdale", "Ballarat", "Glenroy", "Bundoor…
#> $ postcode     <int> 3083, 3875, 3354, 3046, 3083, 3064, 3108, 3095, 3199, 322…
#> $ state        <fct> VIC, VIC, VIC, VIC, VIC, VIC, VIC, VIC, VIC, VIC, VIC, VI…
#> $ business_cat <chr> "Swimming Club", "Swimming Club", "Swimming Club", "Swimm…
#> $ lga          <chr> "Whittlesea,Darebin,Banyule", "East Gippsland", "Ballarat…
#> $ region       <chr> "North and West Metropolitan Region", "Gippsland", "Gramp…

Podívejte se sami na nápovědu k funkci read_csv() pomocí příkazu?read_csv nebo help(read_csv), které další argumenty má tato funkce.

Pro úplnost je ještě nutné dodat, že kromě stažení souboru na pevný disk a jeho následného importu můžeme některé soubory z intenetu importovat rovnou.

pools2 <- read_csv(
  "https://is.muni.cz/el/fss/podzim2022/PSYn5320/um/datasets/swimming_pools.csv"
)
#> Rows: 253 Columns: 8
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: ","
#> chr (7): Name, Address, Suburb, State, Business Category, LGA, Region
#> dbl (1): Postcode
#> 
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
glimpse(pools2)
#> Rows: 253
#> Columns: 8
#> $ Name                <chr> "Aquabear AUSSI Masters", "Bairnsdale Amateur Swim…
#> $ Address             <chr> "La Trobe University Sports Centre", NA, "PO Box 1…
#> $ Suburb              <chr> "Bundoora", "Bairnsdale", "Ballarat", "Glenroy", "…
#> $ Postcode            <dbl> 3083, 3875, 3354, 3046, 3083, 3064, 3108, 3095, 31…
#> $ State               <chr> "VIC", "VIC", "VIC", "VIC", "VIC", "VIC", "VIC", "…
#> $ `Business Category` <chr> "Swimming Club", "Swimming Club", "Swimming Club",…
#> $ LGA                 <chr> "Whittlesea,Darebin,Banyule", "East Gippsland", "B…
#> $ Region              <chr> "North and West Metropolitan Region", "Gippsland",…

Pokud jsou hodnoty oddělené tabulátory, můžeme použít funkci read_tsv (tab separated values)

hotdogs_1 <- read_tsv("data/hotdogs_1.txt")
#> Rows: 54 Columns: 3
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: "\t"
#> chr (1): Type
#> dbl (2): Calories, Sodium
#> 
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

hotdogs_1
#> # A tibble: 54 × 3
#>    Type  Calories Sodium
#>    <chr>    <dbl>  <dbl>
#>  1 Beef       186    495
#>  2 Beef       181    477
#>  3 Beef       176    425
#>  4 Beef       149    322
#>  5 Beef       184    482
#>  6 Beef       190    587
#>  7 Beef       158    370
#>  8 Beef       139    322
#>  9 Beef       175    479
#> 10 Beef       148    375
#> # … with 44 more rows

hotdogs_1 <- read_tsv("data/hotdogs_1.txt", 
                      col_types = "fii") # Opět můžeme změnit typ sloupců

hotdogs_1
#> # A tibble: 54 × 3
#>    Type  Calories Sodium
#>    <fct>    <int>  <int>
#>  1 Beef       186    495
#>  2 Beef       181    477
#>  3 Beef       176    425
#>  4 Beef       149    322
#>  5 Beef       184    482
#>  6 Beef       190    587
#>  7 Beef       158    370
#>  8 Beef       139    322
#>  9 Beef       175    479
#> 10 Beef       148    375
#> # … with 44 more rows

Co je špatně při tomto importu dat? Zkuste to napravit.

hotdogs_2 <- read_tsv("data/hotdogs_2.txt")
#> Rows: 53 Columns: 3
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: "\t"
#> chr (1): Beef
#> dbl (2): 186, 495
#> 
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

hotdogs_2
#> # A tibble: 53 × 3
#>    Beef  `186` `495`
#>    <chr> <dbl> <dbl>
#>  1 Beef    181   477
#>  2 Beef    176   425
#>  3 Beef    149   322
#>  4 Beef    184   482
#>  5 Beef    190   587
#>  6 Beef    158   370
#>  7 Beef    139   322
#>  8 Beef    175   479
#>  9 Beef    148   375
#> 10 Beef    152   330
#> # … with 43 more rows

glimpse(hotdogs_2)
#> Rows: 53
#> Columns: 3
#> $ Beef  <chr> "Beef", "Beef", "Beef", "Beef", "Beef", "Beef", "Beef", "Beef", …
#> $ `186` <dbl> 181, 176, 149, 184, 190, 158, 139, 175, 148, 152, 111, 141, 153,…
#> $ `495` <dbl> 477, 425, 322, 482, 587, 370, 322, 479, 375, 330, 300, 386, 401,…

Pomocí funkcí slice_min() a slice_max() můžete vybrat určitý počet pozorování s nejmenšími nebo největšími hodnotami zvolené proměnné

  • Nejprve se podívejte na nápovědu k těmto funkcím.
  • Z datasetu hotdogs_1 pak vyberte hotdog s nejmenším množstvím kalorií pomocí funkce slice_min(); a pomocí funkce slice_max() vyberte hotdog s největším množtsvím sodíku.

Nejobecnější je funkce read_delim(), kde si můžete sami specifikovat oddělovač hodnot argumentem delim

read_delim("data/swimming_pools.csv", delim = ",") # čárka
#> Rows: 253 Columns: 8
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: ","
#> chr (7): Name, Address, Suburb, State, Business Category, LGA, Region
#> dbl (1): Postcode
#> 
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#> # A tibble: 253 × 8
#>    Name                        Address Suburb Postc…¹ State Busin…² LGA   Region
#>    <chr>                       <chr>   <chr>    <dbl> <chr> <chr>   <chr> <chr> 
#>  1 Aquabear AUSSI Masters      La Tro… Bundo…    3083 VIC   Swimmi… Whit… North…
#>  2 Bairnsdale Amateur Swimmin… <NA>    Bairn…    3875 VIC   Swimmi… East… Gipps…
#>  3 Ballarat GCO Swim Club      PO Box… Balla…    3354 VIC   Swimmi… Ball… Gramp…
#>  4 Broadmeadows Swimming Clubs PO Box… Glenr…    3046 VIC   Swimmi… More… North…
#>  5 Bundoora Torpedoes Swim Cl… <NA>    Bundo…    3083 VIC   Swimmi… Whit… North…
#>  6 Craigieburn Amateur Swimmi… PO Box… Craig…    3064 VIC   Swimmi… Whit… North…
#>  7 Doncaster Templestowe Amat… Aquare… Donca…    3108 VIC   Swimmi… Mann… Easte…
#>  8 Eltham Swimming School      1441 M… Eltha…    3095 VIC   Swimmi… Nill… North…
#>  9 Frankston Peninsula AUSSI … Jubile… Frank…    3199 VIC   Swimmi… Fran… South…
#> 10 Geelong Swimming Club       Park C… Geelo…    3220 VIC   Swimmi… Grea… Barwo…
#> # … with 243 more rows, and abbreviated variable names ¹​Postcode,
#> #   ²​`Business Category`

read_delim("data/hotdogs_1.txt", delim = "\t") # tabulátor se značí takto
#> Rows: 54 Columns: 3
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: "\t"
#> chr (1): Type
#> dbl (2): Calories, Sodium
#> 
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#> # A tibble: 54 × 3
#>    Type  Calories Sodium
#>    <chr>    <dbl>  <dbl>
#>  1 Beef       186    495
#>  2 Beef       181    477
#>  3 Beef       176    425
#>  4 Beef       149    322
#>  5 Beef       184    482
#>  6 Beef       190    587
#>  7 Beef       158    370
#>  8 Beef       139    322
#>  9 Beef       175    479
#> 10 Beef       148    375
#> # … with 44 more rows

Argumentem na také můžete změnit, jaké hodnoty se mají považovat za chybějící defaultně je na = c("", "NA"), čili prázdné buňky a písmena NA

read_delim("data/hotdogs_1.txt", delim = "\t", na = c("186", "495"))
#> Rows: 54 Columns: 3
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: "\t"
#> chr (1): Type
#> dbl (2): Calories, Sodium
#> 
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#> # A tibble: 54 × 3
#>    Type  Calories Sodium
#>    <chr>    <dbl>  <dbl>
#>  1 Beef        NA     NA
#>  2 Beef       181    477
#>  3 Beef       176    425
#>  4 Beef       149    322
#>  5 Beef       184    482
#>  6 Beef       190    587
#>  7 Beef       158    370
#>  8 Beef       139    322
#>  9 Beef       175    479
#> 10 Beef       148    375
#> # … with 44 more rows

4 Import dat z Excelu

K importu dat z Excelu slouží dva základní příkazy:

  • excel_sheets() pro Výčet listů (sheets) v daném excelovském (.xls, .xlsx) souboru
  • read_excel() pro vlastná načtení souboru excelovského formátu

Použijte funkci excel_sheets() na soubor latitude.xlsx (nezapomeňte upřesnit i podsložku) a zjistěte, kolik sheets má daný sešit a jak se jmenují. Můžete si daný soubor i rovnou otevřít v Excelu.

excel_sheets("data/latitude.xlsx")
#> [1] "1700"   "1900"   "1900_N"

Funkce read_excel() se používá tímto způsobem

# Defaultně importuje první sheet
latitude_1 <- read_excel("data/latitude.xlsx") # sheets lze vybrat jménem 
latitude_1
#> # A tibble: 246 × 2
#>    country               latitude_1700
#>    <chr>                         <dbl>
#>  1 Afghanistan                   34.6 
#>  2 Akrotiri and Dhekelia         34.6 
#>  3 Albania                       41.3 
#>  4 Algeria                       36.7 
#>  5 American Samoa               -14.3 
#>  6 Andorra                       42.5 
#>  7 Angola                        -8.84
#>  8 Anguilla                      18.2 
#>  9 Antigua and Barbuda           17.1 
#> 10 Argentina                    -36.7 
#> # … with 236 more rows

# Sheet pro import lze samozřejmě změnit
# Buď stanovením jeho pořadí, nebo pomocí názvu
latitude_2 <- read_excel("data/latitude.xlsx", 
                         sheet = 2) # druhý sheet
latitude_2
#> # A tibble: 246 × 2
#>    country               latitude_1900
#>    <chr>                         <dbl>
#>  1 Afghanistan                   34.6 
#>  2 Akrotiri and Dhekelia         34.6 
#>  3 Albania                       41.3 
#>  4 Algeria                       36.7 
#>  5 American Samoa               -14.3 
#>  6 Andorra                       42.5 
#>  7 Angola                        -8.84
#>  8 Anguilla                      18.2 
#>  9 Antigua and Barbuda           17.1 
#> 10 Argentina                    -36.7 
#> # … with 236 more rows

# Nebo pomocí názvu
latitude_2 <- read_excel("data/latitude.xlsx", 
                         sheet = "1900") # import druhého listu ze sešitu
latitude_2
#> # A tibble: 246 × 2
#>    country               latitude_1900
#>    <chr>                         <dbl>
#>  1 Afghanistan                   34.6 
#>  2 Akrotiri and Dhekelia         34.6 
#>  3 Albania                       41.3 
#>  4 Algeria                       36.7 
#>  5 American Samoa               -14.3 
#>  6 Andorra                       42.5 
#>  7 Angola                        -8.84
#>  8 Anguilla                      18.2 
#>  9 Antigua and Barbuda           17.1 
#> 10 Argentina                    -36.7 
#> # … with 236 more rows

Podobně jako funkce z balíčku readr má funkce read_excel() mnoho jiných argumentů. Opět si můžeme pohrát s argumentem col_names, protože třetí sheet latitude.xlsx nemá jména.

# Takhle říkáme, že původní dataset nemá názvy sloupců 
# a ať je R vygeneruje automaticky
latitude_3 <-  read_excel("data/latitude.xlsx", 
                          sheet = 3, 
                          col_names = FALSE) 
#> New names:
#> • `` -> `...1`
#> • `` -> `...2`
latitude_3
#> # A tibble: 246 × 2
#>    ...1                    ...2
#>    <chr>                  <dbl>
#>  1 Afghanistan            34.6 
#>  2 Akrotiri and Dhekelia  34.6 
#>  3 Albania                41.3 
#>  4 Algeria                36.7 
#>  5 American Samoa        -14.3 
#>  6 Andorra                42.5 
#>  7 Angola                 -8.84
#>  8 Anguilla               18.2 
#>  9 Antigua and Barbuda    17.1 
#> 10 Argentina             -36.7 
#> # … with 236 more rows

# Takhle říkáme, že původní dataset nemá názvy sloupců 
# a že je chceme nastavit ručně
latitude_3 <- read_excel("data/latitude.xlsx", 
                        sheet = 3, 
                        col_names = c("country", "latitude"))
latitude_3
#> # A tibble: 246 × 2
#>    country               latitude
#>    <chr>                    <dbl>
#>  1 Afghanistan              34.6 
#>  2 Akrotiri and Dhekelia    34.6 
#>  3 Albania                  41.3 
#>  4 Algeria                  36.7 
#>  5 American Samoa          -14.3 
#>  6 Andorra                  42.5 
#>  7 Angola                   -8.84
#>  8 Anguilla                 18.2 
#>  9 Antigua and Barbuda      17.1 
#> 10 Argentina               -36.7 
#> # … with 236 more rows
# Což je lepší, než mít nicneříkající písmena

Zkuste na dataframy latitude_3 a latitude_4 použít funkci summary()

Další argument funkce read_excel(), který se může hodit, je argument skip. Pomocí tohoto argumentu můžeme specifikovat, kolik řádků se má při importu přeskočit.

read_excel("data/latitude.xlsx") |> 
  print(n = 20)
#> # A tibble: 246 × 2
#>    country               latitude_1700
#>    <chr>                         <dbl>
#>  1 Afghanistan                   34.6 
#>  2 Akrotiri and Dhekelia         34.6 
#>  3 Albania                       41.3 
#>  4 Algeria                       36.7 
#>  5 American Samoa               -14.3 
#>  6 Andorra                       42.5 
#>  7 Angola                        -8.84
#>  8 Anguilla                      18.2 
#>  9 Antigua and Barbuda           17.1 
#> 10 Argentina                    -36.7 
#> 11 Armenia                       40.3 
#> 12 Aruba                         12.5 
#> 13 Australia                    -32.2 
#> 14 Austria                       48.2 
#> 15 Azerbaijan                    40.4 
#> 16 Bahamas                       24.7 
#> 17 Bahrain                       26.0 
#> 18 Bangladesh                    23.9 
#> 19 Barbados                      13.2 
#> 20 Belarus                       53.5 
#> # … with 226 more rows

read_excel("data/latitude.xlsx", 
           skip = 15) # přeskočit prvních patnáct řádků
#> # A tibble: 231 × 2
#>    Azerbaijan `40.351999999999997`
#>    <chr>                     <dbl>
#>  1 Bahamas                   24.7 
#>  2 Bahrain                   26.0 
#>  3 Bangladesh                23.9 
#>  4 Barbados                  13.2 
#>  5 Belarus                   53.5 
#>  6 Belgium                   50.8 
#>  7 Belize                    17.8 
#>  8 Benin                      6.36
#>  9 Bermuda                   32.2 
#> 10 Bhutan                    27.5 
#> # … with 221 more rows

# Protože se přeskočí i řádek s názvy sloupců, je potřeba doplnit ručně
read_excel("data/latitude.xlsx", 
           skip = 15, # přeskočit prvních patnáct řádků
           col_names = c("country", "latitude_1900")) # doplnit názvy sloupců
#> # A tibble: 232 × 2
#>    country    latitude_1900
#>    <chr>              <dbl>
#>  1 Azerbaijan         40.4 
#>  2 Bahamas            24.7 
#>  3 Bahrain            26.0 
#>  4 Bangladesh         23.9 
#>  5 Barbados           13.2 
#>  6 Belarus            53.5 
#>  7 Belgium            50.8 
#>  8 Belize             17.8 
#>  9 Benin               6.36
#> 10 Bermuda            32.2 
#> # … with 222 more rows

Mezi další užitečné argumenty funkce read_excel() patří například:

  • range: Rozsah buněk, které se mají importovat, tak jak jej zapisujeme v Excelu, např. “B3:D87” nebo i s odkazem na sheet, např. “Budget!B2:G14”. Tento argument má přednost před ostatními argumenty upravujícími rozsah importu dat.
  • n_max: Maximální počet importovaných řádků.
  • trim_ws: Smazat bílá místa (s mezerníky) před hodnotami? (TRUE/FALSE)
  • na: které hodnoty interpretovat jako missing values? Defaultně jen prázdné buňky (““).

Pokud chceme spojit více datasetů dohromady, můžeme k tomu použít funkci full_join(). Ta se spojtí sloupce obou datasetů a zachová všechny řádky obou datasetů. Používá se takto následovně. Jako první dva argumenty uvedeme slučované dataframy. Argumentem by pak specifikujeme, která proměnná jedinečně identifikuje jednotlivé řádky (případy), aby R vědělo, které řádky patří k sobě a mohlo dataframy spojit.

latitude_all <- full_join(
  latitude_1, latitude_2,
  by = "country" # jedinečný identifikátor řádků
)
latitude_all
#> # A tibble: 246 × 3
#>    country               latitude_1700 latitude_1900
#>    <chr>                         <dbl>         <dbl>
#>  1 Afghanistan                   34.6          34.6 
#>  2 Akrotiri and Dhekelia         34.6          34.6 
#>  3 Albania                       41.3          41.3 
#>  4 Algeria                       36.7          36.7 
#>  5 American Samoa               -14.3         -14.3 
#>  6 Andorra                       42.5          42.5 
#>  7 Angola                        -8.84         -8.84
#>  8 Anguilla                      18.2          18.2 
#>  9 Antigua and Barbuda           17.1          17.1 
#> 10 Argentina                    -36.7         -36.7 
#> # … with 236 more rows

Konečně pokud chceme uložit data ve formátu .csv, který lze otevřít i v Excelu. můžeme k tomu použít funkci write_excel_csv2()

write_excel_csv2(latitude_all, # dataframe
                 file = "data/latitude_all.csv") # vytvořený souboru

5 Import dat z SPSS

K importu dat z SPSS můžeme použít balíček haven. Ten obsahuje intuitivně nazvanou funkci read_spss().

# Import dat z SPSS
international <- read_spss("data/international.sav")
glimpse(international) # vidíme, že proměnná continent obsahuje numerické hodnoty
#> Rows: 20
#> Columns: 7
#> $ id       <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18…
#> $ country  <chr> "Argentina", "Benin", "Burundi", "Chile", "Dominican Republic…
#> $ contint  <dbl+lbl> 2, 1, 1, 2, 2, 2, 1, 4, 3, 3, 4, 1, 1, 1, 1, 1, 1, 4, 3, 2
#> $ m_illit  <dbl> 3.0, 45.2, 33.2, 4.2, 12.0, 17.6, 37.1, 0.6, 16.5, 23.0, …
#> $ f_illit  <dbl> 3.0, 74.5, 48.1, 4.4, 12.7, 22.9, 54.3, 0.7, 29.6, 39.1, 6.6,…
#> $ lifeexpt <dbl> 16, 7, 5, 14, 12, 11, 7, 15, 11, 9, 14, 7, 9, 12, 6, 7, 10, 1…
#> $ gdp      <dbl> 3375, 521, 86, 4523, 2408, 2302, 354, 8384, 2079, 361, 11790,…
international$contint
#> <labelled<double>[20]>: Continent
#>  [1] 2 1 1 2 2 2 1 4 3 3 4 1 1 1 1 1 1 4 3 2
#> 
#> Labels:
#>  value    label
#>      1   Africa
#>      2 Americas
#>      3     Asia
#>      4   Europe

Defaultně se kategorické proměnné z SPSS načtou jako číselné vektory, které ale mají atribut labels, což je pojmenovaný číselný vektor. Jeho hodnoty jsou numerickými kódy jednotlivých úrovní a názvy prvků jsou labely pro jednotlivé úrovně.

attributes(international$contint)
#> $label
#> [1] "Continent"
#> 
#> $format.spss
#> [1] "F8.0"
#> 
#> $class
#> [1] "haven_labelled" "vctrs_vctr"     "double"        
#> 
#> $labels
#>   Africa Americas     Asia   Europe 
#>        1        2        3        4

ke konverzi dané proměnné na factor nabízí balíček haven funkci as_factor. Argumentem levels pouze nastavujeme labely úrovní faktoru.

x <- as_factor(international$contint, levels = "labels") # Defaultní chování
y <- as_factor(international$contint, levels = "values")
z <- as_factor(international$contint, levels = "both")

levels(x)
#> [1] "Africa"   "Americas" "Asia"     "Europe"
levels(y)
#> [1] "1" "2" "3" "4"
levels(z)
#> [1] "[1] Africa"   "[2] Americas" "[3] Asia"     "[4] Europe"

# Konverze sloupce v samotném dataframu 
international$contint <- as_factor(international$contint, levels = "labels")
glimpse(international)
#> Rows: 20
#> Columns: 7
#> $ id       <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18…
#> $ country  <chr> "Argentina", "Benin", "Burundi", "Chile", "Dominican Republic…
#> $ contint  <fct> Americas, Africa, Africa, Americas, Americas, Americas, Afric…
#> $ m_illit  <dbl> 3.0, 45.2, 33.2, 4.2, 12.0, 17.6, 37.1, 0.6, 16.5, 23.0, 8.2,…
#> $ f_illit  <dbl> 3.0, 74.5, 48.1, 4.4, 12.7, 22.9, 54.3, 0.7, 29.6, 39.1, 6.6,…
#> $ lifeexpt <dbl> 16, 7, 5, 14, 12, 11, 7, 15, 11, 9, 14, 7, 9, 12, 6, 7, 10, 1…
#> $ gdp      <dbl> 3375, 521, 86, 4523, 2408, 2302, 354, 8384, 2079, 361, 11790,…

6 Export dat

Do většiny funkcí pro export dat se jako první argument uvádí datový objekt, který chceme exportovat. Argumentem file pak definujeme nově vytvořený soubor.

# Uložení dat ve formátu .sav (nativní formát SPSS)
write_sav(international, 
          path = "data/international_new.sav")

# Do formátu .csv, který otevře většina programů včetně Excelu
# (ale připravíme se tím o metadata)
write_csv2(international, 
           file = "data/international_new.csv")

# Uložení do nativního R formátu
write_rds(international, 
          file = "data/international_new.rds")

Pokud chceme uložit jen jeden datový objekt v nativním R-formátu (.rds), můžeme použít funkci write_rds(). Nepřijdeme tím o metadata a má to tu výhodu, že si můžeme definovat jméno nového objektu, pokud budeme data opětovně načítat do R.

Kdybychom chtěli uložit více objektů, můžeme k tomu použít funkci save(). Stačí vypsat názvy všech objektů, které chceme uložit (oddlené čárkou) a argumentem file specifikovat, kam se data mají uložit.

# Formát RData ukládá i více objektů
save(pools, hotdogs_1,
     file = "data/pools_and_hotdogs.RData")

Kdybychom chtěli uložit všechny objekty v global environment, můžeme použít funkci save_image().

save.image(file = "data/all_objects.RData")

Ta je ale vystavěna kolem funkce save(). Stejně bychom všechny objekty v global environment mohlu uložit takto, v kombinaci s funkcí ls(), která defaultně vrací jména všech objektů v globálním prostředí.

# Funkce ls() vrací character vector s názvy objektů v globálním prostředí
ls()
#>  [1] "dest"          "files"         "hotdogs_1"     "hotdogs_2"    
#>  [5] "international" "latitude_1"    "latitude_2"    "latitude_3"   
#>  [9] "latitude_all"  "pools"         "pools2"        "urls"         
#> [13] "x"             "y"             "z"

# Když výstup této funkce vložíme jako argument "list" do funkce save,
# uložíme všechny objekty
save(list = ls(),
     file = "data/all_objects.RData")

Pokud chceme odstranit objekty z globálního prostředí, můžeme k tomu použít funkci rm(). Stačí do ní vepsat jména všech objektů, které chceme odstranit.

# Odstranění vybraných objektů z globálního prostředí
rm(hotdogs_1, hotdogs_2, pools)
# Odstranění všech objektů z globálního prostředí
rm(list = ls())

Pokud máme data uložena ve nativním formátu .rds, můžeme si je načíst pomocí funkce `read_rds()``a při načtení specifikovat jméno nově vytvořeného objektu v R.

new_name <- read_rds("data/international_new.rds")
new_name
#> # A tibble: 20 × 7
#>       id country              contint  m_illit f_illit lifeexpt   gdp
#>    <dbl> <chr>                <fct>      <dbl>   <dbl>    <dbl> <dbl>
#>  1     1 Argentina            Americas     3       3         16  3375
#>  2     2 Benin                Africa      45.2    74.5        7   521
#>  3     3 Burundi              Africa      33.2    48.1        5    86
#>  4     4 Chile                Americas     4.2     4.4       14  4523
#>  5     5 Dominican Republic   Americas    12      12.7       12  2408
#>  6     6 El Salvador          Americas    17.6    22.9       11  2302
#>  7     7 Ghana                Africa      37.1    54.3        7   354
#>  8     8 Hungary              Europe       0.6     0.7       15  8384
#>  9     9 Iran                 Asia        16.5    29.6       11  2079
#> 10    10 Laos                 Asia        23      39.1        9   361
#> 11    11 Malta                Europe       8.2     6.6       14 11790
#> 12    12 Mauritania           Africa      48.5    68.7        7   381
#> 13    13 Morocco              Africa      36.7    61.7        9  1463
#> 14    14 Namibia              Africa      16.2    17.2       12  2307
#> 15    15 Senegal              Africa      43.9    71.5        6   641
#> 16    16 Sierra Leone         Africa      60.2    79.5        7   197
#> 17    17 Swaziland            Africa      19.6    21.9       10  1653
#> 18    18 Macedonia            Europe       1.8     5.9       12  2225
#> 19    19 United Arab Emirates Asia        24.4    19.3       11 22130
#> 20    20 Uruguay              Americas     2.7     1.9       15  3274

Pokud máme uloženo více datových objektů ve formátu .RData, můžeme si je importovat pomocí funkce load

load("data/pools_and_hotdogs.RData")

7 Práce s balíčky

Někdy se nám můžeme hodit také “vypnutí” (unloading) určitého balíčku (opak toho, co dělá funkce library()). To se dělá pomocí funkce detach("package:jmeno_balicku"), například:

detach("package:readr")
read_csv("data/swimming_pools.csv")
#> Error in read_csv("data/swimming_pools.csv"): could not find function "read_csv"

Nicméně abychom mohli použít funkce nějakého balíčku, nemusíme jej mít načtený pomocí funkce library(), ale můžeme se na určitou funkci z nějakého balíčku odkázat takto ve formě balicek::funkce():

readr::read_csv("data/swimming_pools.csv")
#> Rows: 253 Columns: 8
#> ── Column specification ────────────────────────────────────────────────────────
#> Delimiter: ","
#> chr (7): Name, Address, Suburb, State, Business Category, LGA, Region
#> dbl (1): Postcode
#> 
#> ℹ Use `spec()` to retrieve the full column specification for this data.
#> ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
#> # A tibble: 253 × 8
#>    Name                        Address Suburb Postc…¹ State Busin…² LGA   Region
#>    <chr>                       <chr>   <chr>    <dbl> <chr> <chr>   <chr> <chr> 
#>  1 Aquabear AUSSI Masters      La Tro… Bundo…    3083 VIC   Swimmi… Whit… North…
#>  2 Bairnsdale Amateur Swimmin… <NA>    Bairn…    3875 VIC   Swimmi… East… Gipps…
#>  3 Ballarat GCO Swim Club      PO Box… Balla…    3354 VIC   Swimmi… Ball… Gramp…
#>  4 Broadmeadows Swimming Clubs PO Box… Glenr…    3046 VIC   Swimmi… More… North…
#>  5 Bundoora Torpedoes Swim Cl… <NA>    Bundo…    3083 VIC   Swimmi… Whit… North…
#>  6 Craigieburn Amateur Swimmi… PO Box… Craig…    3064 VIC   Swimmi… Whit… North…
#>  7 Doncaster Templestowe Amat… Aquare… Donca…    3108 VIC   Swimmi… Mann… Easte…
#>  8 Eltham Swimming School      1441 M… Eltha…    3095 VIC   Swimmi… Nill… North…
#>  9 Frankston Peninsula AUSSI … Jubile… Frank…    3199 VIC   Swimmi… Fran… South…
#> 10 Geelong Swimming Club       Park C… Geelo…    3220 VIC   Swimmi… Grea… Barwo…
#> # … with 243 more rows, and abbreviated variable names ¹​Postcode,
#> #   ²​`Business Category`

Tento zápis se hodí i v případě konfliktního názvu funkcí. Kdybychom načetli dva různé balíčky (nejprve balicek1 a poté balicek2) a oba by obsahovaly dvě rozdílné, ale stejně pojmenované funkce (např. fn), pak by defaultně byla použita funkce z později načteného balíčku (balicek2). Proto je lepší se v takovém případě explicitně odkázat na balíček i funkci: balicek1::fn(), nebo balicek2::fn().