| Player | Tm | Opp | Result | MP | FG | FGA | FG% | 3P | 3PA | 3P% | FT | FTA | FT% | ORB | DRB | TRB | AST | STL | BLK | TOV | PF | PTS | +/- | GmSc | Date |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Luka Dončić | LAL | GSW | L | 40:59 | 17 | 27 | 0.630 | 2 | 10 | 0.200 | 7 | 10 | 0.700 | 0 | 12 | 12 | 9 | 2 | 1 | 3 | 1 | 43 | -8 | 38.9 | 2025-10-21 |
| Alperen Şengün | HOU | OKC | L | 48:53 | 12 | 24 | 0.500 | 5 | 8 | 0.625 | 10 | 11 | 0.909 | 4 | 7 | 11 | 7 | 2 | 1 | 4 | 5 | 39 | 9 | 33.1 | 2025-10-21 |
| Jimmy Butler | GSW | LAL | W | 34:44 | 7 | 14 | 0.500 | 1 | 2 | 0.500 | 16 | 16 | 1.000 | 2 | 3 | 5 | 4 | 1 | 0 | 1 | 4 | 31 | 20 | 27.5 | 2025-10-21 |
| Shai Gilgeous-Alexander | OKC | HOU | W | 47:13 | 12 | 26 | 0.462 | 1 | 9 | 0.111 | 10 | 14 | 0.714 | 0 | 5 | 5 | 5 | 2 | 2 | 3 | 2 | 35 | 3 | 24.6 | 2025-10-21 |
| Austin Reaves | LAL | GSW | L | 36:20 | 9 | 16 | 0.563 | 1 | 5 | 0.200 | 7 | 10 | 0.700 | 1 | 4 | 5 | 9 | 2 | 0 | 5 | 5 | 26 | -14 | 20.4 | 2025-10-21 |
| Chet Holmgren | OKC | HOU | W | 38:30 | 11 | 17 | 0.647 | 2 | 5 | 0.400 | 4 | 4 | 1.000 | 2 | 5 | 7 | 2 | 0 | 0 | 3 | 6 | 28 | -1 | 19.4 | 2025-10-21 |
| Stephen Curry | GSW | LAL | W | 32:04 | 6 | 14 | 0.429 | 3 | 9 | 0.333 | 8 | 8 | 1.000 | 0 | 1 | 1 | 4 | 3 | 1 | 2 | 3 | 23 | 1 | 19.2 | 2025-10-21 |
| Jonathan Kuminga | GSW | LAL | W | 32:54 | 6 | 11 | 0.545 | 4 | 6 | 0.667 | 1 | 2 | 0.500 | 3 | 6 | 9 | 6 | 1 | 0 | 2 | 3 | 17 | 4 | 17.2 | 2025-10-21 |
| Cason Wallace | OKC | HOU | W | 41:39 | 5 | 10 | 0.500 | 3 | 8 | 0.375 | 1 | 2 | 0.500 | 1 | 6 | 7 | 5 | 4 | 0 | 2 | 3 | 14 | 8 | 15.4 | 2025-10-21 |
| Kevin Durant | HOU | OKC | L | 47:03 | 9 | 16 | 0.563 | 0 | 4 | 0.000 | 5 | 6 | 0.833 | 0 | 9 | 9 | 3 | 0 | 0 | 4 | 6 | 23 | 0 | 13.4 | 2025-10-21 |
Výber databázy: NBA – štatistiky hráčov v zápasoch, sezóna 2025/26
Zadanie: výber databázy pre ďalšiu prácu
1 Výber databázy
Pre ďalšie hodiny som si zvolil databázu NBA Player Stats – Season 25/26, ktorá obsahuje štatistiky jednotlivých hráčov Národnej basketbalovej asociácie (NBA) zo všetkých odohraných zápasov sezóny 2025/26. Súbor som stiahol z platformy Kaggle (Kaggle Datasets) a uložil ako nba_dailyleaders_full.csv; ide o jeden súbor vo formáte CSV.
1.1 Čo databáza obsahuje
Jeden riadok predstavuje výkon jedného hráča v jednom zápase. Databáza má 28 716 záznamov, 582 rôznych hráčov a 30 tímov. Údaje sú zoradené v čase: pokrývajú obdobie od 21. 10. 2025 do 13. 6. 2026 (212 rôznych dní), teda základnú časť aj play-off. To spĺňa požiadavku, aby databáza obsahovala údaje zoradené v čase.
Hlavné premenné (názvy sú už v upravenej podobe, ktorú používam v ďalšej práci):
| Premenná | Význam |
|---|---|
player, tm, opp |
hráč, jeho tím, súper |
result |
výsledok zápasu pre tím hráča (W – výhra, L – prehra) |
date |
dátum zápasu |
mp |
odohrané minúty |
fg, fga, fg_percent |
úspešné strely z hry, pokusené strely z hry, úspešnosť streľby z hry |
p3fg, p3fga, p3fg_percent |
trojkové strely: úspešné, pokusené, úspešnosť |
ft, fta, ft_percent |
trestné hody: úspešné, pokusené, úspešnosť |
orb, drb, trb |
doskoky (ofenzívne, defenzívne, spolu) |
ast, stl, blk, tov, pf |
asistencie, zisky, bloky, straty, fauly |
pts |
body |
plus_minus |
rozdiel skóre počas hráčovej prítomnosti na ihrisku (+/-) |
gm_sc |
Game Score, súhrnná miera výkonu v zápase |
1.2 Čo s ňou plánujem robiť
Databáza je vhodná na hlbšiu analýzu, napríklad:
- vývoj výkonnosti hráčov a tímov v priebehu sezóny (trend v čase),
- porovnanie základnej časti a play-off,
- vplyv odohraných minút a úspešnosti streľby na body a Game Score,
- porovnanie domácich a hosťujúcich tímov, tímov podľa výsledku zápasu,
- regresný model pre Game Score alebo body.
2 Import údajov
Údaje som importoval zo súboru CSV. Nižšie je ukážka prvých desiatich riadkov v pôvodnej podobe (bez troch úplne prázdnych stĺpcov, ktoré sú súčasťou súboru a v čistení ich odstránim).
3 Čistenie údajov
3.1 Názvy premenných
V pôvodných názvoch stĺpcov sa vyskytujú znaky, ktoré v názvoch premenných v R nie sú prípustné (FG%, 3P, +/-). Použijem knižnicu janitor. Názvy, ktoré po úprave nie sú zrozumiteľné alebo začínajú číslicou, premenujem ručne:
+/-naplus_minus,- trojkové strely (
3P,3PA,3P%) nap3fg,p3fgaap3fg_percent. Názov nezačína číslicou, takže sa v kóde dá používať bez zvláštnych úprav.
Zobraziť kód
udaje <- clean_names(surove) %>%
rename(
plus_minus = x,
p3fg = x3p,
p3fga = x3pa,
p3fg_percent = x3p_percent
)
data.frame(
Povodny_nazov = names(surove),
Novy_nazov = names(udaje)
) %>%
kable(caption = "Pôvodné a nové názvy premenných") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE) %>%
row_spec(0, bold = TRUE, background = "#f2f2f2") %>%
scroll_box(height = "300px")| Povodny_nazov | Novy_nazov |
|---|---|
| Player | player |
| Tm | tm |
| Opp | opp |
| Result | result |
| MP | mp |
| FG | fg |
| FGA | fga |
| FG% | fg_percent |
| 3P | p3fg |
| 3PA | p3fga |
| 3P% | p3fg_percent |
| FT | ft |
| FTA | fta |
| FT% | ft_percent |
| ORB | orb |
| DRB | drb |
| TRB | trb |
| AST | ast |
| STL | stl |
| BLK | blk |
| TOV | tov |
| PF | pf |
| PTS | pts |
| +/- | plus_minus |
| GmSc | gm_sc |
| Date | date |
| Unnamed: 0 | unnamed_0 |
| Unnamed: 1 | unnamed_1 |
| Unnamed: 2 | unnamed_2 |
3.2 Chýbajúce hodnoty
Zobraziť kód
chyby <- colSums(is.na(udaje))
chyby[chyby > 0] fg_percent p3fg_percent ft_percent plus_minus unnamed_0 unnamed_1
1510 5775 12686 30 28716 28716
unnamed_2
28716
Tri stĺpce unnamed_0, unnamed_1 a unnamed_2 sú úplne prázdne (28 716 NA z 28 716 záznamov), preto ich odstránim.
Zobraziť kód
udaje <- udaje %>% select(-starts_with("unnamed"))Chýbajúce hodnoty v stĺpcoch fg_percent, p3fg_percent a ft_percent nevznikli chybou v údajoch. Úspešnosť sa nedá spočítať, ak hráč nemal žiadny pokus. Overím to:
Zobraziť kód
data.frame(
stlpec = c("fg_percent", "p3fg_percent", "ft_percent"),
pocet_NA = c(sum(is.na(udaje$fg_percent)),
sum(is.na(udaje$p3fg_percent)),
sum(is.na(udaje$ft_percent))),
pocet_bez_pokusu = c(sum(udaje$fga == 0),
sum(udaje$p3fga == 0),
sum(udaje$fta == 0))
) stlpec pocet_NA pocet_bez_pokusu
1 fg_percent 1510 1510
2 p3fg_percent 5775 5775
3 ft_percent 12686 12686
Počty sa zhodujú, takže ide o legitímne “nie je k dispozícii” a údaje nebudem imputovať. Imputácia by vymyslela úspešnosť hráčom, ktorí vôbec nestrieľali. V stĺpci plus_minus chýba 30 hodnôt, čo je zanedbateľné (0,1 %), a v analýzach s týmto stĺpcom ich vynechám.
3.3 Typy premenných
Minúty sú zapísané ako text "MM:SS" a dátum treba previesť na dátumový typ.
Zobraziť kód
udaje <- udaje %>%
mutate(
mp = sapply(strsplit(mp, ":", fixed = TRUE), function(x)
as.numeric(x[1]) + as.numeric(x[2]) / 60),
date = as.Date(date),
tm = as.factor(tm),
opp = as.factor(opp),
result = as.factor(result)
) %>%
arrange(date)
glimpse(udaje)Rows: 28,716
Columns: 26
$ player <chr> "Luka Dončić", "Alperen Şengün", "Jimmy Butler", "Shai Gi…
$ tm <fct> LAL, HOU, GSW, OKC, LAL, OKC, GSW, GSW, OKC, HOU, OKC, HO…
$ opp <fct> GSW, OKC, LAL, HOU, GSW, HOU, LAL, LAL, HOU, OKC, HOU, OK…
$ result <fct> L, L, W, W, L, W, W, W, W, L, W, L, W, L, W, W, W, L, L, …
$ mp <dbl> 40.98333, 48.88333, 34.73333, 47.21667, 36.33333, 38.5000…
$ fg <dbl> 17, 12, 7, 12, 9, 11, 6, 6, 5, 9, 6, 8, 6, 7, 2, 3, 3, 3,…
$ fga <dbl> 27, 24, 14, 26, 16, 17, 14, 11, 10, 16, 12, 17, 11, 15, 5…
$ fg_percent <dbl> 0.630, 0.500, 0.500, 0.462, 0.563, 0.647, 0.429, 0.545, 0…
$ p3fg <dbl> 2, 5, 1, 1, 1, 2, 3, 4, 3, 0, 3, 0, 5, 2, 0, 1, 2, 3, 1, …
$ p3fga <dbl> 10, 8, 2, 9, 5, 5, 9, 6, 8, 4, 6, 7, 10, 6, 1, 3, 6, 6, 3…
$ p3fg_percent <dbl> 0.200, 0.625, 0.500, 0.111, 0.200, 0.400, 0.333, 0.667, 0…
$ ft <dbl> 7, 10, 16, 10, 7, 4, 8, 1, 1, 5, 1, 2, 0, 0, 2, 1, 0, 0, …
$ fta <dbl> 10, 11, 16, 14, 10, 4, 8, 2, 2, 6, 1, 2, 0, 0, 2, 3, 0, 0…
$ ft_percent <dbl> 0.700, 0.909, 1.000, 0.714, 0.700, 1.000, 1.000, 0.500, 0…
$ orb <dbl> 0, 4, 2, 0, 1, 2, 0, 3, 1, 0, 1, 2, 0, 3, 5, 1, 0, 0, 1, …
$ drb <dbl> 12, 7, 3, 5, 4, 5, 1, 6, 6, 9, 1, 2, 1, 2, 3, 6, 2, 4, 1,…
$ trb <dbl> 12, 11, 5, 5, 5, 7, 1, 9, 7, 9, 2, 4, 1, 5, 8, 7, 2, 4, 2…
$ ast <dbl> 9, 7, 4, 5, 9, 2, 4, 6, 5, 3, 2, 5, 0, 0, 5, 9, 3, 3, 1, …
$ stl <dbl> 2, 2, 1, 2, 2, 0, 3, 1, 4, 0, 0, 1, 1, 1, 2, 1, 2, 0, 0, …
$ blk <dbl> 1, 1, 0, 2, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 2, 1, 0, 1, …
$ tov <dbl> 3, 4, 1, 3, 5, 3, 2, 2, 2, 4, 0, 4, 2, 0, 1, 4, 0, 1, 0, …
$ pf <dbl> 1, 5, 4, 2, 5, 6, 3, 3, 3, 6, 2, 3, 0, 4, 6, 5, 2, 2, 2, …
$ pts <dbl> 43, 39, 31, 35, 26, 28, 23, 17, 14, 23, 16, 18, 17, 16, 6…
$ plus_minus <dbl> -8, 9, 20, 3, -14, -1, 1, 4, 8, 0, 2, -11, 5, 2, 9, 20, -…
$ gm_sc <dbl> 38.9, 33.1, 27.5, 24.6, 20.4, 19.4, 19.2, 17.2, 15.4, 13.…
$ date <date> 2025-10-21, 2025-10-21, 2025-10-21, 2025-10-21, 2025-10-…
3.4 Kontrola konzistencie
Zobraziť kód
data.frame(
kontrola = c("úplne zhodné riadky",
"úspešné strely > pokusené (fg > fga)",
"úspešné trojky > pokusené (p3fg > p3fga)",
"úspešné trestné hody > pokusené (ft > fta)",
"doskoky spolu != ofenzívne + defenzívne"),
pocet = c(sum(duplicated(udaje)),
sum(udaje$fg > udaje$fga),
sum(udaje$p3fg > udaje$p3fga),
sum(udaje$ft > udaje$fta),
sum(udaje$trb != udaje$orb + udaje$drb))
) %>%
kable(col.names = c("Kontrola", "Počet nezrovnalostí")) %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE) %>%
row_spec(0, bold = TRUE, background = "#f2f2f2")| Kontrola | Počet nezrovnalostí |
|---|---|
| úplne zhodné riadky | 0 |
| úspešné strely > pokusené (fg > fga) | 0 |
| úspešné trojky > pokusené (p3fg > p3fga) | 0 |
| úspešné trestné hody > pokusené (ft > fta) | 0 |
| doskoky spolu != ofenzívne + defenzívne | 0 |
Duplicity ani logické nezrovnalosti sa v údajoch nenachádzajú. Záporné hodnoty v plus_minus a gm_sc sú správne, tieto ukazovatele môžu byť záporné. Odľahlé hodnoty (napr. 83 bodov v jednom zápase) sú skutočné výnimočné výkony, nie chyby, preto ich ponechám.
Zobraziť kód
write.csv2(udaje, "nba_cista.csv", row.names = FALSE, fileEncoding = "UTF-8")4 Základný prehľad čistých údajov
Zobraziť kód
cat("Obdobie:", format(min(udaje$date)), "až", format(max(udaje$date)), "\n")Obdobie: 2025-10-21 až 2026-06-13
Zobraziť kód
cat("Počet hráčov:", n_distinct(udaje$player), "| Počet tímov:", n_distinct(udaje$tm), "\n")Počet hráčov: 582 | Počet tímov: 30
Zobraziť kód
udaje %>%
select(mp, pts, trb, ast, p3fg, plus_minus, gm_sc) %>%
summary() mp pts trb ast
Min. : 0.00 Min. : 0.0 Min. : 0.000 Min. : 0.000
1st Qu.:14.80 1st Qu.: 4.0 1st Qu.: 1.000 1st Qu.: 1.000
Median :23.30 Median : 9.0 Median : 3.000 Median : 2.000
Mean :22.22 Mean :10.6 Mean : 4.022 Mean : 2.441
3rd Qu.:30.47 3rd Qu.:16.0 3rd Qu.: 6.000 3rd Qu.: 4.000
Max. :52.30 Max. :83.0 Max. :25.000 Max. :23.000
p3fg plus_minus gm_sc
Min. : 0.000 Min. :-60 Min. :-10.200
1st Qu.: 0.000 1st Qu.: -7 1st Qu.: 2.500
Median : 1.000 Median : 0 Median : 7.300
Mean : 1.217 Mean : 0 Mean : 8.635
3rd Qu.: 2.000 3rd Qu.: 7 3rd Qu.: 13.300
Max. :12.000 Max. : 52 Max. : 60.500
NA's :30
5 Ukážka časového radu
Pre kontrolu, že údaje sú naozaj usporiadané v čase, zobrazím priemerný počet bodov na hráča podľa dňa (zahrnuté sú len výkony s aspoň 10 odohranými minútami, aby sa nezapočítavali hráči s epizódnou rolou).
Zobraziť kód
denne <- udaje %>%
filter(mp >= 10) %>%
group_by(date) %>%
summarise(priemer_bodov = mean(pts), pocet_vykonov = n(), .groups = "drop")
ggplot(denne, aes(x = date, y = priemer_bodov)) +
geom_line(color = "#1d428a", alpha = 0.45, linewidth = 0.6) +
geom_smooth(method = "loess", formula = y ~ x, se = FALSE,
color = "#c8102e", linewidth = 1.3) +
scale_x_date(date_breaks = "1 month", date_labels = "%m/%Y") +
theme_minimal(base_size = 13) +
theme(
plot.title = element_text(face = "bold", color = "#1d428a"),
plot.subtitle = element_text(color = "grey40"),
panel.grid.minor = element_blank(),
axis.title = element_text(color = "grey30")
) +
labs(title = "Priemerný počet bodov na hráča počas sezóny 2025/26",
subtitle = "Modrá: denný priemer, červená: vyhladený trend",
x = "Dátum", y = "Priemer bodov")Červená čiara zobrazuje vyhladený trend. Jednotlivé dni sa líšia hlavne počtom odohraných zápasov, preto ďalej uvádzam aj mesačný prehľad:
Zobraziť kód
udaje %>%
filter(mp >= 10) %>%
mutate(mesiac = floor_date(date, "month")) %>%
group_by(mesiac) %>%
summarise(
vykony = n(),
body = mean(pts),
trojky = mean(p3fg),
game_score = mean(gm_sc),
.groups = "drop"
) %>%
kable(digits = 2,
col.names = c("Mesiac", "Počet výkonov", "Priemer bodov",
"Priemer úspešných trojok", "Priemer Game Score"),
caption = "Mesačné priemery (hráči s aspoň 10 minútami)") %>%
kable_styling(bootstrap_options = c("striped", "hover", "condensed"),
full_width = FALSE) %>%
row_spec(0, bold = TRUE, background = "#f2f2f2")| Mesiac | Počet výkonov | Priemer bodov | Priemer úspešných trojok | Priemer Game Score |
|---|---|---|---|---|
| 2025-10-01 | 1466 | 12.50 | 1.42 | 10.01 |
| 2025-11-01 | 4011 | 12.43 | 1.42 | 10.12 |
| 2025-12-01 | 3637 | 12.46 | 1.42 | 10.20 |
| 2026-01-01 | 4301 | 12.03 | 1.39 | 9.88 |
| 2026-02-01 | 3083 | 12.02 | 1.40 | 9.90 |
| 2026-03-01 | 4425 | 12.20 | 1.40 | 10.03 |
| 2026-04-01 | 2537 | 12.64 | 1.45 | 10.33 |
| 2026-05-01 | 636 | 12.42 | 1.37 | 9.83 |
| 2026-06-01 | 80 | 12.60 | 1.57 | 9.64 |