5. Darbas su įvairių tipų duomenimis


Šio skyriaus medžiaga vis dar rengiama!
Dabartinė versija skirta tik peržiūrėjimui ir gali smarkiai keistis.












Daugelyje situacijų duomenis galima užrašyti ir nagrinėti kaip reikšmių sekas, kurios padeda atsakyti į mums rūpimus duomenų analizės klausimus.

Žiūrint griežtai, programoje „R“ yra dviejų rūšių vektoriai: to paties duomenų tipo elementų sekos, vadinamos atominiais vektoriais, ir sąrašai, kurie gali būti sudaryti iš skirtingų tipų elementų. Mūsų kursas orientuotas į pradedančiųjų lygio duomenų analizę, todėl, paprastumo dėlei, vartodami terminą „vektorius“, turėsime omenyje to paties duomenų tipo elementų sekas.

Atominis vektorius yra ir pati mažiausia duomenų struktūra programoje: netgi viena reikšmė, tarkim 234, programoje „R“ yra laikoma vektoriumi, susidedančiu iš vieno elemento.

Tad šiame skyriuje panagrinėsime darbo su skaitinių, tekstinių ir kitokių duomenų tipų sekomis specifiką: kaip jas sukurti, apibendrinti, atvaizduoti grafiškai, perskaičiuoti ar transformuoti.

Tikslas – išmokti parengti analizei ir statistiškai apibendrinti duomenis, pateiktus kaip duomenų sekos.

Šio skyriaus uždavinius reikia atlikti iš eilės: dalis uždavinių yra tęstiniai.

Reikiami paketai: DescTools, tidyverse (dplyr, tibble, ggplot2, stringr ir kiti).

5.1 Bendrieji darbo su vektoriais principai

5.1.1 Vektoriaus kūrimas

„R“ vektorius statistikoje atitinka duomenų seką, dar vadinamą duomenų eilute. Kelios reikšmės į vektorių (t. y., į seką) sujungiamos naudojant komandą c() (c nuo žodžio combine arba concatenate). Reikšmės rašomos komandos skliausteliuose ir atskiriamos kableliais (,), pvz.:

c(6, 23, 33, 19)
## [1]  6 23 33 19

Jei tuos pačius skaičius parašysime „R“ konsolėje be komandos c(), „R“ pamanys, kad tai atskiri niekaip nesusiję elementai, nesupras, ką su jais norime daryti, ir praneš, kad tai klaida (Error):

6, 23, 33, 19
## Error: <text>:1:2: unexpected ','
## 1: 6,
##      ^

Komanda c() į vektorių gali sujungti ne tik skaičius, bet ir kitokios tipo duomenų reikšmes:

  • tekstinius kintamuosius (ženklų eilutes):
c("Man", "puikiai", "sekasi", ".")
## [1] "Man"     "puikiai" "sekasi"  "."
  • logines reikšmes (angliškai vadinamos „logical“ arba „boolean“):
c(TRUE, FALSE, FALSE, TRUE, TRUE)
## [1]  TRUE FALSE FALSE  TRUE  TRUE
  • ir kitus.

Programoje „R“ kuriant vektorius, skirtingi skaičiai ar kitokio tipo reikšmės atskiriamos kableliu. O skaičių sveikoji ir dešimtoji dalystašku.

Vektorių galime išsaugoti „R“ atmintyje kaip objektą, naudodami priskyrimo operatorių.

vektorius <- c(11, 20, 33, 45)

Tada jį atspausdinti neišreikštuoju būdu (angl. implicit printing) – tiesiog parašomas objekto pavadinimas:

vektorius
## [1] 11 20 33 45

Jei visą kodo eilutę papildomai apskliaudžiame, rezultatas įprastai taip pat būna atspausdinamas:

(vektorius <- c(11, 20, 33, 45))
## [1] 11 20 33 45

Arba išreikštai (angl. explicit printing) – naudojama funkcija print()):

print(vektorius)
## [1] 11 20 33 45

Yra ir kitų būdų kurti vektorius. Jie įprastai yra specifiški tam tikram duomenų tipui. Juos aptarsime vėliau.

Užduotis 5.1

  1. Sukurkite vektorių iš pateiktų skaičių ir pavadinkite jį seka_1: 1; 10; 100; 1000; 10000.
  2. Vektorių atspausdinkite.
  3. Duoti kelių merginų ūgiai metrais. Pateikite juos kaip duomenų seką merginu_ugiai ir atspausdinkite neišreikštuoju būdu.
Merginų ūgiai (m).
1,671,561,661,59
1,771,711,691,66
1,681,551,701,72

Skirtingų tipų duomenys vienoje sekoje?

Kas atsitiks, jei į vieną seką bandysime sudėti kelių tipų duomenis? „R“ visus elementus pavers į tokį tipą, kuriuo gali būti reprezentuojamos visos reikšmės. Deja, įprastai rezultatas bus netikėtas (ir tikrai ne maloniąja prasme).

Atsargiai – į vieną seką sujungus skirtingus duomenų tipus rezultatas bus netikėtas!

Imkime loginę reikšmę TRUE. Šiame pavyzdyje visos reikšmės bus paverstos į skaičius (TRUE1):

c(TRUE, 1, 0, 1)
## [1] 1 1 0 1

O šiame – į tekstą (TRUE"TRUE"):

c(TRUE, 15, .30, "mama")
## [1] "TRUE" "15"   "0.3"  "mama"

Dar keistesnių dalykų įvyksta dirbant su sudėtiniais duomenų tipais, pvz., faktoriais. Yra tam tikros taisyklės, ką ir kokiais atvejais „R“ padaro. Tačiau pradedantiesiems, nežinantiems šių taisyklių, skirtingų tipų duomenų jungimo į vektorių rekomenduoju vengti.

Užduotis 5.2 Naudodami funkciją class(), patikrinkite, kokiam duomenų tipui („R“ klasei) priklauso sekos c(TRUE, 1, 0, 1) bei c(TRUE, 15, .30, "mama").

5.1.2 Vektoriaus savybių tikrinimas

Aptarsime tik kelias funkcijas, skirtas vektoriaus savybių tikrinimui:

  1. length() – elementų skaičius;
  2. class() – „R“ klasė;
  3. str() ir tibble::glimpse() – struktūra;
  4. attributes() – atributai.

Funkcija length() pateikia vektoriaus ilgį, t. y., suskaičiuoja, iš kelių elementų sudarytas vektorius. Ji bus naudinga, kai turėdami į vektorių surašytas reikšmes norėsime apskaičiuoti imties dydį, įprastai žymimą raide „n“:

vektorius_2 <- c(11, NA, 33, 45)
n <- length(vektorius_2) # Apskaičiuojame ir priskiriame
n                        # Atspausdiname
## [1] 4

Atkreipkite dėmesį į tai, kad skaičiuojamos ir trūkstamos reikšmės.

Bet kokio „R“ objekto, taip pat ir vektoriaus, klasę parodo funkcija class():

class(vektorius_2)
## [1] "numeric"

Mums reiktų žinoti svarbiausius duomenų tipus atitinkančias klases:

  • numeric;
  • integer;
  • character;
  • factor;
  • ordered;
  • logical.

Apie programoje „R“ naudojamus – skyriuje „4.5 [Svarbiausi R duomenų tipai]“.


Vektoriaus struktūrą galime peržiūrėti naudodami funkciją str():

str(vektorius_2)
##  num [1:4] 11 NA 33 45

Arba glimpse() iš paketo tibble() (apie šią funkciją plačiau bus rašoma temoje apie duomenų lenteles):

tibble::glimpse(vektorius_2)
##  num [1:4] 11 NA 33 45

Vektoriams ši funkcija pateikia sutrumpintą „R“ duomenų tipo („R“ klasės) pavadinimą, vektoriaus ilgį (elementų skaičių) ir kelias pirmąsias reikšmes. Pavyzdyje tai:

  • numnumeric – skaitinis duomenų tipas;
  • [1:4] – 4 elementai (nuo 1 iki 4);
  • toliau – 11 NA 33 ir t.t. – kelios pirmosios reikšmės.


Vektoriaus savybes, vadinamas atributais, galima peržiūrėti naudojant funkciją attributes(). Atsakymas NULL rodo, kad objektas atributų neturi:

attributes(vektorius_2)
## NULL

Kategoriniai kintamieji turi atributą, pavadinimu levels – kategorijų pavadinimus.

Užduotis 5.3

  1. Apskaičiuokite anksčiau sukurto vektoriaus seka_1 ilgį.
  2. Programoje „R“ yra apibrėžtas kintamasis letters, kuriame surašytos mažosios angliškos abėcėlės raidės.
    1. Konsolėje atspausdinkite šį kintamąjį, parašydami letters;
    2. Naudodami komandas length() ir str() ištirkite:
      • kiek raidžių yra angliškoje abėcėlėje?
      • koks kintamojo tipas – skaitinis (num) ar kitoks?
  3. Ištirtos 5 gėlės ir duomenys apie jas pateikti po šio uždavinio sąlyga duomenų sekų pavidalu. Kiekvieną iš gėlės savybių (lapu_ilgis ir kt.) ištirkite naudodami funkcijas class(), str() ir attributes() (įvertinkite kiek ir kokių atributų yra).
# Duomenys apie gėles
lapu_ilgis      <- c(1.3, NA, 2.2, 1.1, 1.6)
lapu_skaicius   <- c(24L, 22L, 28L, 25L, 25L)
ziedu_spalva    <- factor(c("raudona", "geltona", "geltona", "balta", "balta"))
kvapo_stiprumas <- ordered(c("silpnas", "vidutinis", "stiprus", "stiprus", NA))
ar_augo_lauke   <- c(FALSE, TRUE, TRUE, FALSE, TRUE)
komentaras      <- c("-", "-", "tirta ryte", "-", "-")

5.1.3 Vektoriaus elementų pasirinkimas

Ši potemė yra susijusi su skyriumi „[Elementų eilės numerių žymėjimas: [ ]]“, nes norėdami pasirinkti tam tikrus vektoriaus elementus (sukurti elementų poaibį, angl. subset), galime naudoti viengubų laužtinių skliaustų operatorių []. Skliaustuose nurodomas teigiamas arba neigiamas skaitinis elemento indeksas (eilės numeris), loginis indeksas arba pavadinimas (jei elementas jį turi).


Pasirinkimas pagal elemento pavadinimą

Iliustracijai naudokime vektorių merginu_ugiai:

merginu_ugiai
##  [1] 1.67 1.56 1.66 1.59 1.77 1.71 1.69 1.66 1.68 1.55 1.70 1.72

Jei elementai turi pavadinimus, juos galime pasirinkti kabutėse nurodydami šiuos pavadinimus.

Naudojant [], elementų pavadinimus reikia pateikti kabutėse.

Sakykime, turime seką su merginų vardais. Naudodamiesi jais, suteikiame reikšmėms pavadinimus. O prieš tai nusistatykime lietuviškąją lokalę, kad galėtume naudoti lietuviškas raides:

Sys.setlocale(locale = "Lithuanian") # Lietuviška lokalė Windows sistemai
vardai <- c("Inga", "Greta", "Jonė", "Justė", "Raimonda", "Laura", "Žaneta",
            "Ingrida", "Kristina", "Toma", "Rima", "Sandra")
names(merginu_ugiai) <- vardai # Suteikiami pavadinimai
merginu_ugiai
##     Inga    Greta     Jonė    Justė Raimonda    Laura   Žaneta  Ingrida 
##     1.67     1.56     1.66     1.59     1.77     1.71     1.69     1.66 
## Kristina     Toma     Rima   Sandra 
##     1.68     1.55     1.70     1.72

Vienoje eilutėje pateiktas elemento pavadinimas (šiuo atveju, merginos vardas), kitoje – elemento reikšmė (šiuo atveju, ūgis).

Dabar ūgius galime sužinoti pagal vardus:

merginu_ugiai["Jonė"]
## Jonė 
## 1.66
merginu_ugiai[c("Jonė", "Laura", "Toma")]
##  Jonė Laura  Toma 
##  1.66  1.71  1.55

Užduotis 5.4

  1. Programoje „R“ yra pavyzdiniai duomenys state.name ir state.area. Pirmajame vektoriuje – JAV valstijų pavadinimai, antrajame – tų valstijų užimamas plotas kvadratinėmis myliomis. Parašykite kodą, kuris atsakytų į klausimus:
    1. Atspausdinkite state.area ir state.name reikšmes.
    2. Kelių valstijų duomenys pateikti?
    3. Pagal pavyzdį, valstijų plotams suteikite pavadinimus.
    4. Tada sudarykite vektorių, kuriame būtų tik šių 4 valstijų plotai: Arizona, New Jersey, Texas, Utah.

Teigiami skaitiniai indeksai

Norėdami pasirinkti elementą, nurodome teigiamą jo indeksą.

Programoje „R“ elementų numeravimas (indeksavimas) prasideda nuo 1.

Tarkime, mus domina antrasis elementas:

merginu_ugiai[2]
## Greta 
##  1.56

Pasirinkime antrą ir ketvirtą (atkreipkite dėmesį į tai, kad nurodant indeksus bus panaudota funkcija c()):

merginu_ugiai[c(2, 4)]
## Greta Justė 
##  1.56  1.59

Dar keli pavyzdžiai:

(skaiciu_seka <- 1:10)
##  [1]  1  2  3  4  5  6  7  8  9 10

skaiciu_seka[2]
## [1] 2

skaiciu_seka[c(2, 4)]
## [1] 2 4

Užduotis 5.5

  1. Naudodami kintamąjį letters atlikite užduotis (parašykite programos kodą):
    1. Nurodykite, kokia 16-toji abėcėlės raidė;
    2. Nurodykite, kokios yra 6, 11, 18 ir 20 abėcėlės raidės.


Neigiami skaitiniai indeksai

Neigiami skaitiniai indeksai panaikina nurodytuosius elementus. Prieš indeksą padedamas „minus“ (-) ženklas:

merginu_ugiai[-2]
##     Inga     Jonė    Justė Raimonda    Laura   Žaneta  Ingrida Kristina 
##     1.67     1.66     1.59     1.77     1.71     1.69     1.66     1.68 
##     Toma     Rima   Sandra 
##     1.55     1.70     1.72
merginu_ugiai[-c(2, 4, 9, 10, 11)]
##     Inga     Jonė Raimonda    Laura   Žaneta  Ingrida   Sandra 
##     1.67     1.66     1.77     1.71     1.69     1.66     1.72

Norėdami panaikinti paskutinį elementą, galime naudoti tokį kodą:

n <- length(merginu_ugiai)
merginu_ugiai[-n]
##     Inga    Greta     Jonė    Justė Raimonda    Laura   Žaneta  Ingrida 
##     1.67     1.56     1.66     1.59     1.77     1.71     1.69     1.66 
## Kristina     Toma     Rima 
##     1.68     1.55     1.70

Čia n yra elementų skaičius, atitinkantis paskutinio elemento eilės numerį: 12.

Dar keli pavyzdžiai:

skaiciu_seka
##  [1]  1  2  3  4  5  6  7  8  9 10

skaiciu_seka[-2]
## [1]  1  3  4  5  6  7  8  9 10

skaiciu_seka[-c(2, 4, 9, 10)]
## [1] 1 3 5 6 7 8

n2 <- length(skaiciu_seka)
skaiciu_seka[-n2]
## [1] 1 2 3 4 5 6 7 8 9

Užduotis 5.6

  1. Naudodami kintamąjį letters atlikite užduotis (parašykite programos kodą):
    1. Pašalinkite 16-tąją abėcėlės raidę;
    2. Pašalinkite 6, 11, 18 ir 20 abėcėlės raides.


Pasirinkimas pagal sąlygas (loginį indeksą)

Kuriant poaibius pagal loginį indeksą pasirenkami tik tie elementai, kuriems loginis indeksas yra TRUE (pav. 5.1). Nagrinėjant šią temą naudinga žinoti, kaip atliekamos pagrindinės palyginimo operacijos (žr. skyriuje „5.5.1 Palyginimo operacijos“).

Loginiai indeksai poaibiams kurti: pasirenkami tik tie elementai, kuriems indeksas yra `TRUE`{.r}.
Iliustracijos šaltinis: [<i class="fa fa-external-link-alt" aria-hidden="true"></i>](https://bookdown.org/ndphillips/YaRrr/logical-indexing.html){target="_blank"}.

Pav. 5.1: Loginiai indeksai poaibiams kurti: pasirenkami tik tie elementai, kuriems indeksas yra TRUE. Iliustracijos šaltinis: .

Sakykime, mus domina tų gėlių, kurios augo lauke, lapų skaičius.

ar_augo_lauke
## [1] FALSE  TRUE  TRUE FALSE  TRUE
lapu_skaicius
## [1] 24 22 28 25 25

Tada naudojame tokį užrašą:

lapu_skaicius[ar_augo_lauke]
## [1] 22 28 25

Be to, abu vektoriai turi būti vienodo ilgio:

length(ar_augo_lauke) == length(lapu_skaicius) # palyginimui naudojame ==, o ne = 
## [1] TRUE

Dabar sakykime, kad mus domina geltonų gėlių lapų skaičius.

ziedu_spalva
## [1] raudona geltona geltona balta   balta  
## Levels: balta geltona raudona

Atlikę palyginimo operaciją, sužinome, kurios gėlės yra geltonos:

ziedu_spalva == "geltona" # TRUE, jei geltona
## [1] FALSE  TRUE  TRUE FALSE FALSE

Palyginimo rezultatą galime išsaugoti kaip objektą, ir jį naudoti reikiamų elementų pasirinkimui net kelis kartus:

ar_geltona <- ziedu_spalva == "geltona"
lapu_skaicius[ar_geltona]
## [1] 22 28

lapu_ilgis[ar_geltona]
## [1]  NA 2.2

Arba palyginimo operaciją galime įrašyti tiesiai tarp laužtinių skliaustų:

lapu_skaicius[ziedu_spalva == "geltona"] # palyginimui naudojame ==, o ne =
## [1] 22 28

Dar keli pavyzdžiai:

skaiciu_seka[skaiciu_seka < 5]
## [1] 1 2 3 4

skaiciu_seka[skaiciu_seka == 5]
## [1] 5

is.na(skaiciu_seka) # Tikrinimas kiekvienam elementui atskirai
##  [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

!is.na(skaiciu_seka)
##  [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE TRUE

Užduotis 5.7

  1. Naudokite uždavinio 5.3 duomenis apie gėles.
    1. Parodykite, kiek lapų (lapu_skaicius) turėjo gėlės, kurių kvapas buvo stiprus (kvapo_stiprumas). Nenustebkite, jei atsakyme atsiras reikšmė NA.
    2. Funkcija !is.na() tikrina, kurios reikšmės yra netrūkstamos (! reiškia NE). Naudodami šią funkciją pasirinkite tik tas gėlių spalvas (ziedu_spalva), jei toms gėlėms yra žinomas lapų ilgis (lapu_ilgis).
  2. Naudodami duomenis state.name ir state.area parašykite kodą, kuris atsakytų į klausimus:
    1. Išvardinkite valstijas, kurių plotas mažesnis už 10000 kvadratinių mylių (pavadinkime jas „mažomis valstijomis“?
    2. Koks mažų valstijų skaičius?

Kai kurie atsakymai pasitikrinimui (jums reikia pateikti sprendimus):

## [1] 28 25 NA
## [1] raudona geltona balta   balta  
## Levels: balta geltona raudona
## [1] "Connecticut"   "Delaware"      "Hawaii"        "Massachusetts"
## [5] "New Hampshire" "New Jersey"    "Rhode Island"  "Vermont"


Specializuotos funkcijos elementams pasirinkti

Norėdami pasirinkti kelis pirmuosius elementus, galime naudoti funkciją head(), kurios argumentas n nurodo, kiek pirmųjų elementų pasirinkti:

head(merginu_ugiai, n = 2)  # palieka pirmus 2 elementus
##  Inga Greta 
##  1.67  1.56

Jei reikia pašalinti kelis paskutinius elementus (ir rodyti pirmuosius), naudojame neigiamą indeksą:

head(merginu_ugiai, n = -8) # pašalina 8 paskutinius elementus
##  Inga Greta  Jonė Justė 
##  1.67  1.56  1.66  1.59

Analogiškai funkcija tail() parodo paskutiniuosius elementus:

tail(merginu_ugiai, n = 3) # palieka 3 paskutinius elementus
##   Toma   Rima Sandra 
##   1.55   1.70   1.72

Arba pašalina pirmuosius (kad būtų rodomi tik paskutiniai):

tail(merginu_ugiai, n = -7) # pašalina 7 pirmuosius elementus
##  Ingrida Kristina     Toma     Rima   Sandra 
##     1.66     1.68     1.55     1.70     1.72

Jei pasirinktus elementus norėsime naudoti toliau, juos priskiriame naujam objektui, pvz.:

ugiai2 <- head(merginu_ugiai, n = 5)
ugiai2_be_vardu <- unname(ugiai2) # pašalina pavadinimus
ugiai2_be_vardu
## [1] 1.67 1.56 1.66 1.59 1.77

Funkcijos head() ir tail() bus naudingos dirbant su duomenų lentelėmis: jos parodys pirmąsias ir paskutines lentelės eilutes.

Dar keli pavyzdžiai:

skaiciu_seka
##  [1]  1  2  3  4  5  6  7  8  9 10

head(skaiciu_seka, n = 2)
## [1] 1 2

head(skaiciu_seka, n = -2)
## [1] 1 2 3 4 5 6 7 8

tail(skaiciu_seka, n = 2)
## [1]  9 10

tail(skaiciu_seka, n = -2)
## [1]  3  4  5  6  7  8  9 10

Užduotis 5.8

  1. Naudodami kintamąjį letters atlikite užduotis (parašykite programos kodą):
    1. Atspausdinkite 10 paskutiniųjų angliškos abėcėlės raidžių;
    2. Pašalinkite 10 paskutiniųjų angliškos abėcėlės raidžių;
    3. Atspausdinkite visas raides, išskyrus pirmą ir paskutinę.

5.1.4 Vektoriaus elementų reikšmių pakeitimas

Vektoriaus reikšmėms pakeisti naudojama operatorių [] ir <- kombinacija. Pasidarykime objekto kopiją, su kuria dirbsime:

ugiai3 <- ugiai2

Galima keisti vieną ar kelias reikšmes naudojant indeksą (eilės numerį):

ugiai3[1] <- 1.90
ugiai3
##     Inga    Greta     Jonė    Justė Raimonda 
##     1.90     1.56     1.66     1.59     1.77
ugiai3[c(1, 3)] <- c(2.00, 2.10)
ugiai3
##     Inga    Greta     Jonė    Justė Raimonda 
##     2.00     1.56     2.10     1.59     1.77

Keitimas pagal loginę sąlygą:

ugiai3[ugiai3 < 1.60] <- NA
ugiai3
##     Inga    Greta     Jonė    Justė Raimonda 
##     2.00       NA     2.10       NA     1.77

Keitimas pagal pavadinimą:

ugiai3["Raimonda"] <- 1.00
ugiai3
##     Inga    Greta     Jonė    Justė Raimonda 
##      2.0       NA      2.1       NA      1.0

Užduotis 5.9

  1. Sudarykite „R“ vektorių, tada visas neigiamas reikšmes duomenų sekoje pakeiskite nuliais:
    • -0.54 0.45 -1.07 0.75 0.88 -0.99 1.24 0.73 0.13 -0.10

5.1.5 Vektorizuotos operacijos

Daugelis operacijų programoje „R“ yra vektorizuotos. T. y., parašius funkciją ar komandą, perskaičiavimas atliekamas kiekvienam elementui atskirai papildomai nerašant sudėtingesnio programos kodo, tokio kaip ciklas (angl., loop). Tai didelis privalumas, supaprastinantis darbą šia programa.

Aritmetiniai (pvz., +, -), palyginimo (pvz., <, >) operatoriai veikia vektorizuotai. Iliustracijai imkime praeituose skyreliuose sukurtus objektus vektorius ir vektorius_2.

vektorius
## [1] 11 20 33 45

vektorius_2
## [1] 11 NA 33 45

Prie kiekvieno vektoriaus elemento pridėkime po 100:

vektorius + 100  # atitinka c(11 + 100, 20 + 100, 33 + 100, 45 + 100)
## [1] 111 120 133 145

Palyginkime, ar reikšmės mažesnės už 21:

vektorius < 21  # atitinka c(11 < 21, 20 < 21, 33 < 21, 45 < 21)
## [1]  TRUE  TRUE FALSE FALSE

Sudėkime kelių vienodo ilgio vektorių pirmuosius, antruosius, trečiuosius ir t.t. elementus:

vektorius + vektorius_2 # atitinka c(11 + 11, 20 + NA, 33 + 33, 45 + 45)
## [1] 22 NA 66 90

Jei dirbame su keliais vektoriais ir vienas iš jų yra trumpesnis, trumpesniojo reikšmės cikliškai naudojamos iš naujo:

vektorius + c(0, 10000) # atitinka c(11 + 0, 20 + 10000, 33 + 0, 45 + 10000)
## [1]    11 10020    33 10045

Toks elgesys dažnai yra nepageidautinas, tad būkite atidūs. Laimei, kai kurios funkcijos, kurias naudosime dirbdami su duomenų lentelėmis kitų užsiėmimų metu, apskritai stabdo skaičiavimus, jei keli vektoriai yra skirtingo ilgio, ir taip apsaugo nuo netikėtų rezultatų.

Kai kurios funkcijos taip pat atlieka veiksmus su kiekvienu elementu atskirai, pvz., logaritmuoja:

log(vektorius) # atitinka c(log(11), log(20), log(33), log(45))
## [1] 2.397895 2.995732 3.496508 3.806662

Arba tikrina, kurios reikšmės yra trūkstamos (žymimos simboliu NA):

is.na(vektorius_2) 
## [1] FALSE  TRUE FALSE FALSE

Jei galite rinktis tarp vektorizuotos ir nevektorizuotos (pvz., savo pačių parašytos) funkcijos, žinokite, kad didelė tikimybė, jog pirmoji veiks efektyviau, nes yra kruopščiai parašyta, išbandyta ir optimizuota.

Užduotis 5.10 Uždaviniuose 5.1 ir 5.2 buvo sukurti keli vektoriai, kuriuos dabar ir panaudosime.

  1. Vektorius merginu_ugiai:
    1. Apskaičiuokite, kiek merginų dalyvavo apklausoje.
    2. Pasirodo, visos merginos buvo apsiavusios aukštakulniais, ūgį padidinančiais 4 cm. Perskaičiuokite, koks tikrasis kiekvienos merginos ūgis. Rezultatą priskirkite kintamajam tikrieji_merginu_ugiai.
  2. Programoje „R“ dešimtainį logaritmą skaičiuoja funkcija log10(), pvz., log10(16). Šio tipo logaritmavimą atlikite kiekvienam vektoriaus seka_1 elementui.

5.2 Darbas su tekstiniais kintamaisiais

Tekstiniai kintamieji – tai ne statistinis duomenų tipas. Jis reikalingas, pvz., užrašyti grafikų pavadinimus. Programoje „R“ tekstinius duomenis atitinka klasė „character“ (sutrumpintai chr). Darbui su tekstiniais kintamaisiais galime naudoti bazines arba paketo stringr funkcijas.

Darbui su tekstiniais kintamaisiais skirtas specializuotas paketas stringr .

Visos svarbiausios paketo stringr funkcijos prasideda str_, todėl paprasta prisiminti. str yra trumpinys nuo kompiuterinio termino „string“ – teksto eilutė.

Duomenyse bus lietuviškų simbolių, todėl įsijunkime lietuviškąją lokalę.

Sys.setlocale(locale = "Lithuanian") # Lietuviška lokalė Windows sistemai

Tekstinės reikšmės sudaromos naudojant funkciją c() ir kabutes. Skirtingos reikšmės atskiriamos kableliais.

miestai <- c("Vilnius", "Kaunas", "Klaipėda")
miestai
## [1] "Vilnius"  "Kaunas"   "Klaipėda"

Naudodami is.character() patikriname, ar vektorius yra tekstinis, o as.character() vektorių paverčia į tekstinį:

is.character(miestai)
## [1] TRUE
skaiciai <- 1:5
skaiciai
## [1] 1 2 3 4 5

is.character(skaiciai)
## [1] FALSE
skaiciai_chr <- as.character(skaiciai)
skaiciai_chr
## [1] "1" "2" "3" "4" "5"

is.character(skaiciai_chr)
## [1] TRUE

Žodžiu is prasidedančios funkcijos tikrina, o žodžiu as – keičia duomenų tipą ar kitą savybę.

Galime palyginti, ar kelios reikšmės yra vienodos:

"A" == "B"
## [1] FALSE
"A" == "a"
## [1] FALSE

Taip pat ar reikšmė priklauso pogrupiui:

"Vilnius" %in% miestai
## [1] TRUE
"A" %in% miestai
## [1] FALSE

Funkcijos paste() ir paste0() sujungia kelias reikšmes į vieną.

paste("A", "B", "C")
## [1] "A B C"
paste0("A", "B", "C")
## [1] "ABC"

Gali būti pasirenkamas norimas skirtumas nurodant sep:

paste("A", "B", "C", sep = ", ")
## [1] "A, B, C"

Funkcija paste0() atitinka paste(sep = ""). Veikia vektorizuotai:

vardas    <- c("Jonas", "Ona", "Gytis")
kreipinys <- c("ponas", "panelė", "ponaitis")

vardas_ir_kreipinys <- paste(kreipinys, vardas)
vardas_ir_kreipinys
## [1] "ponas Jonas"    "panelė Ona"     "ponaitis Gytis"

Jei visas reikšmes norime sujungti į vieną eilutę, papildomai naudojama collapse ir nurodome skirtuką:

paste(kreipinys, vardas, collapse = ", ")
## [1] "ponas Jonas, panelė Ona, ponaitis Gytis"

Kaip alternatyva funkcijai paste(), gali būti naudojama stringr::str_c() (reikalingas paketas stringr). Įprastai str_c() duoda labiau prognozuojamus rezultatus, kai tekstinių reikšmių vektoriuje yra praleistų reikšmių (NA).

stringr::str_c(kreipinys, vardas)
## [1] "ponasJonas"    "panelėOna"     "ponaitisGytis"

stringr::str_c(kreipinys, vardas, sep = " ")
## [1] "ponas Jonas"    "panelė Ona"     "ponaitis Gytis"

stringr::str_c(kreipinys, vardas, collapse = ", ")
## [1] "ponasJonas, panelėOna, ponaitisGytis"

stringr::str_c(kreipinys, vardas, sep = " ", collapse = ", ")
## [1] "ponas Jonas, panelė Ona, ponaitis Gytis"

Kiekvienos tekstinės reikšmės simbolių skaičių pasako nchar() arba stringr::str_length():

nchar(vardas_ir_kreipinys)
## [1] 11 10 14
stringr::str_length(vardas_ir_kreipinys)
## [1] 11 10 14

Naudojant stringr::str_sort() tekstines reikšmes galima išdėlioti eilės tvarka:

  • Nurodant locale ir dviženklį kalbos kodą (pvz., "lt") galima išdėlioti abėcėlės tvarka.
  • Nurodant numeric = TRUE – kaip skaičius.
raidės <- c("Z", "J", "Y", "K")
stringr::str_sort(raidės, locale = "lt")
## [1] "Y" "J" "K" "Z"

stringr::str_sort(raidės, locale = "en")
## [1] "J" "K" "Y" "Z"
skaiciai_chr_2 <- c("20", "5", "10", "150", "12", "1")
stringr::str_sort(skaiciai_chr_2)
## [1] "1"   "10"  "12"  "150" "20"  "5"

stringr::str_sort(skaiciai_chr_2, numeric = TRUE)
## [1] "1"   "5"   "10"  "12"  "20"  "150"

Funkcija stringr::str_order() parodo išdėliojimo eilės tvarką (naudojama analogiškai kaip str_sort()):

stringr::str_order(raidės, locale = "en")
## [1] 2 4 3 1

Funkcija dplyr::recode() perkoduoja reikšmes pagal šabloną senoji_reikšmė = naujoji_reikšmė:

dplyr::recode(kreipinys, "ponas" = "Mr.", "panelė" = "Miss.")
## [1] "Mr."      "Miss."    "ponaitis"

Taip pat gali būti naudingos funkcijos:

stringr::str_to_lower(vardas_ir_kreipinys) # visos mažosios
## [1] "ponas jonas"    "panelė ona"     "ponaitis gytis"

stringr::str_to_upper(vardas_ir_kreipinys) # visos didžiosios
## [1] "PONAS JONAS"    "PANELĖ ONA"     "PONAITIS GYTIS"

stringr::str_to_title(vardas_ir_kreipinys) # pirma didžioji
## [1] "Ponas Jonas"    "Panelė Ona"     "Ponaitis Gytis"

make.names(vardas_ir_kreipinys) # paverčia į leistinus „R“ objektų pavadinimus
## [1] "ponas.Jonas"    "panelė.Ona"     "ponaitis.Gytis"

Kitus duomenų tipus galime paversti į tekstą naudodami as.character(), norimu pavidalu suformatuodami skaičius (žr. „5.4.5 Skaičių formatavimas“) ar kitaip sudarydami teksto eilutes. Įprastai į tekstą paverstus duomenis galima tvarkingiau pateikti lentelėse bei ataskaitose, nei, pvz., suapvalintus, bet nesuformatuotus skaičius.

Visgi tekstiniams kintamiesiems statistinė analizė neatliekama. Prieš tai jie turi būti paversti į kategorinius. Kai kurios funkcijos tekstą automatiškai atpažįsta kaip faktorius (tik kategorijas gali išrikiuoti nelogiška tvarka). Kitais atvejais pakeitimą privalu atlikti „rankiniu būdu“ naudojant as.factor() ar analogiškas funkcijas (žr., „5.3.1 Faktorių kūrimas“).

Praktinis patarimas: dirbdami prisiminkite, kad jei norite pakeisti/atnaujinti objekto reikšmes, reikia naudoti <- arba =:

raidės
## [1] "Z" "J" "Y" "K"

(raidės <- stringr::str_sort(raidės, locale = "lt"))
## [1] "Y" "J" "K" "Z"

(raidės <- dplyr::recode(raidės, "Y" = "i", "K" = "25"))
## [1] "i"  "J"  "25" "Z"

raidės <- stringr::str_c(raidės, collapse = " + ")
raidės
## [1] "i + J + 25 + Z"

Užduotis 5.11 Duota seka vardai_2 <- c("G", "J", "G", "A", "Y", "G"). Tai pirmosios vardų „Gytis“, „Jonas“ ir „Aistis“ raidės. Atlikite užduotis: atsakymai, kurių tikimasi, pateikti žemiau.

  1. Išrikiuokite raides pagal lietuvių kalbos abėcėlę.
  2. Pašalinkite raidę „Y“.
  3. Perkoduokite į vardus.
  4. Suskaičiuokite, kokio ilgio kiekvienas vardas.
  5. Prieš kiekvieną vardą pridėkite „p. “.
  6. Kiekvieną pirmąją raidę paverskite į didžiąją.
  7. Visus vardus (su prierašu „p. “) atskyrę kableliais sujunkite į vieną eilutę.
  8. Suskaičiuokite, kokio ilgio galutinė eilutė.

Atsakymai pasitikrinimui:

## [1] "A" "G" "G" "G" "Y" "J"
## [1] "A" "G" "G" "G" "J"
## [1] "Aistis" "Gytis"  "Gytis"  "Gytis"  "Jonas"
## [1] 6 5 5 5 5
## [1] "p. Aistis" "p. Gytis"  "p. Gytis"  "p. Gytis"  "p. Jonas"
## [1] "P. Aistis" "P. Gytis"  "P. Gytis"  "P. Gytis"  "P. Jonas"
## [1] "P. Aistis, P. Gytis, P. Gytis, P. Gytis, P. Jonas"
## [1] 49

5.3 Darbas su kategoriniais kintamaisiais

Kategoriniai kintamieji (faktoriai) – tai iš anksto žinomą galimų skirtingų reikšmių (kategorijų) skaičių turintys kintamieji. Sutrumpintai žymimi fct.

Darbui su faktoriais yra sukurtas specializuotas paketas forcats . Svarbiausios jo funkcijos prasideda užrašu fct_.

5.3.1 Faktorių kūrimas

Faktoriai sukuriami naudojant funkciją factor().

fct_1 <- factor(c("A", "A", "D", "C", "C", "D"))
fct_2 <- factor(c("A", "T", "T", "T", "C", "T"))

miestai <- c("Vilnius", "Vilnius", "Kaunas", "Vilnius", "Klaipėda", "Kaunas", "Alytus")
(miestai_fct <- factor(miestai))
## [1] Vilnius  Vilnius  Kaunas   Vilnius  Klaipėda Kaunas   Alytus  
## Levels: Alytus Kaunas Klaipėda Vilnius

Taip pat kategorinius kintamuosius galime gauti keisdami duomenų klasę funkcijomis as.factor() (kategorijas išrikiuoja abėcėliškai), forcats::as_factor() (kategorijas išrikiuoja pagal jų eilės tvarką vektoriuje), factor() (kategorijas galime nurodyti patys naudodami levels = c(…)) ir panašias funkcijas.

miestai <- c("Vilnius", "Vilnius", "Kaunas", "Vilnius", "Klaipėda", "Kaunas", "Alytus")

# Kategorijos išdėliojamos pagal abėcėlę.
# Rezultatas skirsis priklausomai nuo nustatytos „R“ lokalės.
as.factor(miestai) 
## [1] Vilnius  Vilnius  Kaunas   Vilnius  Klaipėda Kaunas   Alytus  
## Levels: Alytus Kaunas Klaipėda Vilnius
# Kategorijos išdėliojamos pagal eilės tvarką vektoriuje.
# Pirma sutinkamas „Vilnius“, po to „Kaunas“ ir t.t.
forcats::as_factor(miestai) 
## [1] Vilnius  Vilnius  Kaunas   Vilnius  Klaipėda Kaunas   Alytus  
## Levels: Vilnius Kaunas Klaipėda Alytus
# Kategorijos išdėliojamos nurodyta eilės tvarka.
factor(miestai, levels = c("Kaunas", "Alytus", "Vilnius", "Klaipėda"))
## [1] Vilnius  Vilnius  Kaunas   Vilnius  Klaipėda Kaunas   Alytus  
## Levels: Kaunas Alytus Vilnius Klaipėda

Norint duomenis paversti į ranginius, naudojamos funkcijos ordered(), as.ordered() arba factor(..., ordered = TRUE):

vietos <- c("pirma", "antra", "trečia") 
as.ordered(vietos) # kategorijos išdėliotos neteisingai
## [1] pirma  antra  trečia
## Levels: antra < pirma < trečia

ordered(vietos, levels = c("pirma", "antra", "trečia"))
## [1] pirma  antra  trečia
## Levels: pirma < antra < trečia

factor(vietos, levels = c("pirma", "antra", "trečia"), ordered = TRUE)
## [1] pirma  antra  trečia
## Levels: pirma < antra < trečia

Ranginius duomenis versti į nominaliuosius naudojama funkcija factor(..., ordered = FALSE).

Turint tekstinius kintamuosius, funkcija type.convert() tinkamą duomenų tipą bando atspėti automatiškai, tad ji taip pat gali duomenis paversti į nominaliuosius faktorius (kategorijos nebūtinai bus išrikiuotos logiška tvarka).

type.convert(miestai) # Automatinis kintamojo tipo parinkimas → factor
## [1] Vilnius  Vilnius  Kaunas   Vilnius  Klaipėda Kaunas   Alytus  
## Levels: Alytus Kaunas Klaipėda Vilnius
type.convert(skaiciai_chr_2) # Automatinis kintamojo tipo parinkimas → numeric
## [1]  20   5  10 150  12   1

Įvykdę automatinį duomenų tipo parinkimą būtinai patikrinkite, ar rezultatas yra toks, kokio tikėjotės.

Naudodami funkciją cut() į kategorijas galime padalinti skaitinių kintamųjų reikšmes (apie tai bus rašoma skyriuje „5.4.4 Skaitinio kintamojo reikšmių kategorizavimas“).

Užduotis 5.12

  1. Duota duomenų eilutė budejimo_dienos <- c("Pirmadienis", "Antradienis", "Ketvirtadienis", "Sekmadienis"). Paverskite ją į faktorių. Kategorijos turi būti išrikiuotos logiška tvarka.

5.3.2 Faktorių pertvarkymas ir analizė

Toliau šio skyriaus pavyzdžiuose bus naudojami duomenys apie kates. Duomenų įkėlimo kodo suprasti nebūtina. Duomenų aprašymas: help(cats, package = "MASS").

lytis <- dplyr::recode_factor(MASS::cats$Sex, "M" = "Patinas", "F" = "Patelė")
kunas <- cut(MASS::cats$Bwt, breaks = 3, 
             labels = c("Smulkus", "Vidutinis", "Didelis"), ordered_result = TRUE)
sirdis <- cut(MASS::cats$Hwt, breaks = 2, labels = c("Lengva", "Sunki"), ordered_result = TRUE)
head(lytis)
## [1] Patelė Patelė Patelė Patelė Patelė Patelė
## Levels: Patinas Patelė

head(kunas)
## [1] Smulkus Smulkus Smulkus Smulkus Smulkus Smulkus
## Levels: Smulkus < Vidutinis < Didelis

head(sirdis)
## [1] Lengva Lengva Lengva Lengva Lengva Lengva
## Levels: Lengva < Sunki

Norint patikrinti ar kintamasis yra kategorinis, naudojama funkcija is.factor(), o is.ordered() tikrina, ar kategorijos turi eilės tvarką (t. y., ar kintamasis yra ranginis).

Funkcija levels() išvardija kategorijas:

levels(lytis)
## [1] "Patinas" "Patelė"

levels(miestai_fct)
## [1] "Alytus"   "Kaunas"   "Klaipėda" "Vilnius"

Funkcija summary() automatinę suvestinę atlieka pagal kintamojo tipą („R“ klasę). Kategoriniams kintamiesiems sudaro dažnių lentelę.

summary(lytis)
## Patinas  Patelė 
##      97      47

summary(miestai_fct)
##   Alytus   Kaunas Klaipėda  Vilnius 
##        1        2        1        3

Dažnių lentelėms sudaryti naudojama funkcija table() arba ftable().

table(lytis)
## lytis
## Patinas  Patelė 
##      97      47

table(miestai_fct)
## miestai_fct
##   Alytus   Kaunas Klaipėda  Vilnius 
##        1        2        1        3

„R“ rezultatuose:

  • miestai_fct – kintamojo pavadinimas (gali ir nebūti);
  • Alytus Kaunas ... – reikšmių (grupių) pavadinimai;
  • 1 2 1 3 – reikšmių pasikartojimo dažnis (grupių dydžiai).

Funkciją table() galima naudoti ne tik faktoriams, bet ir kitų tipų kintamiesiems, kai norima sudaryti dažnių lentelę. Taip pat galima sudaryti kryžmines (kelių kintamųjų) dažnių lenteles, kurios rodo, kiek kartų pasikartoja kiekviena kelių kintamųjų reikšmių kombinacija.

dazn_lentele <- table(lytis, kunas)
dazn_lentele
##          kunas
## lytis     Smulkus Vidutinis Didelis
##   Patinas      31        42      24
##   Patelė       39         8       0

„R“ rezultatuose matome, kad, pvz., kombinacija „Patinas“ ir „Smulkus“ pasikartoja 31 kartą, o „Patelė“ ir „Didelis“ – apskritai nepasitaikė.

Funkcija addmargins() prideda eilučių ir stulpelių sumas

addmargins(dazn_lentele)
##          kunas
## lytis     Smulkus Vidutinis Didelis Sum
##   Patinas      31        42      24  97
##   Patelė       39         8       0  47
##   Sum          70        50      24 144

addmargins(dazn_lentele, margin = 1) # tik eilutėms
##          kunas
## lytis     Smulkus Vidutinis Didelis
##   Patinas      31        42      24
##   Patelė       39         8       0
##   Sum          70        50      24

addmargins(dazn_lentele, margin = 2) # tik stulpeliams
##          kunas
## lytis     Smulkus Vidutinis Didelis Sum
##   Patinas      31        42      24  97
##   Patelė       39         8       0  47

ES taisyklė:

  • pirma (1) – eilutės;
  • antra (2) – stulpeliai.

Funkcija prop.table() apskaičiuoja procentines dalis: bendrąją dalį, dalį pagal eilutes arba dalį pagal stulpelius.

prop.table(dazn_lentele) # bendra suma lygi 1
##          kunas
## lytis        Smulkus  Vidutinis    Didelis
##   Patinas 0.21527778 0.29166667 0.16666667
##   Patelė  0.27083333 0.05555556 0.00000000

prop.table(dazn_lentele, margin = 1) # eilučių suma lygi 1
##          kunas
## lytis       Smulkus Vidutinis   Didelis
##   Patinas 0.3195876 0.4329897 0.2474227
##   Patelė  0.8297872 0.1702128 0.0000000

prop.table(dazn_lentele, margin = 2) # stulpelių suma lygi 1
##          kunas
## lytis       Smulkus Vidutinis   Didelis
##   Patinas 0.4428571 0.8400000 1.0000000
##   Patelė  0.5571429 0.1600000 0.0000000

Kiekvienam lentelės elementui galima atlikti matematinius veiksmus (plačiau apie skaičiavimus skyriuje „5.4.2 R kaip kalkuliatorius“):

(rez_1 <- 100 * prop.table(dazn_lentele))
##          kunas
## lytis       Smulkus Vidutinis   Didelis
##   Patinas 21.527778 29.166667 16.666667
##   Patelė  27.083333  5.555556  0.000000

round(rez_1, digits = 1)
##          kunas
## lytis     Smulkus Vidutinis Didelis
##   Patinas    21.5      29.2    16.7
##   Patelė     27.1       5.6     0.0

Dar vienas būdas sudaryti dažnių lentelę – funkcija ftable(). Ji patogesnė tada, kai turime daugiau nei 2 kategorinius kintamuosius.

table(lytis, sirdis, kunas)
## , , kunas = Smulkus
## 
##          sirdis
## lytis     Lengva Sunki
##   Patinas     31     0
##   Patelė      39     0
## 
## , , kunas = Vidutinis
## 
##          sirdis
## lytis     Lengva Sunki
##   Patinas     37     5
##   Patelė       8     0
## 
## , , kunas = Didelis
## 
##          sirdis
## lytis     Lengva Sunki
##   Patinas     11    13
##   Patelė       0     0

ftable(lytis, sirdis, kunas)
##                kunas Smulkus Vidutinis Didelis
## lytis   sirdis                                
## Patinas Lengva            31        37      11
##         Sunki              0         5      13
## Patelė  Lengva            39         8       0
##         Sunki              0         0       0

Automatinę grafinę suvestinę atlieka funkcija plot() – nubraižo stulpelinę diagramą:

plot(lytis)

Arba:

ggplot2::qplot(lytis)

Y ašyje atidedamas reikšmių pasikartojimo dažnumas (grupės narių skaičius).

Norėdami sujungti kelis kategorinius kintamuosius (ir jų kategorijas), naudojame forcats::fct_c().

fct_3 <- forcats::fct_c(fct_1, fct_2)
fct_3
##  [1] A A D C C D A T T T C T
## Levels: A C D T

Nebenaudojamas kategorijas galime pašalinti naudodami droplevels() arba forcats::fct_drop():

# Didelių patelių kūnų nėra, bet kategorija liko.
# Ji bus atvaizduojama tiek grafikuose, tiek lentelėse.
kates_kunas <- kunas[lytis == "Patelė"]
levels(kates_kunas)
## [1] "Smulkus"   "Vidutinis" "Didelis"
# Pašalinama nebenaudojama kategorija.
kates_kunas_drop <- forcats::fct_drop(kates_kunas) 
levels(kates_kunas_drop)
## [1] "Smulkus"   "Vidutinis"
table(kates_kunas)
## kates_kunas
##   Smulkus Vidutinis   Didelis 
##        39         8         0
table(kates_kunas_drop)
## kates_kunas_drop
##   Smulkus Vidutinis 
##        39         8
plot(kates_kunas)

plot(kates_kunas_drop)

Funkcija dplyr::recode_factor() skirta perkoduoti kategorinio kintamojo reikšmes. Kaip ir dplyr::recode(), veikia pagal šabloną senoji_reikšmė = naujoji_reikšmė. Skirtumas toks, kad perkoduojamų reikšmių eiliškumas nurodo naujųjų kategorijų eiliškumą. Reikšmių eiliškumas išlieka tas pats, tik grafikuose ir lentelėse kategorijos bus atvaizduojamos kitokia tvarka.

dplyr::recode_factor(fct_1, "A" = "Arklas", "D" = "Deimantas")
## [1] Arklas    Arklas    Deimantas C         C         Deimantas
## Levels: Arklas Deimantas C

dplyr::recode_factor(fct_1, "D" = "Deimantas",  "A" = "Arklas")
## [1] Arklas    Arklas    Deimantas C         C         Deimantas
## Levels: Deimantas Arklas C

Užduotis 5.13

  1. Paskutinio pavyzdžio kategorijų perkodavimo procedūrą papildykite raidę „C“ perkoduodami į žodį „Citrina“ (t. y., parašykite kodą, kuris perkoduoja visas tris raides į pilnus žodžius). Rezultatus atvaizduokite grafiškai ir dažnių lentele.
  2. Kodas geliu_rusys <- iris$Species sugeneruos duomenų seką geliu_rusys. Kodo suprasti nereikia, bet konsolėje parašę kodą ?iris, „Help“ lange rasite pradinių duomenų aprašymą. Užduotis – ištirti seką geliu_rusys (kiekvienam punktui parašykite kodą):
    1. Kokia duomenų „R“ klasė?
    2. Kokį statistinį duomenų tipą atitinka šie duomenys?
    3. Kiek reikšmių iš viso? (Koks imties dydis?)
    4. Kiek yra skirtingų reikšmių? Kokie jų pavadinimai?
    5. Sudarykite dažnių lentelę.
    6. Duomenis atvaizduokite grafiškai. Įvardinkite, kaip vadinasi diagrama.
  3. Kodas pasaras <- chickwts$feed sugeneruos duomenų seką pasaras. Pradinių duomenų aprašymas: ?chickwts. Ištirkite seką pasaras taip, kaip darėte duomenims geliu_rusys.

5.4 Darbas su skaitiniais kintamaisiais

Programoje „R“ skaičiai visada užrašomi angliškai. Tai reiškia, kad tarp sveikosios ir dešimtosios dalies dedamas taškas (nors lietuviškai sakome „kablelis“). Jei sveikąją dalį sudaro tik nulis, jo galime nerašyti. O kablelis naudojamas atskirti kelias skirtingas reikšmes (t. y., kelis skaičius, o ne skaitmenis), kaip matėte ankstesniuose pavyzdžiuose.

x <- c(1.2, .6, .2200, 3.31)
x
## [1] 1.20 0.60 0.22 3.31

Taip pat „R“ turi kelias matematines konstantas, kurios gali būti panaudotos skaičiavimuose 5.1.

Lentelė 5.1: Matematinės konstantos
KonstantaReikšmėPastaba
piskaičius \(\pi = 3.14159...\)
exp(1)skaičius \(e = 2.71828...\)Atitinka išraišką \(e^1\).

5.4.1 Skaičių sekų kūrimas

Įprastai reikšmių sekos kuriamos naudojant operatorių c(). Tačiau dirbant su skaitiniais duomenimis yra specializuotų būdų skaičių sekoms kurti.

Operatorius :

Naudojant vieno dvitaškio operatorių : sukuriama seka nuo:iki kas 1. Pvz., sukuria didėjančių skaičių seką nuo 3 iki 21 kas 1:

3:21
##  [1]  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21

Ar mažėjančių skaičių seką nuo 3 iki -11 kas 1:

3:-11
##  [1]   3   2   1   0  -1  -2  -3  -4  -5  -6  -7  -8  -9 -10 -11

Užduotis 5.14

Naudodami : operatorių:

  1. Sukurkite seką a nuo 20 iki 200 kas 1 ir ją atspausdinkite.
  2. Sukurkite seką b nuo 0,3 iki -6,6 kas 1 ir ją atspausdinkite.
  3. Abi sekas sudėkite ir rezultatą pavadinkite c. Kokį įspėjimą parašo „R“?

Funkcija seq()

Jei nepakanka operatoriaus :, galime naudoti funkciją seq() (nuo angliško žodžio sequence). Jos argumentai yra:

  • from – (nuo) pirmoji reikšmė,
  • to – (iki) paskutinė galima reikšmė, jei ji įeina į seką.

Bei vienas iš:

  • by – (kas) sekos reikšmių keitimosi žingsnis,
  • length.out – bendras sekos ilgis,
  • along.width – kitas vektorius: šio ir naujojo vektorių ilgiai bus vienodi.

Pvz., seka nuo 1 iki 27 kas 5 (reikšmė 27 neįtraukta):

seq(from = 1, to = 27, by = 5)
## [1]  1  6 11 16 21 26

Seka nuo 1 iki 21, kurią sudaro 4 elementai (atstumai tarp reikšmių vienodi):

seq(from = 1, to = 21, length.out = 4)
## [1]  1.000000  7.666667 14.333333 21.000000

Seka nuo 1 iki 20, kurią sudaro tiek pat elementų, kiek yra sekoje 2:7:

seka_a <- 2:7
seq(from = 1, to = 20, along.with = seka_a)
## [1]  1.0  4.8  8.6 12.4 16.2 20.0

Taip pat dažnai naudojama funkcija seq_along(), kuri išvardija vektoriaus elementų eilės numerius. T. y., sukuria seką nuo 1 iki length(x), jei turime objektą x. Pvz.:

seq_along(seka_a)
## [1] 1 2 3 4 5 6

Toks funkcionalumas naudojamas braižant grafikus, kuriant for ciklus (apie juos kol kas plačiau nesimokysime), ar kitais atvejais, kai reikia vienodo ilgio sekų.

Užduotis 5.15 Sukurkite sekas:

  1. seka_s1: nuo 2 iki \(\pi\) kas 0,2;
  2. seka_s2: nuo \(e\) iki \(\pi\), kurioje yra 10 reikšmių;
  3. seka_s3, kurioje išvardinti seka_s2 elementų eilės numeriai.
Atsakymai:
## [1] 2.0 2.2 2.4 2.6 2.8 3.0
##  [1] 2.718282 2.765316 2.812351 2.859385 2.906420 2.953455 3.000489 3.047524
##  [9] 3.094558 3.141593
##  [1]  1  2  3  4  5  6  7  8  9 10

Atsitiktinės sekos iš galimų reikšmių aibės

Jei norime pasirinkti atsitiktinių skaičių seką iš žinomos reikšmių aibės, naudojame funkciją sample() (angl. sample – imties sudarymas). Svarbiausi funkcijos parametrai:

  • x – galimų reikšmių vektorius;
  • size – būsimos imties (vektoriaus) dydis;
  • replace (loginė reikšmė) – jei TRUE, tada ta pati reikšmė gali būti ištraukta kelis kartus (grąžintinis imties sudarymo būdas). Jei FALSE – kiekviena reikšmė gali būti pasirinkta ne daugiau kaip vieną kartą (negrąžintinis imties sudarymas).
  • prob – kiekvienos x reikšmės pasirinkimo tikimybė. Jei nenurodyta, tada tikimybės yra lygios.
set.seed(1) # Apie šią funkciją - kitame skyriuje

galimos_reikšmės <- c(1, 5, 7)
sample(galimos_reikšmės)
## [1] 1 5 7
sample(galimos_reikšmės, size = 1)
## [1] 1
sample(galimos_reikšmės, size = 20, replace = TRUE)
##  [1] 5 1 7 7 5 5 7 7 1 1 1 5 5 5 5 7 1 7 1 1

Užduotis 5.16

  1. Sudarykite sveikųjų skaičių seką nuo 1 iki 10 ir pavadinkite seka_int_1.
  2. Sekos seka_int_1 narius išdėliokite atsitiktine tvarka.
  3. Atsitiktiniu negrąžintiniu būdu iš sekos seka_int_1 paimkite 5 reikšmes. Ar paimtosios reikšmės gali būti vienodos?
  4. Atsitiktiniu grąžintiniu būdu iš sekos seka_int_1 paimkite 25 reikšmes. Ar paimtosios reikšmės gali būti vienodos?
  5. Ar pakartojus ketvirto punkto eksperimentą kiekvieną kartą bus gautas toks pats atsakymas?

Atsitiktinių skaičių sekos: statistiniai dėsniai

Atsitiktinių skaičių sekų, kurių nariai skirstosi pagal įvairius statistinius dėsnius, kūrimui naudojamos funkcijos, prasidedančios raide r (ang. random), po kurios eina sutrumpintas dėsnio pavadinimas, toks kaip norm – normalusis, arba Gauso, dėsnis, pois – Puasono (prancūzų mokslininko pavardė Poisson), unif tolygusis (angl. uniform) ir kiti. Kiekvienam iš šių dėsnių būdingi tam tikri parametrai. Pvz., rnorm(10, mean = 1, sd = 0.2) sukurs atsitiktinę seką iš 10 skaičių, paimtų iš generalinės aibės, pasiskirsčiusios pagal normalųjį skirstinį, kurio vidurkis (angl. mean) lygus 1, o standartinis nuokrypis (sd angl. standard deviation) – 0,2:

rnorm(10, mean = 1, sd = 0.2)
##  [1] 1.1667466 0.9447904 0.9289996 1.0174975 1.4504511 1.1668920 1.2624831
##  [8] 1.5005291 1.2336463 0.9147669

Funkcija rpois(6, lambda = 3) sukurs atsitiktinę seką iš 6 skaičių, paimtų iš pagal Puasono (Poisson) skirstinį, kurio parametras \(\lambda = 3\), pasiskirsčiusios aibės.

Funkcija runif(5, min = 2, max = 14) sukurs seką, paimtą iš generalinės aibės, kurios reikšmės pasiskirsčiusios tolygiai intervale nuo 2 iki 14:

runif(5, min = 2, max = 14)
## [1] 3.915123 2.967743 3.591804 4.062865 7.733334

Plačiau šiuos dėsnius nagrinėsime temoje apie tikimybes.

Atkreipkite dėmesį, kad tolydusis ir tolygusis (skirstinys) yra du skirtingi terminai.

Užduotis 5.17

  1. Simuliuokite eksperimentą, kurio metu paimama 9 narių imtis iš pagal normalųjį skirstinį pasiskirsčiusios generalinės aibės su parametrais \(\mu\) = 1.82 (vidurkis) ir \(\sigma\) = 0.18 (standartinis nuokrypis).

Atkartojamas atsitiktinumas

Visgi dirbant kompiuteriu reikia žinoti, kad kompiuteryje atsitiktinumas nėra tikras. Jis yra simuliuojamas algoritmais, kuriais sugeneruotų reikšmių pasikartojimo periodas yra labai didelis, tarkim \(2^{19937}-1\). Daugeliui praktinių problemų spręsti to pakanka. Algoritmo rezultatas priklauso nuo pradinių sąlygų. Šias pradines sąlygas nustato funkcija set.seed(), kurios skliaustuose nurodomas teigiamas arba neigiamas sveikasis skaičius. Kiekvieną kartą prieš atsitiktinių skaičių kūrimą naudojant šią funkciją gaunami vienodi rezultatai. Todėl „atsitiktinai“ sugeneruoti skaičiai iš tiesų yra pseudoatsitiktiniai.

rnorm(10) # Variantas A
##  [1] -0.96193342 -0.29252572  0.25878822 -1.15213189  0.19578283  0.03012394
##  [7]  0.08541773  1.11661021 -1.21885742  1.26736872
rnorm(10)  # Variantas B
##  [1] -0.7447816 -1.1312186 -0.7163585  0.2526524  0.1520457 -0.3076564
##  [7] -0.9530173 -0.6482428  1.2243136  0.1998116
set.seed(201809)
rnorm(10)  # Variantas C
##  [1]  0.9991890 -1.2069877  0.5160472  0.4601108 -0.5160344  0.2357106
##  [7] -0.6072210 -0.7666150  1.0941386  0.7102374
set.seed(201809)
rnorm(10)  # Variantas D identiškas variantui C
##  [1]  0.9991890 -1.2069877  0.5160472  0.4601108 -0.5160344  0.2357106
##  [7] -0.6072210 -0.7666150  1.0941386  0.7102374
set.seed(201809)
rnorm(10)  # Variantas E identiškas variantui C
##  [1]  0.9991890 -1.2069877  0.5160472  0.4601108 -0.5160344  0.2357106
##  [7] -0.6072210 -0.7666150  1.0941386  0.7102374

Kaip matote, trys paskutinės sekos yra identiškos, nes naudotos tos pačios pradinės sąlygos.

Prieš atliekant analizę, programos kodo pradžioje rekomenduojama nurodyti pradines pseudoatsitiktinių skaičių generatoriaus vertes. Taip kelis kartus vykdant tą pačią analizę bus gaunami identiški rezultatai, jei analizės metu naudojami atsitiktinumą simuliuojantys analizės metodai.

Užduotis 5.18

  1. Simuliuokite eksperimentą, kurio metu iš tolygiojo skirstinio (mažiausia reikšmė -100, didžiausia – 100) sudaroma 65 narių imtis. Kodą parašykite taip, kad ir jūsų, ir kolegos kompiuteryje būtų gauti identiški rezultatai.

5.4.2 R kaip kalkuliatorius

Programoje „R“ matematinius (ir kitokius) veiksmus atlieka simboliai, vadinami operatoriais (pvz., lentelėje 5.2), arba komandos, vadinamos funkcijomis (pvz., lentelėse 5.3, 5.4). Taip pat galima panaudoti ir konstantas, tokias kaip skaičius \(\pi\) (lentelė 5.1).

„R“ operatoriai – tai funkcijos, užrašomos ne žodžiais, o specialiaisiais simboliais, tokiais kaip +, <-, == ar %>%.

Lentelė 5.2: Matematinius veiksmus atliekantys „R“ operatoriai
Simbolis (operatorius)Atliekamas veiksmas (operacija)PavyzdysPavyzdžio atsakymas
+Sudėtis5 + 813
-Atimtis5 - 7-2
*Daugyba3 * 412
/Dalyba6 / 32
^Kėlimas laipsniu3^29
**Kėlimas laipsniu3**29
%/%Sveikoji dalis (po dalybos)7 %/% 32
%%Liekana (po dalybos)7 %% 31

Veiksmai atliekami eilės tvarka, panašiai, kaip matematikoje:

  • pirma veiksmai skliausteliuose;
  • tada kėlimas laipsniu;
  • tada daugyba, dalyba;
  • tada sudėtis, atimtis.
2 * 3^2          # 2 * 9
## [1] 18
(3 + 6)^2 - 9/3  # 9^2 - 3
## [1] 78
21 %/% 2^2     # 21 %/% 4
## [1] 5

Jei nesate tikri, kokia tvarka bus atlikti veiksmai – naudokite papildomus skliaustus. Tada tikrai bus aišku:

(5 %/% 2)^2
## [1] 4
5 %/% (2^2)
## [1] 1

Jei yra pradžios skliaustai (, būtinai turi būti ir pabaigos skliaustai ).


Lentelė 5.3: „R“ komandos, atliekančios dažnas matematines operacijas
Funkcija (komanda)Atliekamas veiksmas (operacija)PavyzdysPavyzdžio atsakymas
sqrt()Kvadratinė šaknissqrt(4)2
abs()Modulis (absoliučioji vertė)abs(-2)2
sin(), cos(), tan(),Trigonometrinės funkcijos (skliaustuose radianai; daugiau informacijos – suvedus komandą ?Trig).sin(pi/6)0.5
exp()Eksponentė \((e^x)\)exp(0)1
log(), log2(), log10()Natūrinis \((\ln{x})\), dvejetainis \((\log_2{x})\) ir dešimtainis \((\lg{x})\) logaritmai.log10(100)2
factorial()Faktorialas \((4! = 4\cdot3\cdot2\cdot1)\)factorial(4)24
choose()Binominis koeficientas \(C^k_n\).
Taip pat žymimas \(\binom{n}{k} = {n! \over k!(n-k)!}\).
choose(n = 5, k = 2)10


Lentelė 5.4: „R“ komandos, atliekančios apvalinimą.
Funkcija (komanda)Atliekamas veiksmas (operacija)PavyzdysPavyzdžio atsakymas
round()Įprastinis apvalinimas (iki n skaičių po kablelio)round(8.275, digits = 2)8.28
  round(-8.275, digits = 2)-8.28
signif()Įprastinis apvalinimas (iki n reikšmingų skaičių)signif(8.275, digits = 2)8.3
  signif(0.0275, digits = 2)0.028
ceiling()Apvalinimas¹ į didesnę pusęceiling(8.275)9
  ceiling(-8.275)-8
floor()Apvalinimas¹ į mažesnę pusęfloor(8.975)8
  floor(-8.975)-9
trunc()Apvalinimas¹ į nulio pusętrunc(9.99)9
  trunc(-9.99)-9

¹Apvalinimas iki artimiausio sveikojo skaičiaus.

Pavyzdžiai

Komandų, atliekančių matematinius veiksmus, naudojimo pavyzdžiai.

sqrt(125)
## [1] 11.18034
abs(-4)
## [1] 4
cos(4 * pi)
## [1] 1
exp(2) # Skaičius e pakeltas kvadratu
## [1] 7.389056
log(2.718282) # logaritmas pagrindu e
## [1] 1
factorial(6) # 6!
## [1] 720
choose(52, 5) # skaičiuojama 52!/(47! × 5!)
## [1] 2598960

arba

choose(n = 52, k = 5) # nurodyti argumentai suteikia aiškumo
## [1] 2598960

Užduotis 5.19

  1. Naudodamiesi „R“, parašykite ir apskaičiuokite šias išraiškas:
    1. \((2+3.3)^7 + \ln{6} + cos(\pi\sqrt{2})\);
    2. \(|2^5 - 3^4|\);
    3. \(e^{\left(-\frac{1}{2}\right)}\);
    4. \(e^e\);
    5. \(\pi r\ ^2\), kai \(r = 2.5\);
  2. Konstantą \(\pi\) suapvalinkite:
    1. iki 3 skaičių po kablelio;
    2. iki 5 reikšmingų skaitmenų.

5.4.3 Skaitinių kintamųjų suvestinės

Skaitines suvestines galima skaičiuoti automatiškai („greituoju būdu“) arba išreikštai nurodant norimą funkciją. Pavyzdžiuose bus naudojamas vektorius x. Kai tirsite savo duomenis, naudokite savojo vektoriaus pavadinimą.

set.seed(951753)
x <- round(rnorm(30), digits = 1) # suapvalinta iki 1 skaičiaus po kablelio.

Automatines suvestines atlieka funkcija summary(x). Skaitiniams kintamiesiems tai mažiausia reikšmė, 1 kvartilis, mediana, vidurkis, 3 kvartilis ir didžiausia reikšmė. Jei yra trūkstamų reikšmių, nurodomas jų skaičius.

summary(x)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##  -2.200  -0.875  -0.100  -0.090   0.575   2.400

Vietoje x reikia įrašyti kintamojo pavadinimą:

  1. Duomenų centras:
    • mean(x) – vidurkis;
    • mean(x, trim = .10) – 10% nupjautinis vidurkis. Skaičių trim galima keisti nuo 0 iki 0.5, tai atitinka nuo 0% iki 50% nupjautinį vidurkį;
    • median(x) – mediana;
    • DescTools::Hmean(x) – harmoninis vidurkis;
    • DescTools::Gmean(x) – geometrinis vidurkis.
  2. Sklaida:
    • sd(x) – standartinis nuokrypis;
    • var(x) – dispersija;
    • IQR(x) – IQR, tarpkvartilinis plotis, arba kvartilių skirtumas (angl. interquartile range);
    • mad(x) – MAD, absoliučiojo nuokrypio nuo medianos mediana, padauginta iš 1,4826 (angl. median absolute deviation).
  3. Kitos padėties statistikos:
    • min(x) – mažiausia reikšmė;
    • max(x) – didžiausia reikšmė;
    • quantile(x, probs = 0.25), quantile(x, probs = 0.75) – 25% ir 75% procentiliai. Skaičių probs galima keisti nuo 0 iki 1.
  4. Pozicija:
    • dplyr::first(x) – pirmoji reikšmė pagal eilę;
    • dplyr::last(x) – paskutinė reikšmė pagal eilę;
    • dplyr::nth(x, n = 2) – n-toji reikšmė pagal eilę (šiuo atveju – antroji reikšmė).
  5. Skaičius, dydis:
    • sum(x) – visų reikšmių suma (atitinka matematinį užrašą \(\sum x_i\));
    • length(x) – imties arba grupės dydis;
    • dplyr::n_distinct(x) arba length(unique(x)) – unikalių (nepasikartojančių) reikšmių skaičius;
    • sum(is.na(x)) – trūkstamų reikšmių skaičius;
    • sum(!is.na(x)) – netrūkstamų reikšmių skaičius.
  6. Skirstinio forma:
    • DescTools::Kurt(x) – eksceso koeficientas (angl., excess kurtosis). Parametras method (galimos reikšmės yra 1, 2, 3) kontroliuoja, kuris eksceso skaičiavimo metodas naudojamas;
    • DescTools::Skew() – asimetrijos koeficientas (angl., skewness). Parametras method (galimos reikšmės yra 1, 2, 3) kontroliuoja, kuris asimetrijos koeficiento skaičiavimo metodas naudojamas.

Pvz.:

median(x)
## [1] -0.1
DescTools::Kurt(x)
## [1] -0.7198677
quantile(x, probs = 0.25)
##    25% 
## -0.875
min(x)
## [1] -2.2

Jei duomenyse yra trūkstamų reikšmių, tada daugumos iš šių funkcijų atsakymas bus NA.

x_na <- x
x_na[25] <- NA
x_na
##  [1] -1.9 -1.7  2.4  0.0  2.0 -0.1 -1.5 -0.8 -2.2  0.6  0.0 -0.3 -0.9 -0.3 -0.1
## [16] -0.1  0.5  1.9 -0.9  0.0 -0.8  1.4 -0.1  0.3   NA  1.0 -1.8 -1.1  1.4 -0.6
mean(x_na)
## [1] NA

Tokiu atveju įprastai galima nurodyti parametrą na.rm = TRUE. Taip bus daromos suvestinės prieš tai pašalinus trūkstamas reikšmes.

mean(x_na, na.rm = TRUE)
## [1] -0.1275862

Alternatyva, jei funkcija neturi parametro na.rm – papildomai naudoti funkciją na.omit():

mean(na.omit(x_na))
## [1] -0.1275862

Arba

x_be_na <- na.omit(x_na)
sd(x_be_na)
## [1] 1.195795

„Greitam“ grafiniam atvaizdavimui galime naudoti šias funkcijas:

hist(x)

plot(density(x))

boxplot(x)

ggplot2::qplot(x = x, geom = "histogram",
               bins = 5, # bins - stulpelių skaičius
               xlab = "Pavadinimas X",
               ylab = "Pavadinimas Y",
               color = I("black"))

ggplot2::qplot(x = x, geom = "density",
               adjust = 1) # adjust - glotninimo parametro daugiklis

ggplot2::qplot(y = x, geom = "boxplot")

Išsamiau apie grafikus mokysimės atskiro užsiėmimo metu.

Užduotis 5.20

  1. Šio skyriaus pavyzdžiuose sukurtai duomenų eilutei x apskaičiuokite visas poskyryje nurodytas aprašomąsias statistikas. Įvertinkite:
    1. duomenų centro padėtį;
    2. sklaidą;
    3. simetriją;
    4. išskirčių buvimą/nebuvimą.
  2. Sukurkite duomenų eilutę y <- rexp(30) (pagal eksponentinį dėsnį pasiskirstę duomenys). Apskaičiuokite poskyryje nurodytas aprašomąsias statistikas bei atvaizduokite grafiškai. Įvertinkite:
    1. duomenų centro padėtį;
    2. sklaidą;
    3. simetriją;
    4. išskirčių buvimą/nebuvimą.
  3. Apskaičiuokite, koks imties set.seed(12); x_3 <- rnorm(30) standartinis nuokrypis, kuris skaičiuojamas pagal formulę: \[s_x = \sqrt{\frac{\sum^n_{i=1}(x_i-\overline{x})^2}{n-1}}\] Funkcijų sd() bei var() naudoti negalima. Funkcija set.seed(12) nustato pradines sąlygas kompiuterio pseudoatsitiktinių skaičių generatoriui, todėl kiekvieno iš mūsų skaičiavimuose sugeneruojama ta pati skaičių seka (gaunami atkartojami rezultatai, o tai šiuolaikinėje duomenų analizėje labai svarbu).
  4. Apskaičiuokite, koks imties set.seed(12); x_4 <- rnorm(30) medianinis absoliutusis nuokrypis nuo medianos, kuris skaičiuojamas pagal formulę: \[mad_x = 1.4826 \cdot median( |x_i - median(x)|)\] Funkcijos mad() naudoti negalima;
  5. Sakykime, kad set.seed(-121258); x_5 <- rnorm(1e5) yra visa mūsų tiriama generalinė aibė (GA). Apskaičiuokite jai GA eksceso koeficientą (angl. excess kurtosis) pagal formulę: \[ekscesas = N \cdot \frac{\sum^N_{i=1}{(x_i - \overline{x}})^4}{\left(\sum^N_{i=1}{(x_i - \overline{x}})^2\right)^2} - 3\] kur \(N\) – GA dydis, \(\overline{x}\) – GA vidurkis. Formulė gali būti išskaidyta į kelias eilutes.

5.4.4 Skaitinio kintamojo reikšmių kategorizavimas

Kartais skaitinio kintamojo reikšmes, pvz., amžių, reikia suskirstyti į kategorijas „jaunas“, „vidutinio amžiaus“, „pagyvenęs“. Tam naudinga funkcija cut().

set.seed(654852)
amžius <- sample(1:80, size = 100, replace = TRUE)

summary(amžius)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    1.00   18.75   42.00   40.99   59.50   80.00


Funkcijoje nurodomos ribos, kaip „supjaustyti“ kintamojo reikšmes. Kiekvienam pogrupiui galime suteikti pavadinimus.

amžiaus_gr <- cut(amžius, breaks = c(0, 30, 60, 100),   # intervalų ribos
                  labels = c("jaunas", "suaugęs", "pagyvenęs"))
summary(amžiaus_gr)
##    jaunas   suaugęs pagyvenęs 
##        33        42        25

Jei mažiausios ar didžiausios galimos reikšmės nežinome, galime nurodyti -Inf arba Inf

Neturint rimto pagrindo tolydžiuosius dydžius kategorizuoti ir analizuoti kaip kategorinius yra nekorektiška.

amžiaus_gr_2 <- cut(amžius, breaks = c(-Inf, 30, 60, Inf),  # intervalų ribos
                  labels = c("jaunas", "suaugęs", "pagyvenęs"))
summary(amžiaus_gr_2)
##    jaunas   suaugęs pagyvenęs 
##        33        42        25

Jei reikšmes norite suskirstyti į kelias pagal intervalo plotį lygias grupes, parametrui breaks nurodykite vieną sveikąjį skaičių:

amžiaus_gr_3 <- cut(amžius, breaks = 4) # intervalų skaičius
summary(amžiaus_gr_3)
## (0.921,20.8]  (20.8,40.5]  (40.5,60.2]  (60.2,80.1] 
##           26           22           27           25

Matome, kad reikšmės pateiktos kaip vienodo pločio intervalai. Tik išorinių intervalų galai padidinti 0.1% tam, kad didžiausios ir mažiausios reikšmės patektų į intervalą.

Plačiau apie funkciją rašoma dokumentacijoje: ?cut.

Labiau specializuotas funkcijos cut() atmainas galime rasti pakete ggplot2:

  • cut_interval() – sudaroma n grupių, kurių reikšmių intervalo plotis (ilgis) vienodas;
  • cut_number() – sudaroma n grupių, kurių dydis pagal narių skaičių yra daugmaž vienodas;
  • cut_width() – sudaromi nurodyto pločio (width) intervalai. Taip pat galima nurodyti vieno (bet kurio, nebūtinai pirmojo) iš intervalų arba centro (center), arba ribos (boundary) padėtį. Kitų intervalų centrai bus kartotiniai išraiškai center ± i * width, o ribos – boundary ± i * width, kur i – sveikasis skaičius.

Štai keletas pavyzdžių:

ggplot2::cut_interval(MASS::cats$Hwt, n = 2) %>% table()
## .
##  [6.3,13.4] (13.4,20.5] 
##         126          18
ggplot2::cut_number(MASS::cats$Hwt, n = 2)   %>% table()
## .
##  [6.3,10.1] (10.1,20.5] 
##          73          71
ggplot2::cut_width(MASS::cats$Hwt, width = 2) %>% table()
## .
##   [5,7]   (7,9]  (9,11] (11,13] (13,15] (15,17] (17,19] (19,21] 
##       4      36      50      33      15       4       1       1
ggplot2::cut_width(MASS::cats$Hwt, width = 2, center = 5) %>% table()
## .
##   [6,8]  (8,10] (10,12] (12,14] (14,16] (16,18] (18,20] (20,22] 
##      20      45      42      23      11       2       0       1
ggplot2::cut_width(MASS::cats$Hwt, width = 2, boundary = 11.5) %>% table()
## .
##   [5.5,7.5]   (7.5,9.5]  (9.5,11.5] (11.5,13.5] (13.5,15.5] (15.5,17.5] 
##          11          40          47          30          11           4 
## (17.5,19.5] (19.5,21.5] 
##           0           1

Pastaba: neturint rimto pagrindo, tolydžiuosius dydžius kategorizuoti ir analizuoti kaip kategorinius kintamuosius yra nekorektiška, nes skirstant į kategorijas prarandama dalis informacijos. Pradinių duomenų reikšmių atstatyti iš kategorijų nebeįmanoma.

seq(2, 80, length.out = 4)
## [1]  2 28 54 80

Užduotis 5.21

  1. Sugeneruokite duomenis duom <- rnorm(62, 180, 20). Reikšmes suskirstykite į grupes „didelis“ ir „mažas“. Pirmoje grupėje turi būti reikšmės didesnės už medianą, antroje – mažesnės.
  2. Tą pačią duomenų eilutę suskirstykite į 5 reikšmių grupes. Kokia duomenų „R“ klasė (duomenų tipas)?

5.4.5 Skaičių formatavimas

Rengiant galutinę duomenų analizės ataskaitą įprastai norima, kad skaičiai būtų suapvalinti ir pateikti tvarkingai. Problema atliekant įprastinį apvalinimą – jei paskutinis skaičius yra nulis, įprastai „R“ jo nerodo.

round(10.2, digits = 0) # Tikimės 10.0
## [1] 10

Taip pat gali būti ir kitų aplinkybių, kada naudingos funkcijos, kurios skaičius suformatuoja ir paverčia į tvarkingai apipavidalintą tekstą. Priklausomai nuo situacijos, gali būti naudingos funkcijos, formatC(), prettyNum(), sprintf(), sringr::str_glue(), format() ar kitos. Apžvelgsime tik kelias.

Funkcija format(). Keli svarbesni parametrai:

  • digits – reikšmingų skaitmenų skaičius;
  • nsmall – minimalus skaitmenų po kablelio skaičius;
  • width – minimalus laukelio plotis (simbolių skaičius).
  • decimal.mark – sveikosios ir dešimtosios dalies skirtukas ("." arba ",").
set.seed(2015874)
(pries_formatavima <- rnorm(5))
## [1] -0.1295767 -0.7823619  0.7726673  2.3148301 -0.4781434
pries_formatavima[3] <- pries_formatavima[3] * 1000
format(pries_formatavima, digits = 1)
## [1] " -0.1" " -0.8" "772.7" "  2.3" " -0.5"

format(pries_formatavima, digits = 1, width = 6)
## [1] "  -0.1" "  -0.8" " 772.7" "   2.3" "  -0.5"

format(pries_formatavima, digits = 3)
## [1] " -0.130" " -0.782" "772.667" "  2.315" " -0.478"

format(pries_formatavima, digits = 1, decimal.mark = ",")
## [1] " -0,1" " -0,8" "772,7" "  2,3" " -0,5"

Peržvelkime formatC() galimybes. Svarbiausi funkcijos argumentai:

  • width – minimalus laukelio plotis (simbolių skaičius). Jei reikia, rezultatas gali užimti ir daugiau ženklų, nei nurodyta.
  • digits – skaitmenų po kablelio skaičius;
  • format – skaičių formatas:
    • "f" – fiksuotasis skaičių formatas: išlaikomas nurodytas skaitmenų po kablelio skaičius.
    • "e" – inžinerinis skaičių formatas;
    • "g" – formatas parenkamas pagal skaičiaus dydį.
  • decimal.mark – sveikosios ir dešimtosios dalies skirtukas ("." arba ",").
  • flag – formato modifikatoriaus žymė:
    • "0" – jei yra tuščių vietų, prieš skaičių pridedami nuliai;
    • "-" – lygiavimas ties kairiuoju kraštu;
    • "+" – visada rodo skaičiaus ženklą (+ ar -);
    • " " – jei pirmasis simbolis nėra ženklas (+ ar -), prideda tarpą prieš skaičių (taip išlaikomas lygiavimas).
formatC(pries_formatavima, format = "f", digits = 1)
## [1] "-0.1"  "-0.8"  "772.7" "2.3"   "-0.5"

formatC(pries_formatavima, format = "f", digits = 2)
## [1] "-0.13"  "-0.78"  "772.67" "2.31"   "-0.48"

formatC(pries_formatavima, format = "f", digits = 5)
## [1] "-0.12958"  "-0.78236"  "772.66728" "2.31483"   "-0.47814"

formatC(pries_formatavima, format = "f", digits = 1, width = 10)
## [1] "      -0.1" "      -0.8" "     772.7" "       2.3" "      -0.5"

formatC(pries_formatavima, format = "f", digits = 1, width = 10, flag = "0")
## [1] "-0000000.1" "-0000000.8" "00000772.7" "00000002.3" "-0000000.5"

formatC(pries_formatavima, format = "f", digits = 1, width = 10, flag = "-")
## [1] "-0.1      " "-0.8      " "772.7     " "2.3       " "-0.5      "

formatC(pries_formatavima, format = "f", digits = 1, width = 10, flag = "+")
## [1] "      -0.1" "      -0.8" "    +772.7" "      +2.3" "      -0.5"

formatC(pries_formatavima, format = "f", digits = 1, decimal.mark = ",")
## [1] "-0,1"  "-0,8"  "772,7" "2,3"   "-0,5"

formatC(pries_formatavima, format = "g", digits = 1)
## [1] "-0.1"  "-0.8"  "8e+02" " 2"    "-0.5"

formatC(pries_formatavima, format = "e", digits = 1)
## [1] "-1.3e-01" "-7.8e-01" "7.7e+02"  "2.3e+00"  "-4.8e-01"

formatC(pries_formatavima, format = "e", digits = 1, flag = " ")
## [1] "-1.3e-01" "-7.8e-01" " 7.7e+02" " 2.3e+00" "-4.8e-01"
Užduotis 5.22 (Užduotis dar nepateikta)

5.5 Darbas su loginiais kintamaisiais

Loginiai kintamieji – tai „R“ duomenų tipas, kuris atsiranda atlikus palyginimo arba loginio patikrinimo operacijas, kai atsakymas būna TRUE (loginė reikšmė „taip“, „tiesa“) arba FALSE („ne“, „netiesa“). Trumpieji reikšmių variantai pademonstruoti lentelėje 4.1. Įprastai loginiai kintamieji trumpinami lgl.

Susikurkime loginių reikšmių vektorių:

lgl_seka <- c(T, T, T, F, F, F, F, T, F, T, F, F)
lgl_seka
##  [1]  TRUE  TRUE  TRUE FALSE FALSE FALSE FALSE  TRUE FALSE  TRUE FALSE FALSE

Kiek elementų iš viso?

n <- length(lgl_seka)
n
## [1] 12

Norint statistiškai apdoroti pačias logines reikšmes, jos įprastai verčiamos į kategorinius kintamuosius, kaip tai daroma su tekstiniais kintamaisiais (žr. skyriuje „5.3.1 Faktorių kūrimas“).

5.5.1 Palyginimo operacijos

Palyginimo operacijos yra tam tikri reikšmių palyginimo ar patikrinimo veiksmai, kurių rezultatas yra loginės reikšmės. Prisiminkime, programoje „R“ loginės reikšmės yra kad TRUE (loginis „taip“, „tiesa“) bei FALSE („ne“, „netiesa“). Taip pat galima neapibrėžta, nežinoma ar trūkstama reikšmė – NA.

Palyginimo operacijos yra labai susijusios su loginėmis: įprastai pirmiausia atliekamos pirmosios, o jų rezultatai apibendrinami arba modifikuojami pastarosiomis. Palyginimo operatoriai pateikti lentelėje 5.5, o keletas patikrinimą atliekančių funkcijų – lentelėje 5.5. Atkreipkite dėmesį, kad nemaža dalis patikrinimą atliekančių funkcijų prasideda is, is. arba is_: is.factor(), is.ordered(), is.numeric(), is.integer(), is.character(), is.logical(), is.data.frame(), is.list(), is.function(), is.na(), isTRUE(), isFALSE(), tibble::is_tibble(), … Apie logines operacijas bus kalbama kitame poskyryje.

Lentelė 5.5: Palyginimą atliekantys „R“ operatoriai.
OperatoriusAtliekamas palyginimasPavyzdysPavyzdžio atsakymas
<Ar mažiau5 < 8TRUE
>Ar daugiau5 > 7FALSE
<=Ar mažiau arba lygu3 <= 4TRUE
>=Ar daugiau arba lygu6 >= 3TRUE
==Ar lygu3 == 2FALSE
!=Ar nelygu3 != 2TRUE
%in%Ar tai vienas iš …"C" %in% c("G", "M", "C")TRUE
Lentelė 5.6: Kelios sąlygų patikrinimui naudingos funkcijos.
Simbolis (operatorius), funkcijaTikrinimasPavyzdysPavyzdžio atsakymas
is.na()Ar eilutėje esanti reikšmė yra praleista (NA)is.na(NA);TRUE
  is.na(NaN);TRUE
  is.na(2);FALSE
!is.na()Ar eilutėje esanti reikšmė nėra praleista!is.na(NA)FALSE
isTRUE()Ar tikrai TRUE (t.y., ne FALSE, ne NA ar pan.)isTRUE(TRUE)TRUE
  isTRUE(NA)FALSE
isFALSE()Ar tikrai FALSE (t.y., ne TRUE, ne NA ar pan.)isFALSE(FASLE)TRUE
  isFALSE(NA)FALSE
is.numeric()Ar skaičiusis.numeric(FASLE)FALSE
  is.numeric(55)TRUE
between()¹skaičius yra tam tikrame intervale (imtinai)between(10, left = 11, right = 20)FALSE


¹ funkcija iš paketo dplyr, t. y., dplyr::between().

Daugiau informacijos – dokumentacijoje:

  • apie palyginimo operacijas - įvykdžius komandą ?Comparison;
  • apie kitas funkcijas, parašius klaustuką ir jų pavadinimą, pvz., ?dplyr::between ar ?isTRUE.
Užduotis 5.23 (Užduotis dar nepateikta)

5.5.2 Loginės operacijos

Loginės operacijos – tai veiksmai su loginėmis reikšmėmis, kurių rezultatas taip pat yra loginė reikšmė. Pagrindinės loginės operacijos yra konjunkcija, disjunkcija bei inversija, kurias reprezentuoja operatoriai & (IR), | (ARBA) bei ! (NE).

  1. Vienos loginės reikšmės modifikavimas:
    1. ! – neiginys, operatorius „NE“ (angl. NOT) atlieka loginę inversiją:
      • FALSE („ne“) padaro TRUE („taip“), iš TRUEFALSE;
      • pvz,: !(amžius < 22) reiškia: „amžius nemažesnis už 22“.
  2. Dviejų loginių reikšmių apibendrinimas:
    1. & – operatorius „IR“ (angl. AND) atlieka loginę konjunkciją. Tam, kad rezultatas būtų teigiamas (TRUE), turi būti tenkinamos abi sąlygos
      • pvz., kai tikriname, ar tai vyras, jaunesnis nei 35 metai;
      • sąlyga lytis == "vyras" & amžius < 35 tikrina teiginį „ir vyras, ir jaunesnis nei 35“.
    2. | – operatorius „ARBA“ (angl. OR) atlieka loginę disjunkciją. Tam, kad rezultatas būtų teigiamas, turi būti tenkinama bent viena sąlyga:
      • pvz., kai tikriname, ar diena ne darbo, jei nedirbame per šventes ir sekmadieniais;
      • diena == "šventinė" | savaitės_diena == "sekmadienis":
      • „diena yra arba šventinė, arba savaitės diena yra sekmadienis“.
    3. xor() – funkcija „išskirtinai ARBA“ (angl. explicit OR): rezultatas bus teigiamas tik tada, kai arba tik pirma, arba tik antra sąlyga yra tenkinama, bet ne tada, kai abi.
  3. Kelių loginių reikšmių apibendrinimas:
    1. all() – (funkcija „visos“) tai jungtuko IR generalizacija: rezultatas teigiamas, kai visos tikrinamos sąlygos yra teigiamos.
    2. any() – (funkcija „bent viena“) tai jungtuko ARBA generalizacija: rezultatas teigiamas, kai bent viena sąlyga tenkinama.

Daugiau pavyzdžių galite rasti lentelėse 5.7 ir 5.8 bei dokumentacijoje (įvykdykite komandą ??base::logic).

Lentelė 5.7: Loginiai „R“ operatoriai ir funkcijos.
Simbolis (operatorius), funkcijaOperacijaPavyzdysPavyzdžio atsakymas
!Loginė operacija „NE!FALSETRUE
  !TRUEFALSE
&Loginė operacija „IR“ (atliekama kiekvienam elementui)FALSE & FALSEFALSE
  TRUE & FALSEFALSE
  FALSE & TRUEFALSE
  TRUE & TRUETRUE
|Loginė operacija „ARBA“ (atliekama kiekvienam elementui)FALSE | FALSEFALSE
  TRUE | FALSETRUE
  FALSE | TRUETRUE
  TRUE | TRUETRUE
xor()Loginė operacija „išskirtinai ARBAxor(TRUE, TRUE)FALSE
  xor(FALSE, TRUE)TRUE
  xor(TRUE, FALSE)TRUE
  xor(FALSE, FALSE)FALSE
any()Tikrinimas, ar bent vienas yra TRUEany(FALSE, TRUE, FALSE)TRUE
all()Tikrinimas, ar visi yra TRUEall(FALSE, TRUE, FALSE)FALSE
  all(TRUE, TRUE, TRUE)TRUE
Lentelė 5.8: Rečiau naudojami loginiai „R“ operatoriai.
Simbolis (operatorius), funkcijaOperacijaPavyzdysPavyzdžio atsakymas
&&Loginė operacija „IR“ (atliekama tik pirmam elementui)TRUE && TRUEFALSE
||Loginė operacija „ARBA“ (atliekama tik pirmam elementui)TRUE || FALSETRUE
Užduotis 5.24 (Užduotis dar nepateikta)

5.5.3 Loginės reikšmės atliekant skaičiavimus

Vykdant analizę dažnai panaudojama tokia savybė – atliekant matematinius veiksmus, „R“ loginius kintamuosius automatiškai paverčia į skaičius:

  • TRUE → 1;
  • FALSE → 0.

Todėl sum() apskaičiuoja, keli elementai, o mean() parodo, kuri dalis (skaičius nuo 0 iki 1) tenkina sąlygą (yra TRUE).

sum(lgl_seka) # Sekoje yra 5 TRUE reikšmės
## [1] 5
 
mean(lgl_seka) # Sekoje yra 41,7% TRUE reikšmių
## [1] 0.4166667

Taikymo pavyzdžiai:

  • Kiek kartų pasikartoja žodis „Vilnius“ ir kurią reikšmių dalį jis užima duomenų eilutėje?
miestai <- c("Vilnius", "Vilnius", "Kaunas", "Vilnius", "Klaipėda", "Kaunas", "Alytus")
sum(miestai == "Vilnius")
## [1] 3

mean(miestai == "Vilnius")
## [1] 0.4285714
  • Kiek kartų pasikartoja žodžiai „Vilnius“ bei „Alytus“ ir kurią reikšmių dalį jie užima duomenų eilutėje?
sum(miestai %in% c("Vilnius", "Alytus"))
## [1] 4

mean(miestai %in% c("Vilnius", "Alytus"))
## [1] 0.5714286
  • Kurią procentinę duomenų eilutės reikšmių dalį sudaro praleistos reikšmės? Atsakymą pateikti dešimtosios dalies tikslumu.
eilute <- c(1:3, NA, 1:14, NA, NA, NA, 22:25, NA, NA, 1:6, NA, NA, NA, NA)

ar_trukstama <- is.na(eilute)
(ats1 <- mean(ar_trukstama) * 100) # dalis procentais
## [1] 27.02703

# Pašalins paskutinius skaičius, jei jie yra nuliai
(ats2a <- round(ats1, digits = 1)) 
## [1] 27
paste("Trūkstamų reikšmių dalis yra", ats2a, "%.")
## [1] "Trūkstamų reikšmių dalis yra 27 %."


# Paliks paskutinius skaičius, net jei jie yra nuliai
(ats2b <- formatC(ats1, digits = 1, format = "f")) 
## [1] "27.0"
paste("Trūkstamų reikšmių dalis yra", ats2b, "%.")
## [1] "Trūkstamų reikšmių dalis yra 27.0 %."
Užduotis 5.25

Klausimai ir komentarai