---
title: "Základné operácie v R"
subtitle: "Skaláre, text, logika, vektory, matice a vlastné čísla na príkladoch z basketbalu"
author: "Richard Vladyka <br> (s pomocou claude.ai)"
date: "September 2026"
lang: sk
format:
html:
toc: true
toc-location: left
toc-depth: 3
number-sections: true
theme: flatly
highlight-style: github
embed-resources: true
smooth-scroll: true
code-fold: show
code-tools: true
code-copy: true
fig-align: center
fig-dpi: 150
df-print: kable
execute:
echo: true
message: false
warning: false
editor:
markdown:
wrap: 72
---
```{=html}
<style>
:root { --nba-blue: #1d428a; --nba-orange: #e56020; --bg: #eef3fb; }
/* Jemné farebné pozadie */
html, body { background-color: var(--bg) !important; }
#quarto-margin-sidebar, #TOC { background-color: transparent !important; }
/* Font s plnou podporou slovenskej diakritiky (č, š, ž, ľ, ĺ, ŕ, ô ...) */
body, h1, h2, h3, h4, .title, .subtitle, .author, .date, #TOC {
font-family: -apple-system, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif !important;
}
body { font-size: 16px; line-height: 1.6; }
.subtitle { color: #4a5a75; }
h1, h2, h3 { color: var(--nba-blue); font-weight: 700; }
h1 { border-bottom: 3px solid var(--nba-orange); padding-bottom: .25em; margin-top: 2em; }
h2 { margin-top: 1.6em; }
pre, div.sourceCode { border-radius: 8px; }
div.sourceCode { border-left: 4px solid var(--nba-orange); background-color: #ffffff; }
table { margin: 1em auto; background-color: #ffffff; }
blockquote { border-left: 4px solid var(--nba-blue); background: #e3ebf8;
padding: .6em 1em; border-radius: 0 6px 6px 0; }
.callout { border-radius: 8px; }
figcaption { font-style: italic; text-align: center; }
</style>
```
# Úvod
Tento notebook demonštruje **základné operácie** v jazyku R s:
- skalárnymi číslami (t. j. 1 číslo),
- textovými (znakovými) reťazcami,
- logickými (boolovskými) hodnotami,
- numerickými vektormi,
- maticami,
- vlastnými číslami a vlastnými vektormi.
Väčšinu ukážok sme postavili na **štatistikách z basketbalu (NBA)**.
Hodnoty sú ilustratívne a slúžia len na precvičenie.
---
# Skaláre (jednočíselné hodnoty)
## Numerické skaláre
```{r}
# Priradenie konštanty do premennej
a <- 24 # napr. body hráča v zápase
b <- 4.5 # napr. asistencie hráča v zápase
# Aritmetika
sum_ab <- a + b # súčet
diff_ab <- a - b # rozdiel
prod_ab <- a * b # násobenie
quot_ab <- a / b # delenie
power_ab <- a ^ b # umocňovanie
mod_ab <- a %% 5 # zvyšok po delení piatimi (modulo)
int_div_ab <- a %/% b # celočíselné delenie
# Zaokrúhľovanie
round_b <- round(b) # zaokrúhlenie na najbližšie celé číslo
ceil_b <- ceiling(b) # najbližšie vyššie celé číslo
floor_b <- floor(b) # najbližšie nižšie celé číslo
a; b
sum_ab; diff_ab; prod_ab; quot_ab; power_ab; mod_ab; int_div_ab
round_b; ceil_b; floor_b
```
::: {.callout-tip}
## Poznámky
- `^` je operátor umocňovania.
- `%%` je modulo, teda zvyšok po delení; `%/%` je celočíselné delenie.
- `round(x, digits = 0)` zaokrúhľuje na zadaný počet desatinných miest.
R pri hodnote presne uprostred zaokrúhľuje na párne číslo, preto
`round(4.5)` dá `4`, ale `round(5.5)` dá `6`.
:::
## Príklad z NBA: úspešnosť streľby
```{r}
trojky_trafene <- 9
trojky_pokusy <- 17
uspesnost_3p <- trojky_trafene / trojky_pokusy * 100
uspesnost_3p
round(uspesnost_3p, 1) # zaokrúhlenie na 1 desatinné miesto
```
## Malé cvičenie
> Vypočítajte:
$$\frac{(18^2-9)}{5}$$
```{r}
(18^2 - 9) / 5
```
---
# Text
## Vytváranie textových premenných a práca s nimi
```{r}
meno <- "Nikola" # obsah textovej premennej meno
priezv <- "Jokic" # obsah textovej premennej priezv
cele <- paste(meno, priezv) # spojenie s medzerou
bez_med <- paste0(meno, priezv) # spojenie bez medzery
csv_riadok <- paste("Denver", "Boston", "Miami", sep = ",") # oddeľovač ","
meno; priezv; cele; bez_med; csv_riadok
```
## Dĺžka textového reťazca a podreťazec
```{r}
x <- "Triple-double!"
nchar(x) # počet znakov
substr(x, 1, 6) # podreťazec od 1. do 6. znaku
toupper(x) # veľké písmená
tolower(x) # malé písmená
```
## Príklad z NBA: tímové skratky
```{r}
tim <- "Golden State Warriors"
skratka <- toupper(substr(tim, 1, 3))
paste("Skratka tímu", tim, "je", skratka)
```
::: {.callout-tip}
Knižnica **stringr** ponúka mnoho ďalších možností práce s textom, no
základné funkcie R pokrývajú väčšinu bežných potrieb.
:::
---
# Logické (boolovské) hodnoty
## Základy
```{r}
p <- TRUE # hráč dal aspoň 20 bodov
q <- FALSE # hráč mal aspoň 10 asistencií
!p # NOT
p & q # AND
p | q # OR
xor(p, q) # exclusive OR - platí práve jedno z p, q
```
## Logický výsledok porovnávania
```{r}
25 < 30
12 >= 12
"Lakers" == "Lakers"
"Lakers" != "Celtics" # != znamená "nerovná sa"
!TRUE
```
## Zložitejšie logické operácie
```{r}
body <- 27
asistencie <- 11
doskoky <- 4
body > 20 & asistencie > 10 # súčasne (logický prienik)
body > 40 | asistencie > 15 # alebo (logické zjednotenie)
# Double-double: aspoň 10 v dvoch štatistikách
double_double <- (body >= 10) + (asistencie >= 10) + (doskoky >= 10) >= 2
double_double
```
::: {.callout-tip}
Pri zložitejších podmienkach používajte okrúhle zátvorky `()`.
:::
## Zlučovanie logických hodnôt do vektora
```{r}
# Skóroval hráč v posledných 4 zápasoch aspoň 25 bodov?
vals <- c(TRUE, FALSE, TRUE, TRUE)
sum(vals) # počet zápasov s aspoň 25 bodmi (TRUE = 1)
mean(vals) # podiel takýchto zápasov
```
---
# Numerické vektory
## Generovanie vektorov
```{r}
set.seed(2026) # aby boli náhodné čísla reprodukovateľné
v1 <- c(3, 6, 9, 12) # zadanie prvkov ručne
v2 <- 1:8 # postupnosť 1, 2, ..., 8
v3 <- seq(from = 0, to = 2, by = 0.5) # postupnosť s krokom 0.5
v4 <- rep(2, times = 6) # 2, 2, 2, 2, 2, 2
v5 <- runif(5) # rovnomerné rozdelenie na [0, 1]
v6 <- rnorm(5) # normálne rozdelenie N(0, 1)
v1; v2; v3; v4; v5; v6
```
## Príklad z NBA: body v 5 zápasoch
```{r}
body_zapasy <- c(31, 28, 35, 22, 40)
names(body_zapasy) <- paste("Zápas", 1:5)
body_zapasy
```
## Aritmetické operácie s vektormi
```{r}
v <- c(2, 4, 6, 8)
v + 10 # každý prvok zväčšíme o 10
v * 3 # každý prvok vynásobíme 3
(v + 1) / 2
exp(v) # exponenciálna funkcia z každého prvku
sum(c(1, 2, 3) * c(2, 2, 2)) # skalárny súčin - výsledok je skalár
crossprod(c(1, 2, 3), c(2, 2, 2)) # skalárny súčin - výsledok je matica 1x1
c(1, 2, 3) * c(2, 2, 2) # Hadamardov súčin (po prvkoch)
```
## Operácie s dvoma vektormi rovnakého rozmeru
```{r}
body <- c(31, 28, 35, 22, 40)
minuty <- c(36, 34, 38, 30, 41)
length(body)
length(minuty)
body / minuty # body na minútu v každom zápase
round(body / minuty * 36, 1) # prepočet na 36 minút
```
::: {.callout-warning}
Pri operáciách po prvkoch musia mať oba vektory rovnakú dĺžku. Pri
rôznych dĺžkach R vektor kratší "recykluje", čo býva zdrojom chýb.
:::
## Indexovanie a výber prvkov vektora
```{r}
x <- c(25, 14, 33, 8, 41, 19, 30) # body v 7 zápasoch
x[1] # prvý prvok
x[2:4] # druhý až štvrtý prvok
x[-1] # všetky prvky okrem prvého
x[x > 25] # zápasy s viac ako 25 bodmi
which(x > 25) # poradie týchto zápasov
```
## Práca s chýbajúcimi hodnotami
```{r}
# Hráč v 2. a 4. zápase nenastúpil (DNP) - chýbajúce hodnoty NA
y <- c(22, NA, 30, NA, 27)
is.na(y)
mean(y) # NA
mean(y, na.rm = TRUE) # NA ignorujeme
```
## Základné štatistiky a usporiadanie prvkov
```{r}
z <- c(18, 25, 31, 12, 27)
mean(z) # priemer
sd(z) # smerodajná odchýlka
max(z) # maximum
summary(z) # rýchly prehľad
sort(z) # vzostupne
sort(z, decreasing = TRUE) # zostupne
```
## Malé cvičenie
> Vytvorte vektor `w` s číslami 1 až 30 a vypočítajte súčet všetkých
> nepárnych čísel.
```{r}
w <- 1:30
sum(w[w %% 2 == 1])
```
---
# Matice
## Vytvorenie matíc
```{r}
m <- matrix(1:12, nrow = 3, ncol = 4) # hodnoty po stĺpcoch
m_byrow <- matrix(1:12, nrow = 3, byrow = TRUE) # hodnoty po riadkoch
m; m_byrow
```
## Príklad z NBA: body troch hráčov v štyroch zápasoch
```{r}
body_mat <- matrix(c(30, 25, 28, 33,
22, 27, 31, 24,
18, 20, 15, 26),
nrow = 3, byrow = TRUE,
dimnames = list(c("Hráč A", "Hráč B", "Hráč C"),
paste("Zápas", 1:4)))
knitr::kable(body_mat, caption = "Body hráčov v jednotlivých zápasoch")
```
## Rozmery matice
```{r}
dim(m) # (riadky, stĺpce)
nrow(m); ncol(m)
```
## Adresovanie prvkov matice
```{r}
body_mat[1, 2] # Hráč A, 2. zápas
body_mat[, 3] # všetci hráči v 3. zápase
body_mat["Hráč B", ] # všetky zápasy hráča B
body_mat[1:2, 2:3] # podmatica: riadky 1-2, stĺpce 2-3
```
## Maticové operácie
```{r}
A <- matrix(c(2, 0, 1, 3), nrow = 2)
B <- matrix(c(1, 4, 2, 5), nrow = 2)
A + B # sčítanie matíc
A * B # Hadamardov súčin (po prvkoch)
A %*% B # násobenie matíc
t(A) # transpozícia
det(A) # determinant
solve(A) # inverzia (ak existuje)
```
## Zlučovanie vektorov do matíc
```{r}
body_hrac1 <- c(30, 25, 28)
body_hrac2 <- c(22, 27, 31)
cbind(body_hrac1, body_hrac2) # po stĺpcoch
rbind(body_hrac1, body_hrac2) # po riadkoch
```
## Štatistiky po riadkoch (stĺpcoch) matice
```{r}
apply(body_mat, 1, mean) # priemer bodov každého hráča (po riadkoch)
apply(body_mat, 2, sum) # súčet bodov v každom zápase (po stĺpcoch)
rowMeans(body_mat) # to isté skrátene
colSums(body_mat)
```
## Malé cvičenie
> Vytvorte maticu 4x4 s hodnotami 1 až 16 po riadkoch, vypočítajte
> stĺpcové sumy a súčin matíc $M^T M$.
```{r}
M2 <- matrix(1:16, nrow = 4, byrow = TRUE)
colSums(M2)
t(M2) %*% M2
```
---
# Vlastné čísla a vlastné vektory matíc
## Čo znamenajú?
Nech $\mathbf A$ je štvorcová matica. **Vlastné číslo** $\lambda$ a
príslušný **vlastný vektor** $\mathbf h \ne \mathbf 0$ spĺňajú vzťah
$$
\mathbf A \mathbf h = \lambda \mathbf h.
$$
Násobenie maticou $\mathbf A$ teda pôsobí na vlastný vektor ako
násobenie číslom $\lambda$: smer ostáva zachovaný (pri $\lambda < 0$ sa
obráti) a dĺžka sa násobí hodnotou $|\lambda|$.
## Príklad 2 × 2: ručný výpočet
Použijeme symetrickú maticu ($\mathbf A^T = \mathbf A$), aké sa
používajú napríklad ako variančno-kovariančné matice:
$$
\mathbf A =
\begin{pmatrix}
3 & 1 \\
1 & 3
\end{pmatrix}.
$$
Z podmienky $(\mathbf A - \lambda \mathbf I)\mathbf h = \mathbf 0$ má
sústava netriviálne riešenie práve vtedy, keď
$\det(\mathbf A-\lambda \mathbf I)=0$, teda
$$
\begin{vmatrix}
3-\lambda & 1 \\
1 & 3-\lambda
\end{vmatrix}
=
\lambda^2-6\lambda+8
=
(\lambda-4)(\lambda-2)
=
0
\quad\Longrightarrow\quad
\lambda_1=4,\ \lambda_2=2.
$$
**Vlastné vektory** dostaneme dosadením do $(\mathbf A-\lambda\mathbf I)\mathbf h=\mathbf 0$
a normalizáciou na dĺžku 1:
- pre $\lambda_1=4$ dostávame $-h_{1}+h_{2}=0$, teda $h_1=h_2$,
- pre $\lambda_2=2$ dostávame $h_{1}+h_{2}=0$, teda $h_2=-h_1$.
$$
\mathbf h_1=
\begin{pmatrix}
\sqrt{1/2}\\
\sqrt{1/2}
\end{pmatrix},
\qquad
\mathbf h_2=
\begin{pmatrix}
\sqrt{1/2}\\
-\sqrt{1/2}
\end{pmatrix}.
$$
Každý nenulový násobok týchto vektorov je tiež vlastným vektorom. Keďže
je $\mathbf A$ symetrická, vlastné vektory sú navzájom kolmé:
$\mathbf h_1^T\mathbf h_2 = \tfrac12 - \tfrac12 = 0$.
## Výpočet pomocou funkcie `eigen()`
Funkcia `eigen()` je súčasťou základného R. Argument `symmetric = TRUE`
použijeme, keď vieme, že matica je symetrická.
```{r}
#| label: eigen-vypocet
A_eig <- matrix(c(3, 1,
1, 3),
nrow = 2, byrow = TRUE)
eig_A <- eigen(A_eig, symmetric = TRUE) # výsledok je list
eig_A
lambda_A <- eig_A$values # vlastné čísla
V_A <- eig_A$vectors # vlastné vektory v stĺpcoch
# Overenie vzťahu A v = lambda v pre prvý vlastný pár
all.equal(as.vector(A_eig %*% V_A[, 1]), lambda_A[1] * V_A[, 1])
```
Znak `$` vyberá pomenovanú zložku listu (`eig_A$values`,
`eig_A$vectors`). R vracia vlastné čísla zostupne a vlastné vektory
s jednotkovou dĺžkou; od našich ručne zvolených sa môžu líšiť
znamienkom, pretože $\mathbf v$ aj $-\mathbf v$ sú rovnako správne.
## Geometrické znázornenie
Pri vlastnom vektore zostáva jeho obraz $\mathbf A\mathbf x$ na tej
istej priamke ako $\mathbf x$: vľavo je 4-krát dlhší, vpravo 2-krát.
```{r}
#| label: eigen-geometria
#| fig-width: 9
#| fig-height: 4
#| fig-cap: "Vektor x (modrá, prerušovaná) a jeho obraz Ax (oranžová) pre dva vlastné vektory."
local({
povodne <- par(mfrow = c(1, 2), mar = c(4, 4, 3, 1), bg = "white")
on.exit(par(povodne))
priklady <- list(c(1, 1), c(1, -1))
nazvy <- c("Vlastný vektor: lambda = 4",
"Vlastný vektor: lambda = 2")
for (j in seq_along(priklady)) {
x_plot <- priklady[[j]]
Ax_plot <- as.vector(A_eig %*% x_plot)
plot(NA, xlim = c(-2, 5), ylim = c(-3, 5),
asp = 1, xlab = "Prvá súradnica", ylab = "Druhá súradnica",
main = nazvy[j], cex.main = 0.9)
abline(h = 0, v = 0, col = "grey80")
arrows(0, 0, Ax_plot[1], Ax_plot[2],
col = "#e56020", lwd = 4, length = 0.12)
arrows(0, 0, x_plot[1], x_plot[2],
col = "#1d428a", lwd = 2, lty = 2, length = 0.10)
legend("topleft", legend = c("x", "Ax"),
col = c("#1d428a", "#e56020"),
lty = c(2, 1), lwd = c(2, 4), bty = "n", cex = 0.8)
}
})
```
## Matica 3 × 3, stopa a determinant
Pre štvorcovú maticu platí: súčet vlastných čísel sa rovná stope matice
(súčtu diagonálnych prvkov) a ich súčin sa rovná determinantu.
```{r}
#| label: eigen-tri-krat-tri
B_eig <- matrix(c(3, 1, 0,
1, 3, 0,
0, 0, 5), nrow = 3, byrow = TRUE)
eig_B <- eigen(B_eig, symmetric = TRUE)
eig_B$values # 5, 4, 2
c(sucet_vlastnych_cisel = sum(eig_B$values), # obe hodnoty sú 11
stopa_matice = sum(diag(B_eig)))
c(sucin_vlastnych_cisel = prod(eig_B$values), # obe hodnoty sú 40
determinant = det(B_eig))
```
## Malé cvičenie
Pre variančno-kovariančnú maticu štatistík hráča (body, doskoky,
asistencie na zápas) vypočítajte vlastné čísla a vlastné vektory.
| Štatistika | **Body** | **Doskoky** | **Asistencie** |
|:---|:---|:---|:---|
| **Body** | `36.00` | `6.00` | `8.00` |
| **Doskoky** | `6.00` | `9.00` | `2.50` |
| **Asistencie** | `8.00` | `2.50` | `6.25` |
```{r}
# Vytvorenie matice
C <- matrix(c(
36.00, 6.00, 8.00, # Body
6.00, 9.00, 2.50, # Doskoky
8.00, 2.50, 6.25 # Asistencie
), nrow = 3, byrow = TRUE,
dimnames = list(c("Body", "Doskoky", "Asistencie"),
c("Body", "Doskoky", "Asistencie")))
C
# Doplňte: výpočet a výpis vlastných čísel a vlastných vektorov
```
Nápoveda k funkcii `eigen()`:
[R: eigen()](https://stat.ethz.ch/R-manual/R-devel/library/base/html/eigen.html).