Przykłady zastosowania API TREZOR-a¶
Dzisiaj z serii ciekawe publiczne dane, o których istnieniu mało kto wie będzie o przejrzystości budżetu państwa.
Otóż ostatnio widziałem na Twitterze kilka wpisów osób, które uzyskały informacje w trybie dostępu do informacji publicznej odnośnie dochodów budżetu państwa. Sprowadziło się to do przekazania informacji, które są już dostępne, tylko że w formie oficjalnego pisma. Nie wiem dlaczego ktoś taką formę preferuje, może to zwyczajnie wynika z braku wiedzy. Tym krótkim wpisem mam nadzieję, że tą wiedzą się podzielę.
DISCLAIMER: Nie pracuję przy opracowaniu tej aplikacji, ale zdarza mi się pracować z tymi danymi, ale w innej formie i zakresie. Tutaj tylko jako ciekawostka i przykład co można z publicznie dostępnych danych wyciągnąć. Nie jest to żadna opinia, argument czy zaawansowana analiza. Jedyne co chcę tu pokazać, że MF udostępnia ciekawe dane i warto to rozpropagować.
Planowanie i koordynacja dochodów i wydatków w administracji, gdzie mamy wiele odrębnych jednostek stanowi nie lada wyzwanie. W tym celu powstał system TREZOR. Jest to wewnętrzny system MF pozwalający nie tylko na planowanie, ale też służący sprawozdawczości dochodów i wydatków. Dla zainteresowanych jak wygląda praca z TREZOR-em od środka MF udostępnia dokumentację na stronie.
Przyznam się szczerze, że sam niedawno odkryłem, że MF udostępnia te dane bezpłatnie, wszystkim, bez konieczności rejestracji. Dzięki temu wydaje mi się, że MF ma chyba jeden z najbardziej czytelnych i otwartych mechanizmów planowania i sprawozdawczości miesięcznej dochodów i wydatków. API wraz z dokumentację dostępne jest tutaj: Swagger UI (mf.gov.pl).
Co tam znajdziemy? Plany wydatków i dochodów, wykonanie miesięczne powyższego oraz słowniki. Dlaczego tak? A bo ustawa o finansach publicznych określa co należy sprawozdawać. Ponadto ustawa określa szczegółową klasyfikację dochodów i wydatków zawartą w rozporządzeniu Szczegółowa klasyfikacja dochodów, wydatków, przychodów i rozchodów oraz środków pochodzących ze źródeł zagranicznych. - Dz.U.2022.513 t.j. - OpenLEX. Dzięki temu można na podstawie kodu działu/rozdziału określić na co jest dany wydatek, z czego dochód oraz paragrafu jaki to rodzaj operacji. To wszystko jest.
Ze słowników warto zwrócić uwagę na ‘jednostki budżetowe’, dzięki czemu można zidentyfikować jakiej jednostki dotyczą określone wydatki bądź dochody. Przydaje się np. przy okazji rozdzielania wydatków na jednostki będące pod nadzorem wojewodów. Bez tej identyfikacji wydatki byłyby liczone podwójnie.
Najważniejsze dane stanowią jednak sprawozdania:
- Rb-27 czyli sprawozdanie z wykonania planu dochodów budżetowych,
- Rb-28 czyli sprawozdanie z wykonania planu wydatków budżetu państwa.
Format danych oraz instrukcję sporządzania sprawozdań określa Rozporządzenie Ministra Finansów z dnia 11 stycznia 2022 r. w sprawie sprawozdawczości budżetowej (sejm.gov.pl).
Te dane zawierają absolutnie wszystko jeśli chodzi o budżet państwa i łatwo się też tego powodu w nich pogubić. Uwaga, nie ma tutaj ujętych funduszy typu FUS, FER czy NFZ, ale o tym może kiedy indziej.
# MN 27/05/23
# Pakiety
library(data.table)
library(magrittr)
library(ggplot2)
library(gridExtra)
library(knitr)
library(kableExtra)
# Oprócz tego korzystam httr, jsonlite oraz IRkernel do połaczenia z Jupyter
# Określenie czy korzystamy z API REST-owego czy też z serwera SQL
czy_api <- TRUE
if (czy_api == FALSE){
######################################################################
# Używam PostreSQL
library(RPostgreSQL)
# Parametry połączenia z serwerem PostgreSQL zmiennych środowiskowych
# Można zastąpić str
db_param <- list(
user = Sys.getenv("DB_USER"),
pass = Sys.getenv("DB_PASS"),
base = Sys.getenv("DB_BASE"),
host = Sys.getenv("DB_HOSTNAME")
)
drv <- dbDriver("PostgreSQL")
con <- dbConnect(
drv,
user = db_param$user,
password = db_param$pass,
dbname = db_param$base,
host = db_param$host
)
}
######################################################################
# Ustawienia wyświetlania dla ggplot
theme_set(theme_bw())
theme_update(legend.position="bottom", text = element_text(size = 20))
# Kolory: https://www.datanovia.com/en/blog/ggplot-colors-best-tricks-you-will-love/
# The palette with grey:
cbp1 <- c("#999999", "#E69F00", "#56B4E9", "#009E73",
"#F0E442", "#0072B2", "#D55E00", "#CC79A7")
color_fill <- scale_fill_manual(values = cbp1)
# To use for line and point colors, add
color_color <- scale_colour_manual(values=cbp1)
Dostęp do danych¶
Dane dostępne są w postaci API REST-owego. Format dostępu do danych wraz z opisami pól oraz przykładami jak niektóre rzeczy pobrać jest szczegółowo udokumentowany na stronie MF: Swagger UI (mf.gov.pl). To znaczy, że można skonstruować skrypty do automatycznego odpytywania i ściągania danych. Można, znaczy napisałem i się dzielę.
Skrypty zaciągają w R dane z API i zapisują do bazy PostgresSQL. Trwa to dość długo, bo API ma ograniczenie do liczby zapytań na godzinę, a danych jest dużo, bo od 2015 r. Jeśli jest taka potrzeba, to mogę przesłać skompresowane CSV. Póki co dałem przełącznik czy_api
, który pozwala wybrać czy dane zaczytywać z bazy SQL (szybciej) czy też z API MF (bez konieczności kompletowania całej bazy).
Zasadnicza część zawarta jest w pliku pobierz_trezor.R
. Zawiera on listę z linkami do poszczególnych elementów API oraz funkcję pobierz_trezor()
, która obsługuje API za pomocą następujących parametrów:
- url - adres czyli element z listy
trezor_api
, - param - lista z filtrami do API. Należy podać co najmniej rok, ale można też inne elementy,
- sleep - odstęp pomiędzy zapytaniami w sekundach. Potrzebujemy tego żeby serwery MF nas nie wyrzuciły,
- callback - funkcja do ewentualnego wykonania po zaczytaniu fragmentu danych. Tutaj w pozostałych skryptach umieszczam funkcję do wrzucania danych do bazy SQL.
Na wyjściu funkcja zwraca listę z elementami w postaci data.table
.
# Linki do poszczególnych zbiorów
trezor_api <- list(
slownik_dysponenci = "https://trezor-api.mf.gov.pl/api/v1/slownik/dysponenci",
slownik_czesci = "https://trezor-api.mf.gov.pl/api/v1/slownik/czesci",
slownik_dzialy = "https://trezor-api.mf.gov.pl/api/v1/slownik/dzialy",
slownik_paragrafy = "https://trezor-api.mf.gov.pl/api/v1/slownik/paragrafy",
slownik_rozdzialy = "https://trezor-api.mf.gov.pl/api/v1/slownik/rozdzialy",
slownik_grupy_ekonomiczne = "https://trezor-api.mf.gov.pl/api/v1/slownik/grupy-ekonomiczne",
slownik_jednostki_budzetowe = "https://trezor-api.mf.gov.pl/api/v1/slownik/jednostki-budzetowe",
slownik_zrodla_finansowania = "https://trezor-api.mf.gov.pl/api/v1/slownik/zrodla-finansowania",
rb28 = "https://trezor-api.mf.gov.pl/api/v1/sprawozdania-RB28",
rb27 = "https://trezor-api.mf.gov.pl/api/v1/sprawozdania-RB27",
rb50 = "https://trezor-api.mf.gov.pl/api/v1/sprawozdania-RB50"
)
# Funkcja do zaczytywania całych zbiorów z TERZOR-a
pobierz_trezor <- function(url, param, sleep = 0.8, callback = NULL){
wyniki <- list()
id <- 1
dalej <- TRUE
while (dalej) {
# message("Zapytanie: ", id)
param$page <- id
odp <- httr::GET(
url,
query = param
)
# print(odp)
if (httr::status_code(odp) != 200) {
dalej <- FALSE
} else {
wynik <- jsonlite::fromJSON(httr::content(odp, as = "text"))
wyniki[[id]] <- data.table(wynik$data)
if (!is.null(callback)) callback(wyniki[[id]])
if (is.na(wynik$links$`next`[1])) dalej <- FALSE
id <- id + 1
Sys.sleep(sleep)
}
}
wyniki
}
Dochody z PIT w podziale na BP i JST¶
Jako pierwszy przykład wykorzystania tych danych przychodzi mi do głowy pokazanie i rozbicie dochodów sektora publicznego z PIT. Otóż kto się interesuje ten wie, że tylko część dochodów z PIT płaconego przez podatników trafia do budżetu państwa i tylko ta część jest wykazywana w sprawozdaniach. Część udziałów mają samorządy. Stąd też informacje w sprawozdaniach rocznych z wykonania budżetu pokazują tylko to, co trafia do budżetu centralnego (Sprawozdanie z wykonania budżetu państwa za 2022 rok).
Brak jednak informacji o całości płaconego PIT przez podatników. Oczywiście to nie tak, że ktoś coś tutaj ukrywa, bo jest to dostępne w innych miejscach (np. GUS, EUROSTAT, wpływy budżetowe), ale tutaj można pokazać wszystko za jednym zamachem, miesięcznie i w rozbiciu na rozdziały i paragrafy. Co więcej można to wszystko rozbić na poszczególne Urzędy Skarbowe.
Rozpoczynamy od wyboru, które paragrafy odpowiadają za podatek dochodowy od osób fizycznych.
if (czy_api){
paragrafy <- pobierz_trezor(
trezor_api$slownik_paragrafy,
param = list(
kwalifikator = 'D',
opis = '%dochodo%',
limit = 500,
format = "json"
)
) %>% rbindlist
rozdzialy <- pobierz_trezor(
trezor_api$slownik_rozdzialy,
param = list(
limit = 500,
format = "json"
)
) %>% rbindlist
} else {
paragrafy <- "SELECT
paragraf,
opis,
aktywny_od,
aktywny_do
from trezor.slownik_paragrafy
where kwalifikator = 'D' and opis like '%dochodo%'
" %>%
dbGetQuery(con, .) %>%
setDT()
}
paragrafy[, .(paragraf, opis, aktywny_od, aktywny_do)] %>%
kable("html", caption = "Paragrafy podatków dochodowych") %>%
as.character() %>%
IRdisplay::display_html()
Z powyższego wynika, że paragrafy, które nas interesują to:
- 001 - podatek dochodowy od osób fizycznych <- ta część jest dzielona na BP i JST, reszta do BP
- 003 - ryczałt;
- 004 - dochody kapitałowe;
- 017 i 020 - pozostałe
Poniżej zapytanie z rozbiciem na rozdziały i paragrafy.
if (czy_api){
dodaj_do_rb27 <- function(dane){
# Zamień na float
changeCols <- c(
"plan",
"naleznosci",
"potracenia",
"dochody_wykonane",
"dochody_przekazane",
"naleznosci_do_zaplaty",
"zaleglosci",
"nadplaty"
)
dane <- dane[, (changeCols) := lapply(.SD, as.numeric), .SDcols = changeCols]
}
pit_bp <- lapply(
2022,
function(x) {
pobierz_trezor(
trezor_api$rb27,
param = list(
rok = 2022,
miesiac = 12,
czesc = '77',
dzial = '756',
id_dysp = 26893,
limit = 500,
format = "json"
),
sleep = 0.8,
callback = dodaj_do_rb27
) %>% rbindlist
}
) %>% rbindlist
pit_bp <- pit_bp[
paragraf %in% c('0010', '0030', '0040', '0170', '0200'),
.(
dochody_mld = sum(dochody_wykonane) / 1e9
),
.(
rozdzial,
par = fcase(
paragraf == '0010' & rozdzial == '75604', 'linia',
paragraf == '0010', 'skala',
paragraf == '0030', 'ryczałt',
paragraf == '0040', 'kapitałowe',
default = 'pozostałe'
)
)
]
pit_bp <- merge(
pit_bp,
rozdzialy[, .(rozdzial, opis_rozdzialu = opis)],
by = "rozdzial"
)
} else {
pit_bp <- "
select
r.rozdzial,
roz.opis as opis_rozdzialu,
case
when r.paragraf = '0010' and r.rozdzial = '75604' then 'linia'
when r.paragraf = '0010' then 'skala'
when r.paragraf = '0030' then 'ryczałt'
when r.paragraf = '0040' then 'kapitałowe'
else 'pozostałe'
end as par,
sum(r.dochody_wykonane) / 1e9 dochody_mld
from trezor.rb27 r
inner join (
select
id_dysp
from trezor.slownik_dysponenci
where id_dysp_nadrz = 1
) sd
on r.id_dysp = sd.id_dysp
left join trezor.slownik_rozdzialy roz
on r.rozdzial = roz.rozdzial
where
miesiac = 12
and rok = 2022
and czesc = '77'
and dzial = '756'
and paragraf in ('0010', '0030', '0040', '0170', '0200')
group by r.rozdzial, roz.opis, case
when r.paragraf = '0010' and r.rozdzial = '75604' then 'linia'
when r.paragraf = '0010' then 'skala'
when r.paragraf = '0030' then 'ryczałt'
when r.paragraf = '0040' then 'kapitałowe'
else 'pozostałe'
end
order by sum(r.dochody_wykonane) desc
" %>%
dbGetQuery(con, .) %>% data.table()
}
pit_bp_tab <- copy(pit_bp)
pit_bp_tab[, dochody_mld := round(dochody_mld, 3)]
pit_bp_tab[order(-dochody_mld), .(rozdzial, par, opis_rozdzialu, dochody_mld)] %>%
kable("html", caption = "Wpływy z PIT w 2022 r. w podziale na rozdziały i paragrafy") %>%
as.character() %>%
IRdisplay::display_html()
Dochody z PIT, które przedstawione są w ustawie budżetowej nie stanowią całości tego ile podatnicy odprowadzają PIT, ale jedynie tę część, która trafia do budżetu centralnego.
Przedstawione są one w TERZORze w ciekawy sposób. Nie ma tam ostatecznego udziału budżetu, jak ma to miejsce w ustawie budżetowej, ale przedstawione są całkowite wpływy sektora z tych podatków. Są to wciąż jednak wpływy netto, czyli nie możemy rozdzielić powyższego na to ile urzędy skarbowe zwracają w rozliczeniu rocznym oraz na to jakie zaliczki podatnicy płacą.
Udziały JST, które pomniejszają dochody BP, są ujęte jako ujemne dochody. W podobny sposób przedstawiane są udziały OPP w PIT oraz zwroty podatku z tytułu niewykorzystanej ulgi na dzieci. Przy czym każda z tych kategorii opisana jest kombinacją rozdziałów i paragrafów.
Poniżej agregaty dla 2022 r. w mld zł, bez rozbicia.
pit_bp_podsumowanie <- copy(pit_bp)
pit_bp_podsumowanie <- pit_bp_podsumowanie[,
.(suma_mld = round(sum(dochody_mld), 3)),
by = .(rodzaj = fcase(
rozdzial %in% c("75601", "75604"), "Całkowite wpływy",
rozdzial %in% c("75621", "75622", "75623", "75634"), "JST",
rozdzial %in% c("75656"), "OPP",
rozdzial %in% c("75657"), "Zwrotna ulga na dzieci"
) %>% factor)
]
bp <- sum(pit_bp_podsumowanie$suma_mld)
rbind(
data.table(rodzaj = "BP", suma_mld = round(bp, 3)),
pit_bp_podsumowanie
) %>%
kable("html", caption = "Podział całkowitych wpływów z PIT w 2022 r.") %>%
as.character() %>%
IRdisplay::display_html()
Poniżej agregaty roczne oraz wykres miesięczny całkowitego PIT płaconego przez podatników z podziałem na budżet państwa i JST. Co się stało w 2022? Po pierwsze od tego roku zaczął obowiązywać system równych rat JST, gdzie udziały JST przestały być obliczane w oparciu o bieżące wpływy, ale udziały były przekazywane w równych miesięcznych ratach w oparciu o prognozę całkowitego PIT przy ustawie budżetowej.
Po drugie w IV kw JST otrzymały dodatkowe 13,7 mld zł udziałów w PIT jako wsparcie w kryzysie energetycznym. Oznacza to, że ostatecznie w 2022 udziały JST w PIT były o ok. 4 p.p. wyższe niż w poprzednich latach. W wyniku reform z 2022 widać, że poziom całkowitych wpływów z PIT zatrzymał się praktycznie na tym samym poziomie, pomimo wzrostu wynagrodzeń oraz emerytur i rent. Dla JST nie oznaczało to jednak straty, lecz wzrost. Oczywiście w wyniku wyjątkowych przepisów.
Dla 2023 udział JST wynosi 50% bo w danych dopiero kilka pierwszych miesięcy, gdzie przy wysokich zwrotach JST korzystają na systemie równych rat. Jak rozliczenie roczne się zakończy, to pewno ten współczynnik zacznie spadać.
# Dochody budżetu państwa z PIT
if (czy_api){
doch <- lapply(
2015:2023,
function(x) {
pobierz_trezor(
trezor_api$rb27,
param = list(
rok = x,
czesc = '77',
dzial = '756',
id_dysp = 26893,
limit = 500,
format = "json"
),
sleep = 0.8,
callback = dodaj_do_rb27
) %>% rbindlist
}
) %>% rbindlist
doch <- doch[
paragraf %in% c('0010', '0030', '0040', '0170', '0200'),
.(
dochody_wykonane = sum(dochody_wykonane)
),
.(
rok, miesiac, rozdzial, paragraf
)
]
} else {
doch_sql <- "
select
rok,miesiac,
r.rozdzial, r.paragraf,
sum(dochody_wykonane) dochody_wykonane
from trezor.rb27 r
inner join (
select
id_dysp
from trezor.slownik_dysponenci
where id_dysp_nadrz = 1
) sd
on r.id_dysp = sd.id_dysp
and czesc = '77'
and dzial = '756'
and paragraf in ('0010', '0030', '0040', '0170', '0200')
group by rok, miesiac, r.rozdzial, r.paragraf
order by rok, miesiac"
doch <- dbGetQuery(con, doch_sql) %>% setDT()
# Uzyskaj wartości miesięczne, nie narastająco w każdym roku
#doch
}
doch[order(miesiac), dochody_wykonane := dochody_wykonane - shift(dochody_wykonane, fill=0.0), by = .(rok, paragraf, rozdzial)]
# Agregacja na główne składowe
doch_pit <- doch[
,
.(suma_mld = round(sum(dochody_wykonane) / 1e9, 3)),
by = .(
rok, miesiac,
rodzaj = fcase(
rozdzial %in% c("75601", "75604"), "Całkowite wpływy",
rozdzial %in% c("75656"), "OPP",
rozdzial %in% c("75657"), "Zwrotna ulga na dzieci",
rozdzial %in% c("75621", "75622", "75623", "75634"), "JST"
) %>% factor
)
]
doch_pit <- doch_pit[!is.na(rodzaj)]
# Dodaj dochody BP jako resztę
doch_pit <- rbind(
doch_pit,
doch_pit[, .(rodzaj = factor("BP"), suma_mld = sum(suma_mld)), keyby = .(rok, miesiac)]
)
# Zmień kolejność etykiet do wykresu
doch_pit[, rodzaj := factor(rodzaj, levels = c("Całkowite wpływy", "BP", "OPP", "Zwrotna ulga na dzieci", "JST"))]
# Dodaj daty
doch_pit[, data := as.Date(stringr::str_c(rok, "-", miesiac, "-01"))]
doch_pit_wide <- doch_pit[, .(suma_mld = sum(suma_mld)), keyby = .(rok, rodzaj)] %>%
dcast(rok~rodzaj, value.var = "suma_mld")
doch_pit_wide[, `Udział JST` := sprintf("%.1f%%", -JST / `Całkowite wpływy` * 100)]
doch_pit_wide %>%
kable("html", caption = "Całkowite roczne wpływy z PIT [mld zł] wraz z podziałem") %>%
as.character() %>%
IRdisplay::display_html()
options(repr.plot.width = 16, repr.plot.height = 7, repr.plot.scale = 1.5)
doch_pit[rodzaj != "Całkowite wpływy"] %>%
ggplot(aes(x = data, y= abs(suma_mld), fill = rodzaj)) + geom_area() +
labs(x="Data", y = "Udział, mld zł/m-c", title="Udział we wpływach PIT wg celu") +
color_fill
Na wykresie może tego nie widać tak dobrze, ale w wyniku wysokich zwrotów na rozliczeniu rocznym miesięczne całkowite wpływy z PIT były na tyle niskie, że aby zapewnić zwroty ulgi na dzieci oraz stałe raty dla JST BP był w tym miesiącu na minusie.
Patrząc na poprzednie lata widać odpowiednio wysoki spadek w dochodach JST z PIT z tytułu rozliczenia rocznego właśnie w okolicach marca. Gdyby nie przejście na stałe raty dla JST, to w marcu 2022 r. JST by nie miały w ogóle dochodów z PIT.
doch_pit[rok == 2023] %>%
dcast(data~rodzaj, value.var = "suma_mld") %>%
kable("html", caption = "Udział we wpływach PIT wg celu, miesięcznie dla 2023 r., mld zł") %>%
as.character() %>%
IRdisplay::display_html()
O ile same dochody JST się ustabilizowały w zakresie kwoty z PIT, to oznacza to z kolei, że ich udziały procentowe w całości wpływów w danym miesiącu są zmienne w czasie. Doskonale widać to na poniższych wykresach, gdzie po lewej mamy kwoty miesięczne, które się stabilizują od 2022 r., natomiast po prawej mamy udział w całości wpływów z PIT. Przed 2022 r. udział ten był w miarę stabilny i zmieniał się w miesiącach, gdzie było raz mniej, raz więcej wpływów z pozostałych rodzajów podatków, gdzie BP ma całkowity udział (ryczały, giełda, ryczałt od przychodów ewidencjonowanych). Natomiast po zamrożeniu kwoty, to udział ten szaleje i w III 2023 osiąga ponad 100% w wyniku wysokich zwrotów na rozliczeniu rocznym.
options(repr.plot.width = 16, repr.plot.height = 7, repr.plot.scale = 1.5)
jst_kwoty <- doch_pit %>%
dcast(rok+miesiac~rodzaj, value.var = "suma_mld") %>%
ggplot(aes(x = rok+(miesiac-1)/12, y= -JST )) + geom_line() +
labs(x = "Data", y = "Udziały JST, mld zł/m-c")
jst_udzialy <- doch_pit %>%
dcast(rok+miesiac~rodzaj, value.var = "suma_mld") %>%
ggplot(aes(x = rok+(miesiac-1)/12, y= -JST / `Całkowite wpływy` )) + geom_line() +
labs(x = "Data", y = "Udziały JST, %") + scale_y_continuous (labels = scales::percent)
grid.arrange(jst_kwoty, jst_udzialy, nrow=1, ncol=2)
Udziały we wpływach PIT wg formy rozliczenia¶
Dodatkowo, dane w TREZOR-ze pozwalają na podział PIT względem formy rozliczenia. Ma to znaczenie o tyle, że nie we wszystkim samorządy mają swój udział. Jedynie w PIT na skali oraz linii. w CIT też, ale nie o CIT jest ten wpis.
Jeśli spojrzymy na udziały po rodzaju rozliczenia, to widać spadek znaczenia liniówki oraz wzrost ryczałtu w 2022 r.
# Udziały całkowitych wpływów wg źrógła
# Agregacja na główne składowe
doch_zrodlo <- doch[
rozdzial %in% c("75601", "75604"),
.(suma_mld = round(sum(dochody_wykonane) / 1e9, 3)),
by = .(
rok, miesiac,
rodzaj = fcase(
paragraf == '0010' & rozdzial == '75604', 'linia',
paragraf == '0010', 'skala',
paragraf == '0030', 'ryczałt',
paragraf == '0040', 'kapitałowe',
default = 'pozostałe'
) %>% factor
)
]
# Zmień kolejność etykiet do wykresu
doch_zrodlo[, rodzaj := factor(rodzaj, levels = c("kapitałowe", "ryczałt", "linia", "skala", "pozostałe"))]
doch_wide <- doch_zrodlo[, .(suma_mld = round(sum(suma_mld), 3)), .(rok, rodzaj)] %>%
dcast(rok~rodzaj, value.var = "suma_mld")
doch_wide[, .(rok, skala, linia, ryczałt, kapitałowe, pozostałe)] %>%
kable("html", caption = "Wpływy roczne PIT, wg formy rozliczenia, mld zł") %>%
as.character() %>%
IRdisplay::display_html()
W szczególności widać to na dynamikach rocznych, poniżej w %.
Na skali widać ujemną dynamikę całkowitych wpływów w 2020 r. oraz 2022 r. W pierwszym przypadku widoczne są efekty zmian wprowadzonych pod koniec 2019 r. czyli PIT-0 dla osó do 26 r.ż. (zwolnienie przychodu do ok. 85 tys. zł/rok z opodatkowania) oraz obniżenia stawki PIT z 18% do 17%. Zmiany te w pełni uwidoczniły się dopiero w 2020 r. Do tego doszła oczywiście pandemia w 2020 r.
Rok 2022 z kolei pokazuje efekty Niskich Podatków. Mamy spadek wpływów ze skali o ok. 10% przy wzroście przeciętnych wynagrodzeń o 12% (Komunikaty GUS, przed rewizją) oraz waloryzacji rent i emerytur o 9% w marcu 2022 r. Do tego dochodzi zwolnienie 13. i 14. emerytury z PIT w 2022 r.
wybrane <- c("skala", "linia", "ryczałt", "kapitałowe")
doch_wide_dynamiki <- copy(doch_wide)
doch_wide_dynamiki[
rok < 2023,
(wybrane) := lapply(.SD, function(x){round(100 * (x/shift(x) - 1), 1) }),
.SDcols = wybrane
][
rok < 2023,
.(rok, skala, linia, ryczałt, kapitałowe)
] %>%
kable("html", caption = "Wpływy roczne PIT, wg formy rozliczenia, dynamiki r/r, %") %>%
as.character() %>%
IRdisplay::display_html()
# Dodaj daty
doch_zrodlo[, data := as.Date(stringr::str_c(rok, "-", miesiac, "-01"))]
doch_zrodlo %>%
ggplot(aes(x = data, y= suma_mld, fill = rodzaj)) + geom_area() + color_fill +
labs(x="Data", y = "Udział, mld zł/m-c", , title= "Udział we wpływach PIT wg formy rozliczenia")
doch_zrodlo[, udzialy := pmax(suma_mld,0) / sum(pmax(suma_mld, 0)), .(data)]
doch_zrodlo %>%
ggplot(aes(x = data, y= udzialy, fill = rodzaj)) + geom_area() +
scale_y_continuous (labels = scales::percent) + color_fill +
labs(x="Data", y = "Udział, % wpływów", title= "Udział we wpływach PIT wg formy rozliczenia")
Podsumowanie¶
Oczywiście jest to tylko drobny ułamek tego, co w tych danych siedzi. Jak będę miał trochę czasu to może spróbuję wrzucać dalsze wyniki eksploracji tego zbioru. Ciekawe tematy:
- Pozostałe dochody;
- Wydatki ogółem i po działach;
- Wydatki na wynagrodzenia;
- Funkcjonowanie jednostek podległych wojewodom;
- Rozszerzenie o pozostałe fundusze.
Zaznaczam też, że wszystko co powyżej napisałem to efekt pracy w czasie wolnym, którego ostatnio u mnie jak na lekarstwo.