Budeme modelovať vývoj HDP jednotlivých provincií Číny v závislosti od roku. Zameriame sa na skúmanie trendu rastu a rozdielov medzi regiónmi.
-> HDP všetkých provincií rastie v čase (očakávame kladný trend) -> Rýchlosť rastu sa však líši medzi regiónmi (napr. Guangdong vs. Tibet)
# Načítanie dát
udaje <- read.csv2("Chinas GDP in Province En.csv", header = TRUE, sep = ",", dec = ".")
# Pozrime si štruktúru
str(udaje)## 'data.frame': 29 obs. of 32 variables:
## $ X : int 2020 2019 2018 2017 2016 2015 2014 2013 2012 2011 ...
## $ Beijing : num 36103 35445 33106 29883 27041 ...
## $ Tianjin : num 14084 14056 13363 12451 11477 ...
## $ Hebei : num 36207 34979 32495 30641 28474 ...
## $ Shanxi : num 17652 16962 15958 14484 11946 ...
## $ Inner.Mongolia: num 17360 17212 16141 14898 13789 ...
## $ Liaoning : num 25115 24855 23510 21693 20392 ...
## $ Jilin : num 12311 11727 11254 10922 10427 ...
## $ Heilongjiang : num 13698 13544 12846 12313 11895 ...
## $ Shanghai : num 38701 37988 36012 32925 29887 ...
## $ Jiangsu : num 102719 98657 93208 85870 77351 ...
## $ Zhejiang : num 64613 62462 58003 52403 47254 ...
## $ Anhui : num 38681 36846 34011 29676 26308 ...
## $ Fujian : num 43904 42327 38688 33842 29609 ...
## $ Jiangxi : num 25692 24667 22716 20211 18389 ...
## $ Shandong : num 73129 70540 66649 63012 58762 ...
## $ Henan : num 54997 53718 49936 44825 40249 ...
## $ Hubei : num 43444 45429 42022 37235 33353 ...
## $ Hunan : num 41782 39894 36330 33828 30854 ...
## $ Guangdong : num 110761 107987 99945 91649 82163 ...
## $ Guangxi. : num 22157 21237 19628 17791 16117 ...
## $ Hainan : num 5532 5331 4911 4498 4090 ...
## $ Chongqing : num 25003 23606 21589 20066 18023 ...
## $ Sichuan : num 48599 46364 42902 37905 33138 ...
## $ Guizhou : num 17827 16769 15353 13605 11792 ...
## $ Yunnan : num 24522 23224 20881 18486 16369 ...
## $ Tibet : num 1903 1698 1548 1349 1173 ...
## $ Shaanxi : num 26182 25793 23942 21474 19046 ...
## $ Gansu : num 9017 8718 8104 7337 6908 ...
## $ Qinghai : num 3006 2941 2748 2465 2258 ...
## $ Ningxia : num 3921 3748 3510 3200 2781 ...
## $ Xinjiang : num 13798 13597 12809 11160 9631 ...
# Premenujeme stĺpec s rokmi, ak má neštandardný názov
names(udaje)[1] <- "Year"
# Z údajov si vyberieme obdobie po roku 2000 (modernejšia ekonomika)
udaje.modern <- udaje[udaje$Year >= 2000, ]
# Základné čistenie - nahradíme chýbajúce hodnoty mediánom každej provincie
column_medians <- sapply(udaje.modern[,-1], median, na.rm = TRUE)
udaje_imputed <- udaje.modern
for (col in names(udaje.modern)[-1]) {
udaje_imputed[[col]][is.na(udaje_imputed[[col]])] <- column_medians[col]
}
udaje.modern <- udaje_imputed##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(tidyr)
# Premeníme dáta do long formátu (rok, provincia, HDP)
udaje_long <- udaje.modern %>%
pivot_longer(cols = -Year, names_to = "Province", values_to = "GDP")
# Pridáme nový ukazovateľ - medziročný rast HDP (%)
udaje_long <- udaje_long %>%
group_by(Province) %>%
arrange(Year) %>%
mutate(GDP_growth = 100 * (GDP - lag(GDP)) / lag(GDP))# Priemerný medziročný rast HDP za celé obdobie
avg_growth <- udaje_long %>%
group_by(Province) %>%
summarise(AverageGrowth = mean(GDP_growth, na.rm = TRUE)) %>%
arrange(desc(AverageGrowth))
# Top 10 provincií s najrýchlejším rastom
top10 <- head(avg_growth, 10)
# Vizualizácia: Top 10 rastúcich provincií
ggplot(top10, aes(x = reorder(Province, AverageGrowth), y = AverageGrowth, fill = Province)) +
geom_col(show.legend = FALSE) +
coord_flip() +
labs(title = "Top 10 čínskych provincií podľa priemerného rastu HDP (2000–2020)",
x = "Provincia", y = "Priemerný medziročný rast HDP (%)") +
theme_minimal(base_size = 13)# Vyberme napríklad Guangdong (ekonomický líder)
guangdong <- udaje_long %>% filter(Province == "Guangdong")
# Jednoduchý lineárny model rastu HDP ~ rok
model <- lm(GDP ~ Year, data = guangdong)
summary(model)##
## Call:
## lm(formula = GDP ~ Year, data = guangdong)
##
## Residuals:
## Min 1Q Median 3Q Max
## -6759 -4303 -2994 4132 11842
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -1.050e+07 4.198e+05 -25.02 5.26e-16 ***
## Year 5.250e+03 2.088e+02 25.14 4.80e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 5795 on 19 degrees of freedom
## Multiple R-squared: 0.9708, Adjusted R-squared: 0.9693
## F-statistic: 632.1 on 1 and 19 DF, p-value: 4.801e-16
# Vizualizácia trendu
ggplot(guangdong, aes(x = Year, y = GDP)) +
geom_line(color = "#0072B2", size = 1.2) +
geom_smooth(method = "lm", se = TRUE, color = "#E69F00") +
labs(title = "Trend HDP provincie Guangdong (2000–2020)",
subtitle = paste0("Odhadovaný ročný rast: ",
round(coef(model)[2], 1), " mld. CNY / rok"),
x = "Rok", y = "HDP (mld. CNY)") +
theme_minimal(base_size = 13)## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `geom_smooth()` using formula = 'y ~ x'
Predpokladáme, že máme dátový rámec udaje.modern (rok + provincie) alebo jeho verziu po imputácii chýbajúcich údajov
# Vynecháme stĺpec s rokom
udaje_numeric <- udaje.modern[, -1]
# Zistíme globálny rozsah hodnôt HDP vo všetkých provinciách
global_range <- range(udaje_numeric, na.rm = TRUE)
# Počet premenných (provincie)
num_plots <- ncol(udaje_numeric)
# Nastavíme rozloženie grafov – 4x4, aby sme videli viac naraz
par(mfrow = c(4, 4))
par(mar = c(3.5, 3.5, 2, 1)) # okraje grafov
# Kreslenie boxplotov pre každú provinciu
for (col in names(udaje_numeric)) {
data_col <- udaje_numeric[[col]]
# Boxplot pre danú provinciu
boxplot(data_col,
main = col,
col = ifelse(any(data_col == 0, na.rm = TRUE), "tomato", "lightblue"),
ylab = "HDP (mld. CNY)",
cex.main = 0.8,
ylim = global_range) # <<< rovnaký rozsah pre všetky
}# Globálny titulok pre všetky grafy
mtext("Boxploty HDP jednotlivých provincií Číny (2000–2020)",
outer = TRUE, cex = 1.3, font = 2)
# Obnovíme pôvodné nastavenie grafov
par(mfrow = c(1, 1))
## Kontrola nulových hodnôt v dataset-e
# Počet nulových hodnôt v každej provincii
nulove <- sapply(udaje_numeric, function(x) sum(x == 0, na.rm = TRUE))
# Zobraz provincie s nulami (ak existujú)
nulove_df <- data.frame(Provincia = names(nulove),
PocetNul = nulove)
# Zobrazíme len provincie, kde sa nuly vyskytli
nulove_df <- subset(nulove_df, PocetNul > 0)
if(nrow(nulove_df) > 0) {
print("Provinicie obsahujúce nulové hodnoty HDP:")
print(nulove_df)
} else {
print("V dátach sa nenachádzajú žiadne nulové hodnoty HDP.")
}## [1] "V dátach sa nenachádzajú žiadne nulové hodnoty HDP."
# Vyberieme si konkrétnu provinciu, napr. Guangdong (ekonomický líder)
province_name <- "Guangdong"
# Vytvoríme podmnožinu dát pre danú provinciu
data_prov <- data.frame(
Year = udaje.modern$Year,
GDP = udaje.modern[[province_name]]
)
# Skontrolujeme, či tam nie sú chýbajúce hodnoty
sum(is.na(data_prov$GDP))## [1] 0
# Odhadneme lineárny model HDP ~ rok
model <- lm(GDP ~ Year, data = data_prov)
# Výpis základných výsledkov
cat("✅ Odhadnuté koeficienty modelu pre provinciu", province_name, ":\n")## ✅ Odhadnuté koeficienty modelu pre provinciu Guangdong :
## (Intercept) Year
## -10502068.979 5250.519
##
## Priemerný medziročný rast HDP: 5250.52 mld. CNY
##
## Call:
## lm(formula = GDP ~ Year, data = data_prov)
##
## Residuals:
## Min 1Q Median 3Q Max
## -6759 -4303 -2994 4132 11842
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -1.050e+07 4.198e+05 -25.02 5.26e-16 ***
## Year 5.250e+03 2.088e+02 25.14 4.80e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 5795 on 19 degrees of freedom
## Multiple R-squared: 0.9708, Adjusted R-squared: 0.9693
## F-statistic: 632.1 on 1 and 19 DF, p-value: 4.801e-16
# Nastavíme grafické parametre
par(mfrow = c(1, 1))
plot(data_prov$Year, data_prov$GDP,
main = paste("Lineárna regresia rastu HDP -", province_name),
xlab = "Rok", ylab = "HDP (mld. CNY)",
pch = 16, col = "skyblue")
# Regresná priamka
abline(model, col = "red", lwd = 2)
# Doplníme text s R²
r2 <- summary(model)$r.squared
legend("topleft", legend = paste("R² =", round(r2, 3)),
bty = "n", text.col = "red")par(mfrow = c(2, 2))
plot(model)
mtext(paste("Diagnostické grafy pre model provincie", province_name),
outer = TRUE, cex = 1.2, font = 2)# Vytvoríme nový dataset s budúcimi rokmi
future_years <- data.frame(Year = seq(2021, 2025, by = 1))
# Predikcia pomocou modelu
pred <- predict(model, newdata = future_years, interval = "prediction")
# Spojíme s rokmi
pred_df <- data.frame(future_years, pred)
cat("\n📈 Odhadovaný HDP provincie", province_name, "do roku 2025:\n")##
## 📈 Odhadovaný HDP provincie Guangdong do roku 2025:
## Year fit lwr upr
## 1 2021 109229.6 95916.15 122543.0
## 2 2022 114480.1 101002.64 127957.6
## 3 2023 119730.6 106077.10 133384.1
## 4 2024 124981.1 111139.99 138822.3
## 5 2025 130231.7 116191.77 144271.5
# Vizualizácia predikcie
plot(data_prov$Year, data_prov$GDP,
main = paste("Predikcia HDP do roku 2025 –", province_name),
xlab = "Rok", ylab = "HDP (mld. CNY)",
pch = 16, col = "skyblue", xlim = c(2000, 2025))
abline(model, col = "red", lwd = 2)
lines(pred_df$Year, pred_df$fit, col = "darkgreen", lwd = 2, lty = 2)
lines(pred_df$Year, pred_df$lwr, col = "gray50", lty = 3)
lines(pred_df$Year, pred_df$upr, col = "gray50", lty = 3)
legend("topleft", legend = c("Skutočné údaje", "Regresná priamka", "Predikcia 2021–2025"),
col = c("skyblue", "red", "darkgreen"), pch = c(16, NA, NA), lty = c(NA, 1, 2),
bty = "n")# Vykreslenie základného diagnostického grafu
plot(model$fitted.values, model$residuals,
main = paste("Rezíduá vs. prispôsobené hodnoty –", province_name),
xlab = "Predikované hodnoty HDP (mld. CNY)",
ylab = "Rezíduá (skutočné - predikované)",
pch = 19, col = "steelblue")
abline(h = 0, col = "red", lwd = 2)
# Pridáme hladkú čiaru LOESS, ktorá pomáha odhaliť nelinearity
lines(lowess(model$fitted.values, model$residuals), col = "orange", lwd = 2)Rezíduá oscilujú okolo nulovej osi → model nie je systematicky skreslený. Oranžová LOESS krivka je relatívne plochá → lineárny model je postačujúci. Vertikálny rozptyl rezíduí je približne rovnaký → nepozorujeme heteroskedasticitu. Ak by sa body rozširovali do tvaru lievika, znamenalo by to problém s variabilitou chýb. Niekoľko bodov výrazne mimo centrálneho pásma môže byť potenciálne odľahlé pozorovanie.
qqnorm(model$residuals,
main = paste("Q–Q graf rezíduí –", province_name),
pch = 19, col = "steelblue")
qqline(model$residuals, col = "red", lwd = 2)Väčšina bodov leží blízko červenej čiary → rezíduá sú približne normálne rozložené. Mierne odchýlky na okrajoch (vľavo dole a vpravo hore) naznačujú len malé odchýlky od normálneho tvaru. Predpoklad normality je teda približne splnený.
# Vypočítame štandardizované rezíduá
std_resid <- rstandard(model)
# Druhá odmocnina absolútnych štandardizovaných rezíduí
sqrt_abs_std_resid <- sqrt(abs(std_resid))
plot(model$fitted.values, sqrt_abs_std_resid,
main = paste("Scale–Location graf –", province_name),
xlab = "Predikované hodnoty HDP (mld. CNY)",
ylab = expression(sqrt("|Štandardizované rezíduá|")),
pch = 19, col = "skyblue")
lines(lowess(model$fitted.values, sqrt_abs_std_resid), col = "red", lwd = 2)Body sú približne rovnomerne rozptýlené po osi X – variancia rezíduí sa javí ako konštantná (homoskedasticita). Červená LOESS čiara je relatívne plochá – čo potvrdzuje stabilný rozptyl chýb. Niekoľko bodov s mierne vyššími hodnotami (nad 1,5) môže indikovať roky s atypickým rastom HDP, ale bez extrémnych odchýlok.
Väčšina rokov má nízky pákový efekt (<0.05), čo znamená, že jednotlivé roky výrazne neovplyvňujú tvar regresie. Niekoľko bodov vpravo s vyššou hodnotou leverage (napr. po roku 2015) môže mať väčší vplyv na sklon regresnej priamky – ide o roky s neobvykle vysokým HDP. Bodkované kontúry Cookovej vzdialenosti ukazujú, že žiadne pozorovanie výrazne neprekračuje prah 0.5 → žiadny extrémny vplyv.
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
## Loading required package: carData
##
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
##
## recode
residuals <- residuals(model)
# Jarque–Bera test normality
jb_test <- jarque.bera.test(residuals)
cat("\n📊 Jarque–Bera test normality:\n")##
## 📊 Jarque–Bera test normality:
##
## Jarque Bera Test
##
## data: residuals
## X-squared = 2.4675, df = 2, p-value = 0.2912
# Outlier test
outlier_test <- outlierTest(model)
cat("\n📊 Test odľahlých pozorovaní (Bonferroni):\n")##
## 📊 Test odľahlých pozorovaní (Bonferroni):
## No Studentized residuals with Bonferroni p < 0.05
## Largest |rstudent|:
## rstudent unadjusted p-value Bonferroni p
## 21 2.561709 0.019613 0.41188
Ak sa ukáže, že rezíduá nie sú normálne rozdelené alebo majú heteroskedasticitu, transformujeme HDP pomocou logaritmu. Tým dostaneme model, ktorý lepšie vystihuje percentuálny rast HDP.
##
## Call:
## lm(formula = log(GDP) ~ Year, data = data_prov)
##
## Residuals:
## Min 1Q Median 3Q Max
## -0.203248 -0.081222 -0.005315 0.096480 0.150612
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -2.327e+02 7.602e+00 -30.62 <2e-16 ***
## Year 1.211e-01 3.782e-03 32.01 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 0.1049 on 19 degrees of freedom
## Multiple R-squared: 0.9818, Adjusted R-squared: 0.9808
## F-statistic: 1025 on 1 and 19 DF, p-value: < 2.2e-16
# Diagnostické grafy nového modelu
par(mfrow = c(2, 2))
plot(model2)
mtext(paste("Diagnostické grafy log-lineárneho modelu HDP –", province_name),
outer = TRUE, cex = 1.2, font = 2)par(mfrow = c(1, 1))
# Test normality pre nový model
jb_test2 <- jarque.bera.test(residuals(model2))
cat("\n📈 Jarque–Bera test pre log-transformovaný model:\n")##
## 📈 Jarque–Bera test pre log-transformovaný model:
##
## Jarque Bera Test
##
## data: residuals(model2)
## X-squared = 0.98665, df = 2, p-value = 0.6106
Lineárny model HDP ~ Year vystihuje základný trend rastu v čase. Rezíduá oscilujú okolo nuly a nepreukazujú výraznú heteroskedasticitu. Predpoklad normality je približne splnený (ak p > 0.05 v JB teste). Odľahlé roky (napr. prudké skoky HDP v 2008 alebo 2020) môžu mať menší vplyv, ale neovplyvňujú výrazne celkový trend.
Po logaritmickej transformácii sa rozdelenie rezíduí približuje normalite. Koeficient pri Year teraz vyjadruje priemerný percentuálny rast HDP (elasticitu). Model vysvetľuje časový trend ešte lepšie, čo vidno aj na zlepšení R² a stabilnejších rezíduách.