5  Braki danych i statystyki opisowe

5.1 Obsługa brakujących danych

W rzeczywistych danych ekonomicznych prawie zawsze występują braki — respondent nie odpowiedział, dane nie zostały zebrane, pomiar się nie powiódł. Ważne, żeby umieć je wykryć i świadomie obsłużyć.

library(dplyr)

# Przykładowe dane z brakami
dane_z_brakami <- data.frame(
  kraj     = c("PL", "DE", "FR", "IT", NA),
  PKB      = c(674, 4260, 2925, NA, 1418),
  inflacja = c(3.4, 2.1, NA, 8.7, NA)
)

# Wykrywanie braków
is.na(dane_z_brakami)           # maska logiczna (TRUE = brak)
#>       kraj   PKB inflacja
#> [1,] FALSE FALSE    FALSE
#> [2,] FALSE FALSE    FALSE
#> [3,] FALSE FALSE     TRUE
#> [4,] FALSE  TRUE    FALSE
#> [5,]  TRUE FALSE     TRUE
sum(is.na(dane_z_brakami))      # całkowita liczba braków
#> [1] 4
colSums(is.na(dane_z_brakami))  # braki w każdej kolumnie
#>     kraj      PKB inflacja 
#>        1        1        2
# Usunięcie wierszy z brakami
na.omit(dane_z_brakami)
#>   kraj  PKB inflacja
#> 1   PL  674      3.4
#> 2   DE 4260      2.1
# Zastąpienie braków — różne strategie
dane_z_brakami |>
  mutate(
    PKB      = ifelse(is.na(PKB),      mean(PKB,      na.rm = TRUE), PKB),
    inflacja = ifelse(is.na(inflacja), median(inflacja, na.rm = TRUE), inflacja)
  )
#>   kraj     PKB inflacja
#> 1   PL  674.00      3.4
#> 2   DE 4260.00      2.1
#> 3   FR 2925.00      3.4
#> 4   IT 2319.25      8.7
#> 5 <NA> 1418.00      3.4
import pandas as pd
import numpy as np

# Przykładowe dane z brakami
dane_z_brakami = pd.DataFrame({
    "kraj":     ["PL", "DE", "FR", "IT", None],
    "PKB":      [674, 4260, 2925, None, 1418],
    "inflacja": [3.4, 2.1, None, 8.7, None]
})

# Wykrywanie braków
dane_z_brakami.isna()              # maska logiczna
dane_z_brakami.isna().sum()        # braki w każdej kolumnie
dane_z_brakami.isna().sum().sum()  # całkowita liczba braków
# Usunięcie wierszy z brakami
dane_z_brakami.dropna()

# Zastąpienie braków — różne strategie
dane_z_brakami.fillna({
    "PKB":      dane_z_brakami["PKB"].mean(),
    "inflacja": dane_z_brakami["inflacja"].median()
})
ImportantStrategie obsługi braków — wybór ma znaczenie ekonomiczne
  • Usunięcie (dropna / na.omit) — bezpieczne tylko gdy braków jest mało (< 5%) i ich brak jest losowy (brak nie jest związany z wartością)
  • Zastąpienie średnią/medianą — prosta imputacja, ale zniekształca rozkład zmiennej
  • Zastąpienie 0 — sensowne gdy brak = nieobecność zjawiska (np. brak eksportu = 0), ale w innych przypadkach błędne
  • Modele imputacyjne — zaawansowane metody dla dużych zbiorów (pakiet mice w R, sklearn w Pythonie)

5.2 Statystyki opisowe

Statystyki opisowe to pierwsza rzecz, którą robimy po wczytaniu nowych danych. Pozwalają szybko ocenić skalę, zakres i rozkład zmiennych.

# Dane makroekonomiczne do dalszych ćwiczeń
dane_ekon <- data.frame(
  rok          = 2015:2024,
  PKB          = c(1800, 1862, 1984, 2120, 2292, 2330, 2625, 2780, 2900, 3070),
  inflacja     = c(2.1, 1.3, -0.6, 1.6, 1.8, 2.3, 5.1, 14.4, 11.4, 3.6),
  stopa_bezrob = c(7.5, 6.2, 5.5, 4.9, 3.8, 3.3, 5.6, 3.4, 2.9, 2.8)
)

# Zbiorcze statystyki opisowe
summary(dane_ekon)
#>       rok            PKB          inflacja       stopa_bezrob  
#>  Min.   :2015   Min.   :1800   Min.   :-0.600   Min.   :2.800  
#>  1st Qu.:2017   1st Qu.:2018   1st Qu.: 1.650   1st Qu.:3.325  
#>  Median :2020   Median :2311   Median : 2.200   Median :4.350  
#>  Mean   :2020   Mean   :2376   Mean   : 4.300   Mean   :4.590  
#>  3rd Qu.:2022   3rd Qu.:2741   3rd Qu.: 4.725   3rd Qu.:5.575  
#>  Max.   :2024   Max.   :3070   Max.   :14.400   Max.   :7.500
# Pojedyncze statystyki
mean(dane_ekon$inflacja)
#> [1] 4.3
sd(dane_ekon$inflacja)      # odchylenie standardowe
#> [1] 4.818252
var(dane_ekon$inflacja)     # wariancja
#> [1] 23.21556
quantile(dane_ekon$inflacja, probs = c(0.25, 0.5, 0.75))
#>   25%   50%   75% 
#> 1.650 2.200 4.725
# Macierz korelacji
cor(dane_ekon[, c("PKB", "inflacja", "stopa_bezrob")])
#>                     PKB   inflacja stopa_bezrob
#> PKB           1.0000000  0.6814915   -0.8064647
#> inflacja      0.6814915  1.0000000   -0.4919275
#> stopa_bezrob -0.8064647 -0.4919275    1.0000000
import pandas as pd

# Dane makroekonomiczne
dane_ekon = pd.DataFrame({
    "rok":          list(range(2015, 2025)),
    "PKB":          [1800, 1862, 1984, 2120, 2292, 2330, 2625, 2780, 2900, 3070],
    "inflacja":     [2.1, 1.3, -0.6, 1.6, 1.8, 2.3, 5.1, 14.4, 11.4, 3.6],
    "stopa_bezrob": [7.5, 6.2, 5.5, 4.9, 3.8, 3.3, 5.6, 3.4, 2.9, 2.8]
})

# Zbiorcze statystyki opisowe
dane_ekon.describe()
# Pojedyncze statystyki
dane_ekon["inflacja"].mean()
dane_ekon["inflacja"].std()       # odchylenie standardowe
dane_ekon["inflacja"].var()       # wariancja
dane_ekon["inflacja"].quantile([0.25, 0.5, 0.75])

# Macierz korelacji
dane_ekon[["PKB", "inflacja", "stopa_bezrob"]].corr()
TipDane dane_ekon — używamy w kolejnych rozdziałach

Ramka dane_ekon z symulowanymi wskaźnikami makroekonomicznymi będzie naszym głównym przykładem w rozdziałach o wizualizacji. Zdefiniuj ją raz na początku swojego skryptu.