Argument ...

Funkcia na výpočet kvantilov v R umožňuje zvoliť si metódy výpočtu kvantilov pomocou argumentu type. Pre drvivú väčšinu dát ale na spôsobe výpočtu kvantilov nezáleží, môžeme ho ale napriek tomu umožniť užívateľovi nastaviť.

rozdiel4 <- function(x, probs = c(0, 1), ...) {
  qv <- quantile(x = x, probs = probs, ...)
  max(qv) - min(qv)
}

Funkciu teraz môžeme volať aj nasledovným spôsobom:

data(iris)
rozdiel4(iris$Sepal.Width, type=4)
## [1] 2.4
rozdiel4(iris$Petal.Length, type=5)
## [1] 5.9

Argument ... používame vtedy, keď chceme odovzdať argumenty inej funkcii bez toho, aby sme deklarovali formálne argumenty pôvodnej funkcie. Takéto argumenty teda môžeme alebo nemusíme špecifikovať, podľa potreby.

Automatizované testovanie funkcií

library(testthat)

test_that('correct quantiles', {
  expect_identical(rozdiel4(iris$Sepal.Length), max(iris$Sepal.Length)-min(iris$Sepal.Length))
})

test_that('correct quantiles', {
  expect_identical(rozdiel4(iris$Sepal.Length, c(0.25,0.75)), max(iris$Sepal.Length)-min(iris$Sepal.Length))
})

test_that('invalid args are detected', {
  expect_error(rozdiel4("matfyz"))
  expect_error(rozdiel4(iris))
})

test_that('NA handling works', {
  expect_that(rozdiel4(c(1:5, NA)), equals(4))
})

test_that('multiple tests', {
  expect_identical(rozdiel4(iris$Sepal.Length), max(iris$Sepal.Length)-min(iris$Sepal.Length))
})

Zoznam užitočných funkcií v balíku testthat:

Sú si hodnoty rovné, ekvivalentné alebo identické?

expect_equal(x, y)
expect_equivalent(x, y)
expect_identical(x, y)

Dáva funkcia nejaký výstup, varovanie alebo chybu?

expect_output(x, y)
expect_message(x, y)
expect_warning(x, y)
expect_error(x, y)

Aká je hodnota na výstupe v porovnaní so špecifickou hodnotou?

expect_lt(x, y)
expect_lte(x, y)
expect_gt(x, y)
expect_gte(x, y)

Podrobnejší tutorial je na https://codingclubuc3m.rbind.io/post/2019-11-26/

Špeciálne funkcie

1.REP

S príkazom rep sme sa stretli už na predchádzajúcich cvičeniach.

Úloha: Vytvorte vektory

(1,2,...,10,1,2,...10,1,2,...,10)

(4,6,3,4,6,3,...,4,6,3), kde sa trojica 4,6,3 zopakuje 10-krát.

(1,1,1,2,2,2,...,10,10,10)

2.OUTER

Príkaz outer slúži na vytváranie tzv. vonkajšieho súčinu dvoch polí. Vstupom sú polia a operátor, ktorý na ne chceme aplikovať. Pozorujte, ako sa táto funkcia správa v nasledujúcich prípadoch:

x <- c(1,2.3,2,3,4,8,12,43)
y <- c(2,4)
outer(x, y, "log")
##          [,1]      [,2]
## [1,] 0.000000 0.0000000
## [2,] 1.201634 0.6008169
## [3,] 1.000000 0.5000000
## [4,] 1.584963 0.7924813
## [5,] 2.000000 1.0000000
## [6,] 3.000000 1.5000000
## [7,] 3.584963 1.7924813
## [8,] 5.426265 2.7131324
outer(x, y, "+")
##      [,1] [,2]
## [1,]  3.0  5.0
## [2,]  4.3  6.3
## [3,]  4.0  6.0
## [4,]  5.0  7.0
## [5,]  6.0  8.0
## [6,] 10.0 12.0
## [7,] 14.0 16.0
## [8,] 45.0 47.0
outer(x, y, "*")
##      [,1]  [,2]
## [1,]  2.0   4.0
## [2,]  4.6   9.2
## [3,]  4.0   8.0
## [4,]  6.0  12.0
## [5,]  8.0  16.0
## [6,] 16.0  32.0
## [7,] 24.0  48.0
## [8,] 86.0 172.0

Tabuľka malej násobilky:

x <- 1:10; names(x) <- x
outer(x, x, "*")
##     1  2  3  4  5  6  7  8  9  10
## 1   1  2  3  4  5  6  7  8  9  10
## 2   2  4  6  8 10 12 14 16 18  20
## 3   3  6  9 12 15 18 21 24 27  30
## 4   4  8 12 16 20 24 28 32 36  40
## 5   5 10 15 20 25 30 35 40 45  50
## 6   6 12 18 24 30 36 42 48 54  60
## 7   7 14 21 28 35 42 49 56 63  70
## 8   8 16 24 32 40 48 56 64 72  80
## 9   9 18 27 36 45 54 63 72 81  90
## 10 10 20 30 40 50 60 70 80 90 100

3. ROW, COL

row a col označujú indexy riadku a stĺpca matice.

(X <- matrix(rnorm(20), ncol=4))
##            [,1]        [,2]       [,3]       [,4]
## [1,]  0.9973239 -0.32329112  0.3392520 -0.4524192
## [2,] -1.2828065  0.10232239 -1.2539153 -0.2888192
## [3,] -1.2941385 -0.66449251  0.6616485 -0.6421649
## [4,] -0.1460796  0.43632530  0.1334084  1.1824594
## [5,] -2.1431766  0.01587849 -0.4808409  0.6185719
row(X) #indexy riadkov
##      [,1] [,2] [,3] [,4]
## [1,]    1    1    1    1
## [2,]    2    2    2    2
## [3,]    3    3    3    3
## [4,]    4    4    4    4
## [5,]    5    5    5    5
col(X) #indexy stlpcov
##      [,1] [,2] [,3] [,4]
## [1,]    1    2    3    4
## [2,]    1    2    3    4
## [3,]    1    2    3    4
## [4,]    1    2    3    4
## [5,]    1    2    3    4

Akej operácii je ekvivalentný nasledovný zápis?:

X[row(X) == col(X)]
## [1] 0.9973239 0.1023224 0.6616485 1.1824594
X[row(X) == col(X)] <- 1
X
##            [,1]        [,2]       [,3]       [,4]
## [1,]  1.0000000 -0.32329112  0.3392520 -0.4524192
## [2,] -1.2828065  1.00000000 -1.2539153 -0.2888192
## [3,] -1.2941385 -0.66449251  1.0000000 -0.6421649
## [4,] -0.1460796  0.43632530  0.1334084  1.0000000
## [5,] -2.1431766  0.01587849 -0.4808409  0.6185719

4. PODMNOŽINY

Na predchádzajúcich cvičeniach sme si ukázali, ako vybrať podmnožinu poľa pomocou hranatých zátvoriek a/alebo logických operátorov.

Vytvorme nasledovný vektor

x <- c(5.4, 6.2, 7.1, 4.8, 7.5)
names(x) <- c('a', 'b', 'c', 'd', 'e')

Úloha: Nájdite aspoň tri spôsoby ako dostať nasledovný výstup:

b c d

6.2 7.1 4.8

Logické operátory môžeme použiť aj priamo v hranatých zátvorkách, napríklad nasledovne:

x[x > 7]
##   c   e 
## 7.1 7.5
x[names(x) == "a"] #ktore prvky x maju nazov "a"?
##   a 
## 5.4
x[names(x) != "a"] #ktore prvky x nemaju nazov "a"?
##   b   c   d   e 
## 6.2 7.1 4.8 7.5
sum(x[x<5]) #sucet prvkov x, ktore su mensie ako 5
## [1] 4.8
x*(x<5) 
##   a   b   c   d   e 
## 0.0 0.0 0.0 4.8 0.0

5. UNIQUE, DUPLICATED

Ďalšími užitočnými špeciálnymi funkciami sú unique a duplicated, pomocou ktorých vieme vyberať jedinečné alebo opakujúce sa prvky z poľa:

x <- c(1, 1, 4, 5, 4, 6)
duplicated(x) #opakuje sa dany prvok?
## [1] FALSE  TRUE FALSE FALSE  TRUE FALSE
x[duplicated(x)] #ktore prvky sa opakuju?
## [1] 1 4

Nasledujúce dva riadky urobia rovnakú operáciu: vypíšu prvky vektora bez opakujúcich sa hodnôt

x[!duplicated(x)] 
## [1] 1 4 5 6
unique(x)
## [1] 1 4 5 6

6. UNION, INTERSECT, SETDIFF

V R máme špeciálne funkcie aj na množinové operácie \(\cup\), \(\cap\) a \(\setminus\).

setA<-c("a", "b", "c", "d", "e")
setB<-c("d", "e", "f", "g")
union(setA, setB) #mnozinove zjednotenie
## [1] "a" "b" "c" "d" "e" "f" "g"
intersect(setA, setB) #mnozinovy prienik
## [1] "d" "e"
setdiff(setA, setB) #mnozinovy rozdiel
## [1] "a" "b" "c"
setdiff(setB, setA)
## [1] "f" "g"
setA %in% setB #ktore prvky z A su aj B
## [1] FALSE FALSE FALSE  TRUE  TRUE

7. ANY, ALL, IDENTICAL

Tieto funkcie sú rozšírením už známych logických operátorov.

(x <- 0:6)
## [1] 0 1 2 3 4 5 6
(y <- c(0,1,2,3,4,5,6))
## [1] 0 1 2 3 4 5 6
x == y #su vsetky prvky vektora identicke? vystupom je vektor logickych hodnot
## [1] TRUE TRUE TRUE TRUE TRUE TRUE TRUE
identical(x, y) ##su vsetky prvky vektora identicke? vystupom je jedna logicka hodnota
## [1] FALSE
x < 4 #logicky vektor, TRUE ak je dany prvok mensi ako 4
## [1]  TRUE  TRUE  TRUE  TRUE FALSE FALSE FALSE
all(x > 0) #su vsetky prvky x kladne?
## [1] FALSE
any(x < 0) #je nejaky prvok x mensi ako 0?
## [1] FALSE
sum(x < 4) #kolko prvkov x je mensich ako 4? (sucet logickych hodnot)
## [1] 4

8. WHICH

Pomocou funkcie which sa vieme spýtať na to, v ktorom prvku vektora dochádza k danému javu (napríklad kde sa nadobúda minimum):

which(x == max(x)) #kde sa nadobuda minimum?
## [1] 7
which(x == min(x)) #kde sa nadobuda maximum?
## [1] 1
which(x == mean(x)) #ktory prvok je rovny aritmetickemu priemeru?
## [1] 4

Príklad: náhodné vektory

Vygenerujeme náhodne dva vektory dĺžky 5000 s hodnotami medzi 0 a 1, ktoré zaokrúhlime na dve desatinné miesta.

x <- round(runif(5000), 2)
y <- round(runif(5000), 2)
which(x == y)
##  [1]    7   48   96  101  206  222  268  270  293  692  867  917  932 1013 1042
## [16] 1095 1193 1208 1237 1316 1451 1577 1633 1733 1853 1856 1907 1965 2246 2284
## [31] 2320 2353 2446 2475 2588 2736 2904 3073 3118 3244 3460 3542 3773 3774 3916
## [46] 4101 4309 4466 4689 4715 4806
x[which(x == y)]
##  [1] 0.10 0.59 0.56 0.25 0.86 0.35 0.68 0.49 0.09 1.00 0.31 0.68 0.58 0.79 0.88
## [16] 0.29 0.83 0.57 0.15 0.50 0.59 0.52 0.80 0.45 0.58 0.32 0.61 0.86 0.72 0.96
## [31] 0.91 0.43 0.33 0.84 0.03 0.95 0.57 0.60 0.93 0.31 0.70 0.73 0.98 0.34 0.92
## [46] 0.61 0.24 0.97 0.80 0.56 0.30
y[which(x == y)]
##  [1] 0.10 0.59 0.56 0.25 0.86 0.35 0.68 0.49 0.09 1.00 0.31 0.68 0.58 0.79 0.88
## [16] 0.29 0.83 0.57 0.15 0.50 0.59 0.52 0.80 0.45 0.58 0.32 0.61 0.86 0.72 0.96
## [31] 0.91 0.43 0.33 0.84 0.03 0.95 0.57 0.60 0.93 0.31 0.70 0.73 0.98 0.34 0.92
## [46] 0.61 0.24 0.97 0.80 0.56 0.30
max(x)
## [1] 1
which(x == max(x))
##  [1]  335  377  516  657  692  746  835 1034 1077 1145 1544 2178 2304 2423 2480
## [16] 2630 2943 3125 3137 3213 3230 3862 3926 4318 4481 4486 4516 4526 4647
which(y == max(x))
##  [1]  378  651  692  990 1246 1367 1781 1830 2085 2324 2847 3013 3217 4172 4295
## [16] 4470 4549 4586 4968

Nájdeme x a y, pre ktoré je súčin xy väčší ako 0.5 a vykreslíme ich na červeno

z <- (x*y > 0.5)
plot(x, y, pch=16, col=ifelse(z, "red", "blue"))

Príklad: Švajčiarsko

Vezmime si teraz dáta swiss dostupné medzi dátovými súbormi priamo v R:

data(swiss)
head(swiss)
##              Fertility Agriculture Examination Education Catholic
## Courtelary        80.2        17.0          15        12     9.96
## Delemont          83.1        45.1           6         9    84.84
## Franches-Mnt      92.5        39.7           5         5    93.40
## Moutier           85.8        36.5          12         7    33.77
## Neuveville        76.9        43.5          17        15     5.16
## Porrentruy        76.1        35.3           9         7    90.57
##              Infant.Mortality
## Courtelary               22.2
## Delemont                 22.2
## Franches-Mnt             20.2
## Moutier                  20.3
## Neuveville               20.6
## Porrentruy               26.6

Vypíšeme tie riadky, pre ktoré je hodnota premennej Fertility väčšia ako 80

swiss[swiss$Fertility>80, ]
##              Fertility Agriculture Examination Education Catholic
## Courtelary        80.2        17.0          15        12     9.96
## Delemont          83.1        45.1           6         9    84.84
## Franches-Mnt      92.5        39.7           5         5    93.40
## Moutier           85.8        36.5          12         7    33.77
## Broye             83.8        70.2          16         7    92.85
## Glane             92.4        67.8          14         8    97.16
## Gruyere           82.4        53.3          12         7    97.67
## Sarine            82.9        45.2          16        13    91.38
## Veveyse           87.1        64.5          14         6    98.61
## Sierre            92.2        84.6           3         3    99.46
##              Infant.Mortality
## Courtelary               22.2
## Delemont                 22.2
## Franches-Mnt             20.2
## Moutier                  20.3
## Broye                    23.6
## Glane                    24.9
## Gruyere                  21.0
## Sarine                   24.4
## Veveyse                  24.5
## Sierre                   16.3

Usporiadame oblasti podľa hodnôt premennej Agriculture

swiss[order(swiss$Agriculture), c(1,3)]
##              Fertility Examination
## V. De Geneve      35.0          37
## La Chauxdfnd      65.7          29
## La Vallee         54.3          31
## Le Locle          72.7          22
## Courtelary        80.2          15
## Neuchatel         64.4          35
## ValdeTravers      67.6          25
## Lausanne          55.7          26
## Vevey             58.3          25
## Rive Gauche       42.8          22
## Grandson          71.7          17
## Porrentruy        76.1           9
## Moutier           85.8          12
## Val de Ruz        77.6          15
## Boudry            70.4          26
## Franches-Mnt      92.5           5
## Neuveville        76.9          17
## Delemont          83.1           6
## Sarine            82.9          16
## Rive Droite       44.7          16
## Yverdon           65.4          15
## Nyone             56.6          22
## Gruyere           82.4          12
## Orbe              57.4          20
## Moudon            65.0          14
## Payerne           74.2          14
## Morges            65.5          22
## Avenches          68.9          19
## Rolle             60.5          16
## Aigle             64.1          21
## Sion              79.3          13
## Paysd'enhaut      72.0           6
## Veveyse           87.1          14
## Monthey           79.4           7
## Aubonne           66.9          14
## Glane             92.4          14
## Cossonay          61.7          22
## Broye             83.8          16
## Oron              72.5          12
## Echallens         68.3          18
## Lavaux            65.1          19
## St Maurice        65.0           9
## Martigwy          70.5          12
## Sierre            92.2           3
## Entremont         69.3           7
## Conthey           75.5           3
## Herens            77.3           5

Vypíšeme, aké sú rôzne hodnoty premennej Examination

unique(swiss$Examination)
##  [1] 15  6  5 12 17  9 16 14 21 19 22 18 26 31 20 25  3  7 13 29 35 37

Úloha: Vypíšte, koľko krát sa opakujú jednotlivé hodnoty premennej Examination

Usporiadame oblasti podľa premenných Examination a Education

swiss[order(swiss$Examination, swiss$Education), c(1,4,5)]
##              Fertility Education Catholic
## Conthey           75.5         2    99.71
## Sierre            92.2         3    99.46
## Herens            77.3         2   100.00
## Franches-Mnt      92.5         5    93.40
## Paysd'enhaut      72.0         3     2.56
## Delemont          83.1         9    84.84
## Monthey           79.4         3    98.22
## Entremont         69.3         6    99.68
## Porrentruy        76.1         7    90.57
## St Maurice        65.0         9    99.06
## Oron              72.5         1     2.40
## Martigwy          70.5         6    98.96
## Moutier           85.8         7    33.77
## Gruyere           82.4         7    97.67
## Sion              79.3        13    96.83
## Moudon            65.0         3     4.52
## Veveyse           87.1         6    98.61
## Aubonne           66.9         7     2.27
## Glane             92.4         8    97.16
## Payerne           74.2         8     5.23
## Val de Ruz        77.6         7     4.97
## Yverdon           65.4         8     6.10
## Courtelary        80.2        12     9.96
## Broye             83.8         7    92.85
## Rolle             60.5        10     7.72
## Sarine            82.9        13    91.38
## Rive Droite       44.7        29    50.43
## Grandson          71.7         8     3.30
## Neuveville        76.9        15     5.16
## Echallens         68.3         2    24.20
## Lavaux            65.1         9     2.84
## Avenches          68.9        12     4.43
## Orbe              57.4         6     4.20
## Aigle             64.1        12     8.52
## Cossonay          61.7         5     2.82
## Morges            65.5        10     5.23
## Nyone             56.6        12    15.14
## Le Locle          72.7        13    11.22
## Rive Gauche       42.8        29    58.33
## ValdeTravers      67.6         7     8.65
## Vevey             58.3        19    18.46
## Boudry            70.4        12     5.62
## Lausanne          55.7        28    12.11
## La Chauxdfnd      65.7        11    13.79
## La Vallee         54.3        20     2.15
## Neuchatel         64.4        32    16.92
## V. De Geneve      35.0        53    42.34

Nájdeme oblasti, v ktorých je najmenšia a najväčšia Infant.Mortality

swiss[swiss$Infant.Mortality==max(swiss$Infant.Mortality), ]
##            Fertility Agriculture Examination Education Catholic
## Porrentruy      76.1        35.3           9         7    90.57
##            Infant.Mortality
## Porrentruy             26.6
swiss[swiss$Infant.Mortality==max(swiss$Infant.Mortality), ]
##            Fertility Agriculture Examination Education Catholic
## Porrentruy      76.1        35.3           9         7    90.57
##            Infant.Mortality
## Porrentruy             26.6

Domáca úloha

  1. Vykreslite závislosť premenných Education (na os x) od premennej Infant.Mortality (na os y) pre dáta Swiss a farebne odlíšte body, kde je Infant.Mortality nadpriemerná.

  2. Napíšte funkciu, ktorá určí, či sú dve vstupné množiny A, B (dané reálnymi vektormi) disjunktné. Ak nie sú disjunktné, vypíše ich prienik.

  3. Napíšte funkciu, ktorá pre daný vektor x vráti všetky prvky x, ktoré sú väčšie ako mean(x).