Rynek mieszkaniowy w Polsce podlega nieustannym turbulencjom związanymi z szeregiem czynników kształtujących równowagę rynkową. Ostatni okres kojarzony jest jednak z niepokojem względem kształtowania się ceny adekwatnej do warunków gospodarczych i otoczenia ekonomicznego deweloperów. Kolejne programy rządowe nie przynoszą oczekiwanych skutków, zaś ceny mieszkań naocznie rosną.
Kształtowanie się ceny zależy od szeregu czynników, zarówno ekonomicznych jak i innych, które można zaklasyfikować numerycznie lub opisowo. Nierzadko istotną rolę w doborze inwestycji w nieruchomości odgrywa położenie geograficzne. Mieszkanie w Warszawie czy Gdańsku wzbudza większe zainteresowanie niż odpowiednik w Rzeszowie czy Katowicach, choćby ze względu na średnie zarobki w obu otoczeniach miejskich. Tym samym interesujące wydają się wszelkie porównania oraz wizualne przedstawianie różnic kształtujących się pomiędzy cenami mieszkań.
Narodowy Bank Polski udostępnia cyklicznie kwartalne ceny mieszkań w formie przeciętnej ceny za metr kwadratowy w danym mieście wojewódzkim. Wybrane do raportu dane zostały podane w okresie od III kwartału 2006 do III kwartału 2021 włącznie i obejmują podział na rynek pierwotny i wtórny wraz z kolejnym wewnętrznym rozdzieleniem na ceny ofertowe i transakcyjne dla każdego rodzaju. Ceny zostały podane w walucie PLN.
Przygotowanie danych poza zakresem R objęło podział pierwotnego pliku w formacie .xls na cztery osobne arkusze w formacie .csv z danymi odpowiadającymi kolejno:
rynek pierwotny: ceny ofertowe;
rynek pierwotny: ceny transakcyjne;
rynek wtórny: ceny ofertowe;
rynek wtórny: ceny transakcyjne.
Rynek nieruchomości jest na tyle złożony, że trudno postawić jedno pytanie badawcze, które mogłoby skupić zarówno analizę behawioralną kupujących oraz uwzględnienie innych czynników ekonomicznych, politycznych i społecznych. Tym samym celem raportu jest jak najszersze oszacowanie zmian w obrębie zmian cen i podstawowych operacji statystycznych wykonanu w programie R z wykorzystaniem środowiska programistycznego jakim jest RStudio.
Analiza będzie bazować na podstawowych statystykach oszacowanych na podstawie dostępnych danych. Autorzy pragną zaprezentować oraz krótko oszacować:
Rozkład średnich cen ofertowych mieszkań na rynku wtórnym,
Kształtowanie cen ofertowych na rynku pierwotnym,
Relację odchyleń standardowych ofertowych cen mieszkań na rynku wtórnym w dwóch najbardziej zamożnych miastach,
Kształtowanie przeciętnej ceny transakcyjnej na rynku pierwotnym,
Kształtowanie przeciętnej ceny transakcyjnej w Gdańsku wraz z trendem,
Porównanie ceny ofertowej na rynku pierwtonym sześciu najdroższych miast z wyłączeniem Warszawy względem średniej,
Porównanie cen mieszkań w Warszawie na podstawie wszystkich rynków.
Na podstawie oszacowanych danych zostanie zaprezentowany krótki wniosek względem kondycji rynku nieruchomości w Polsce.
Dane zostały wczytane i oznaczone roboczymi etykietami, kolejno rpo, rpt, rwo, rwt.
setwd("/Users/michalniemczal/Desktop/AG2/AD/Gmail")
rpo <- read.csv("rpierwotny_cofertowe.csv", sep=";", dec=",", stringsAsFactors = T)
rpt <- read.csv("rpierwotny_ctrans.csv", sep=";", dec=",", stringsAsFactors = T)
rwo <- read.csv("rwtorny_cofertowe.csv", sep=";", dec=",", stringsAsFactors = T)
rwt <- read.csv("rwtorny_ctrans.csv", sep=";", dec=",", stringsAsFactors = T)W celu sprawdzenia informacji na temat zaimportowanych danych wykonano podstawowe podsumowania na przykładzie rpo:
head(rpo)tail(rpo)str(rpo)## 'data.frame': 61 obs. of 18 variables:
## $ Kwartał : Factor w/ 61 levels "I 2007","I 2008",..: 31 47 1 16 32 48 2 17 33 49 ...
## $ Białystok : int 2727 2727 4181 4725 4199 4995 5128 5651 5115 4725 ...
## $ Bydgoszcz : int 3243 3947 4501 5700 4994 4829 4893 5035 4959 4989 ...
## $ Gdańsk : int 5004 6199 6437 7999 8053 7402 7210 8509 8454 6609 ...
## $ Gdynia : int 4937 5284 6466 8934 8114 7887 7737 7897 7169 6342 ...
## $ Katowice : int 3986 4062 4518 5181 6236 6458 6258 6599 6303 6677 ...
## $ Kielce : int 2919 3493 3382 3902 4651 4475 4529 5281 5396 5208 ...
## $ Kraków : int 6021 7929 8247 8129 8420 8355 8084 8034 8012 7751 ...
## $ Lublin : int 3456 3314 3604 4143 4645 5047 5011 5174 5170 5266 ...
## $ Łódź : int 3210 4237 4927 5453 5201 5062 5048 4962 5480 5329 ...
## $ Olsztyn : int 4000 4800 5149 4776 4900 4900 4800 4800 4924 4761 ...
## $ Opole : int 3343 NA NA NA 4784 4937 4920 4931 4943 4968 ...
## $ Poznań : int 4770 4827 7275 7360 6838 7564 7480 7338 7320 7277 ...
## $ Rzeszów : int 2862 3401 3420 4080 4069 4357 4188 4215 4433 4069 ...
## $ Szczecin : int 3215 3679 4749 5050 5035 5731 5723 5664 5521 5469 ...
## $ Warszawa : int 5873 6095 7509 8000 8740 9561 9427 9300 9235 9821 ...
## $ Wrocław : int 4750 5759 6309 6294 6444 5495 5728 6299 5704 5027 ...
## $ Zielona.Góra: int 2754 2869 2872 4153 4208 3965 3965 3986 4012 3892 ...
summary(rpo)## Kwartał Białystok Bydgoszcz Gdańsk Gdynia
## I 2007 : 1 Min. :2727 Min. :3243 Min. : 5004 Min. : 4937
## I 2008 : 1 1st Qu.:4791 1st Qu.:4920 1st Qu.: 6248 1st Qu.: 6294
## I 2009 : 1 Median :4886 Median :5100 Median : 6568 Median : 6785
## I 2010 : 1 Mean :5081 Mean :5426 Mean : 7200 Mean : 7267
## I 2011 : 1 3rd Qu.:5236 3rd Qu.:6041 3rd Qu.: 8267 3rd Qu.: 7912
## I 2012 : 1 Max. :7621 Max. :7567 Max. :10310 Max. :11193
## (Other):55
## Katowice Kielce Kraków Lublin Łódź
## Min. :3986 Min. :2919 Min. : 6021 Min. :3314 Min. :3210
## 1st Qu.:5413 1st Qu.:4783 1st Qu.: 6670 1st Qu.:5014 1st Qu.:4906
## Median :5817 Median :4907 Median : 7209 Median :5126 Median :5147
## Mean :5994 Mean :4980 Mean : 7472 Mean :5286 Mean :5325
## 3rd Qu.:6458 3rd Qu.:5112 3rd Qu.: 8012 3rd Qu.:5287 3rd Qu.:5475
## Max. :8387 Max. :6633 Max. :10605 Max. :7965 Max. :8006
##
## Olsztyn Opole Poznań Rzeszów Szczecin
## Min. :4000 Min. :3343 Min. :4770 Min. :2862 Min. :3215
## 1st Qu.:4800 1st Qu.:4764 1st Qu.:6425 1st Qu.:4254 1st Qu.:4890
## Median :4924 Median :4840 Median :6600 Median :4952 Median :5031
## Mean :5241 Mean :5035 Mean :6802 Mean :4834 Mean :5488
## 3rd Qu.:5600 3rd Qu.:5273 3rd Qu.:7277 3rd Qu.:5148 3rd Qu.:5731
## Max. :6921 Max. :6441 Max. :8656 Max. :7271 Max. :8775
## NA's :3
## Warszawa Wrocław Zielona.Góra
## Min. : 5873 Min. :4750 Min. :2754
## 1st Qu.: 7839 1st Qu.:6020 1st Qu.:3660
## Median : 8146 Median :6281 Median :3870
## Mean : 8675 Mean :6550 Mean :4035
## 3rd Qu.: 9561 3rd Qu.:6526 3rd Qu.:4012
## Max. :11406 Max. :9965 Max. :6820
##
Zauważono, że wartości numeryczne zostały zaimportowane w formie int (integer). Z racji późniejszych kalkulacji oraz form wizualizacji danych nastąpiło przekształcenie danych w formie int spośród wszystkich ramek na wartości numeryczne.
rpo$Białystok <- as.numeric(rpo$Białystok)
rpo$Bydgoszcz <- as.numeric(rpo$Bydgoszcz)
rpo$Gdańsk <- as.numeric(rpo$Gdańsk)
rpo$Gdynia <- as.numeric(rpo$Gdynia)
rpo$Katowice <- as.numeric(rpo$Katowice)
rpo$Kielce <- as.numeric(rpo$Kielce)
rpo$Kraków <- as.numeric(rpo$Kraków)
rpo$Lublin <- as.numeric(rpo$Lublin)
rpo$Łódź <- as.numeric(rpo$Łódź)
rpo$Olsztyn <- as.numeric(rpo$Olsztyn)
rpo$Opole <- as.numeric(rpo$Opole)
rpo$Poznań <- as.numeric(rpo$Poznań)
rpo$Rzeszów <- as.numeric(rpo$Rzeszów)
rpo$Szczecin <- as.numeric(rpo$Szczecin)
rpo$Warszawa <- as.numeric(rpo$Warszawa)
rpo$Wrocław <- as.numeric(rpo$Wrocław)
rpo$Zielona.Góra <- as.numeric(rpo$Zielona.Góra)
rpt$Białystok <- as.numeric(rpt$Białystok)
rpt$Bydgoszcz <- as.numeric(rpt$Bydgoszcz)
rpt$Gdańsk <- as.numeric(rpt$Gdańsk)
rpt$Gdynia <- as.numeric(rpt$Gdynia)
rpt$Katowice <- as.numeric(rpt$Katowice)
rpt$Kielce <- as.numeric(rpt$Kielce)
rpt$Kraków <- as.numeric(rpt$Kraków)
rpt$Lublin <- as.numeric(rpt$Lublin)
rpt$Łódź <- as.numeric(rpt$Łódź)
rpt$Olsztyn <- as.numeric(rpt$Olsztyn)
rpt$Opole <- as.numeric(rpt$Opole)
rpt$Poznań <- as.numeric(rpt$Poznań)
rpt$Rzeszów <- as.numeric(rpt$Rzeszów)
rpt$Szczecin <- as.numeric(rpt$Szczecin)
rpt$Warszawa <- as.numeric(rpt$Warszawa)
rpt$Wrocław <- as.numeric(rpt$Wrocław)
rpt$Zielona.Góra <- as.numeric(rpt$Zielona.Góra)
rwo$Białystok <- as.numeric(rwo$Białystok)
rwo$Bydgoszcz <- as.numeric(rwo$Bydgoszcz)
rwo$Gdańsk <- as.numeric(rwo$Gdańsk)
rwo$Gdynia <- as.numeric(rwo$Gdynia)
rwo$Katowice <- as.numeric(rwo$Katowice)
rwo$Kielce <- as.numeric(rwo$Kielce)
rwo$Kraków <- as.numeric(rwo$Kraków)
rwo$Lublin <- as.numeric(rwo$Lublin)
rwo$Łódź <- as.numeric(rwo$Łódź)
rwo$Olsztyn <- as.numeric(rwo$Olsztyn)
rwo$Opole <- as.numeric(rwo$Opole)
rwo$Poznań <- as.numeric(rwo$Poznań)
rwo$Rzeszów <- as.numeric(rwo$Rzeszów)
rwo$Szczecin <- as.numeric(rwo$Szczecin)
rwo$Warszawa <- as.numeric(rwo$Warszawa)
rwo$Wrocław <- as.numeric(rwo$Wrocław)
rwo$Zielona.Góra <- as.numeric(rwo$Zielona.Góra)
rwt$Białystok <- as.numeric(rwt$Białystok)
rwt$Bydgoszcz <- as.numeric(rwt$Bydgoszcz)
rwt$Gdańsk <- as.numeric(rwt$Gdańsk)
rwt$Gdynia <- as.numeric(rwt$Gdynia)
rwt$Katowice <- as.numeric(rwt$Katowice)
rwt$Kielce <- as.numeric(rwt$Kielce)
rwt$Kraków <- as.numeric(rwt$Kraków)
rwt$Lublin <- as.numeric(rwt$Lublin)
rwt$Łódź <- as.numeric(rwt$Łódź)
rwt$Olsztyn <- as.numeric(rwt$Olsztyn)
rwt$Opole <- as.numeric(rwt$Opole)
rwt$Poznań <- as.numeric(rwt$Poznań)
rwt$Rzeszów <- as.numeric(rwt$Rzeszów)
rwt$Szczecin <- as.numeric(rwt$Szczecin)
rwt$Warszawa <- as.numeric(rwt$Warszawa)
rwt$Wrocław <- as.numeric(rwt$Wrocław)
rwt$Zielona.Góra <- as.numeric(rwt$Zielona.Góra)W celu zobrazowania potencjalnego rozkładu cen na poszczególnych rynkach autorzy zdecydowali się na wizualizację rynku rpo za pomocą narzędzia matplot jako poglądowe ujęcie danych. Jako że matplot najlepiej operuje na macierzach, a nie ramkach danych, utworzono kopię rpo w ujęciu macierzowym.
rpo_matrix <- as.matrix(rpo)
head(rpo_matrix)## Kwartał Białystok Bydgoszcz Gdańsk Gdynia Katowice Kielce Kraków
## [1,] "III 2006" "2727" "3243" " 5004" " 4937" "3986" "2919" " 6021"
## [2,] "IV 2006" "2727" "3947" " 6199" " 5284" "4062" "3493" " 7929"
## [3,] "I 2007" "4181" "4501" " 6437" " 6466" "4518" "3382" " 8247"
## [4,] "II 2007" "4725" "5700" " 7999" " 8934" "5181" "3902" " 8129"
## [5,] "III 2007" "4199" "4994" " 8053" " 8114" "6236" "4651" " 8420"
## [6,] "IV 2007" "4995" "4829" " 7402" " 7887" "6458" "4475" " 8355"
## Lublin Łódź Olsztyn Opole Poznań Rzeszów Szczecin Warszawa Wrocław
## [1,] "3456" "3210" "4000" "3343" "4770" "2862" "3215" " 5873" "4750"
## [2,] "3314" "4237" "4800" NA "4827" "3401" "3679" " 6095" "5759"
## [3,] "3604" "4927" "5149" NA "7275" "3420" "4749" " 7509" "6309"
## [4,] "4143" "5453" "4776" NA "7360" "4080" "5050" " 8000" "6294"
## [5,] "4645" "5201" "4900" "4784" "6838" "4069" "5035" " 8740" "6444"
## [6,] "5047" "5062" "4900" "4937" "7564" "4357" "5731" " 9561" "5495"
## Zielona.Góra
## [1,] "2754"
## [2,] "2869"
## [3,] "2872"
## [4,] "4153"
## [5,] "4208"
## [6,] "3965"
Dodano wektor Miast (Cities), który przyczynił się do powstania legendy, aby zaprezentowane dane były bardziej czytelne oraz rozróżnialne.
Cities <- c("Białystok", "Bydgoszcz", "Gdańsk", "Gdynia", "Katowice", "Kielce",
"Kraków", "Lublin", "Łódź","Olsztyn", "Opole", "Poznań", "Rzeszów",
"Szczecin", "Warszawa", "Wrocław", "Zielona Góra")Tym samym skonstruowano poniższy wykres.
matplot(rpo_matrix, type="l", lty = c(1:17), lwd = 2, col=c(1:17),
xlab = "Czas w Kwartałach",
ylab = "Cena w złotówkach za metr kwadratowy",
main = "Ceny mieszkań na rynku pierwotnym w miastach wojewódzkich w Polsce")## Warning in xy.coords(x, y, xlabel, ylabel, log = log, recycle = TRUE): pojawiły
## się wartości NA na skutek przekształcenia
## Warning in xy.coords(x, y, xlabel, ylabel, log): pojawiły się wartości NA na
## skutek przekształcenia
par(mar=c(5, 5, 5, 8.1), xpd=TRUE)
legend("topright", inset=c(-0.3,0), legend=Cities, lty = c(1:17), lwd = 2, col=c(1:17),
horiz=F, xpd = T, title = "Miasta")Jak można zauważyć, wykres jest niedoskonały. Niesie ze sobą ograniczenia zarówno narzędzia, jakim jest matplot oraz dokumentowania w formie R-Markdown. Poniżej zaprezentowano w formie wyeksportowanego zdjęcia wykres z uwzględnieniem legendy:
Widać, że zbiorowe prezentowanie rynków niesie ze sobą przesyt informacyjny i nawet obecność legendy nie jest wystarczającą suplementacją odczytywania danych. Tym samym narzędzie matplot należy traktować jedynie jako opcjonalną wizualizację wstępnych obserwacji, zaś właściwe wykresy zostaną przedstawione za pomocą pakietu ggplot2.
Od tej pory pierwotne faktory “Kwartał” nie będą potrzebne, gdyż zostaną później zastąpione odpowiednim formatowaniem. Tym samym usunięto kolumny zawierające niepotrzebne faktory.
rpo$Kwartał <- NULL
rpt$Kwartał <- NULL
rwo$Kwartał <- NULL
rwt$Kwartał <- NULLSurowe dane nierzadko wymagają dodatkowej uwagi ze względu na potencjalne błędy, nienaturalne odchylenia czy brakujące elementy. W celu uzyskania najbardziej przybliżonego do rzeczywistości obrazu na badane elementy, należy upewnić się czy dane są kompletne.
rpo[!complete.cases(rpo),]rpt[!complete.cases(rpt),]rwo[!complete.cases(rwo),]rwt[!complete.cases(rwt),]Wynikiem sprawdzenia, okazało się, że ramki danych rpo oraz rpt zawierają puste rekordy. Manualne sprawdzenie danych wykazało:
brak trzech rekordów w okresach 4 kwartał 2006, 1 kwartał 2007 i 2 kwartał 2007 w Opolu dla rynku pierwotnego, cen ofertowych,
brak jednego rekordu w 1 kwartale 2007 w Opolu dla rynku pierwotnego, cen transakcyjnych.
Pozostałe dane są kompletne. Bazując na pierwotnych podsumowaniach należy także stwierdzić, że nie nastąpiło żadne szczególne odchylenie. Autorzy nie mają także możliwości weryfikacji potencjalnych błędów.
Przystąpiono do usuwania wartości nieznanych. Poniżej przedstawiono alternatywne sposoby na wskazywanie brakujących danych w kolumnie odpowiadającej Opolu dla rpo:
is.na(rpo$Opole)## [1] FALSE TRUE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [13] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [25] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [37] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [49] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
## [61] FALSE
rpo[is.na(rpo$Opole),]Przy brakujących danych istnieje kilka sposobów na zastąpienie pustych rekordów zamiast usuwania całych wierszy. Poniżej zaprezentowano wybrane metody oraz uzasadnienie wyboru:
Uzupełnienie o wiedzę faktyczną - jak wspomniano, weryfikacja dostępnych danych jest niemożliwa w wykonaniu autorów.
Wykorzystanie danych z innego źródła - zaburzyłoby to podstawową analizę danych oraz byłoby zbyt czasochłonne względem oczekiwanych korzyści.
Zastąpienie brakujących rekordów medianą lub średnią - metoda adekwatna do potrzeb projektowych.
Brakujące wartości można zastąpić na kilka sposobów; puste dane można obliczyć albo za pomocą średniej lub mediany z brakującego okresu tudzież jako średnia lub mediana dla brakującego miasta.
Wykres w poprzednim rozdziale pokazał jasno, że wartości badane (w tym przypadku ceny) w badanym okresie zdecydowanie wzrosły. Tym samym druga metoda może prowadzić do wypaczeń zarówno w przypadku średniej jak i mediany. Innym wnioskiem jaki można było wyciągnąc z wykresu to różnice pomiędzy średnimi cenami w poszczególnych miastach co przejawiało się w odległości pomiędzy liniami reprezentującymi poszczególne miasta.
Wybrano zatem pierwszy sposób z uwzględnieniem mediany. Zdefiniowano wartości statystyki dla każdego brakującego kwartału.
rpoy2006q4 <- median(as.numeric(rpo[2,]), na.rm = T,)
rpoy2007q1 <- median(as.numeric(rpo[3,]), na.rm = T)
rpoy2007q2 <- median(as.numeric(rpo[4,]), na.rm = T)
rpty2007q1 <- median(as.numeric(rpt[3,]), na.rm = T)Za pomocą filtrowania oraz subsettingu uzupełniono obliczone wartości w puste miejsca odpowiednich ramek danych. Aby zaadresować unikalny wiersz wykorzystano wartość w pierwszej kolumnie odpowiadającej Białemustokowi.
rpo[is.na(rpo$Opole) & rpo$Białystok == 2727, "Opole"] <- rpoy2006q4
rpo[is.na(rpo$Opole) & rpo$Białystok == 4181, "Opole"] <- rpoy2007q1
rpo[is.na(rpo$Opole) & rpo$Białystok == 4725, "Opole"] <- rpoy2007q2
rpt[is.na(rpt$Opole) & rpt$Białystok == 3500, "Opole"] <- rpty2007q1Z racji faktu, iż puste rekordy przejawiały się w pierwszych wierszach poszczególnych data frames, do sprawdzenia wystarczy funkcja head() dla obu rynków. Niemniej w celu absolutnej pewności zastosowano powtórnie linijki, których zadaniem było wskazanie brakujących rekordów.
head(rpo)head(rpt)rpo[!complete.cases(rpo),]rpt[!complete.cases(rpt),]Uzupełnianie brakujących danych zostało ukończone z powodzeniem. Tym samym można przystąpić do analizy i wizualizacji wyników.
Pierwszym krokiem w celu dodania wartości obliczeniowej dla badanych rynków będzie dodanie podstawowych statystyk takich jak średnia, mediana, odchylenie standardowe, minimalna wartość oraz maksymalna wartość. Najprostszym sposobem w tym przypadku było rozpisanie funkcji, która zebrałaby odpowiednie dane w postaci wektorów oraz połączenie otrzymanych ramek danych z danymi rynkowymi.
basic_stats <- function(x, digits = 3L, ...) {
x <- c(x, recursive = TRUE, use.names = FALSE)
res <- c(mean = mean(x, ...), sd = sd(x, ...),
median = median(x, ...), max = max(x, ...), min = min(x, ...))
round(res, digits = 0)
}
rpo <- cbind(rpo, t(apply(rpo, 1, basic_stats, na.rm = TRUE)))
rpt <- cbind(rpt, t(apply(rpt, 1, basic_stats, na.rm = TRUE)))
rwo <- cbind(rwo, t(apply(rwo, 1, basic_stats, na.rm = TRUE)))
rwt <- cbind(rwt, t(apply(rwt, 1, basic_stats, na.rm = TRUE)))Po usunięciu kolumny “Kwartał” , badane rynki nie posiadają zmiennej czasowej. Za pomocą pakietu zoo, zwektoryzowano zmienną date dla każdego rynku oraz dołączono kolumnę do każdej z badanych ramek.
date <- c("Q3 2006", "Q4 2006", "Q1 2007", "Q2 2007","Q3 2007",
"Q4 2007", "Q1 2008", "Q2 2008", "Q3 2008","Q4 2008",
"Q1 2009", "Q2 2009", "Q3 2009", "Q4 2009", "Q1 2010",
"Q2 2010", "Q3 2010", "Q4 2010", "Q1 2011", "Q2 2011",
"Q3 2011", "Q4 2011", "Q1 2012", "Q2 2012", "Q3 2012",
"Q4 2012", "Q1 2013", "Q2 2013", "Q3 2013", "Q4 2013",
"Q1 2014", "Q2 2014", "Q3 2014", "Q4 2014", "Q1 2015",
"Q2 2015", "Q3 2015", "Q4 2015", "Q1 2016", "Q2 2016",
"Q3 2016", "Q4 2016", "Q1 2017", "Q2 2017", "Q3 2017",
"Q4 2017", "Q1 2018", "Q2 2018", "Q3 2018", "Q4 2018",
"Q1 2019", "Q2 2019", "Q3 2019", "Q4 2019", "Q1 2020",
"Q2 2020", "Q3 2020", "Q4 2020", "Q1 2021", "Q2 2021",
"Q3 2021")
library(zoo)##
## Dołączanie pakietu: 'zoo'
## Następujące obiekty zostały zakryte z 'package:base':
##
## as.Date, as.Date.numeric
as.yearqtr(format(date), "Q%q %Y")## [1] "2006 Q3" "2006 Q4" "2007 Q1" "2007 Q2" "2007 Q3" "2007 Q4" "2008 Q1"
## [8] "2008 Q2" "2008 Q3" "2008 Q4" "2009 Q1" "2009 Q2" "2009 Q3" "2009 Q4"
## [15] "2010 Q1" "2010 Q2" "2010 Q3" "2010 Q4" "2011 Q1" "2011 Q2" "2011 Q3"
## [22] "2011 Q4" "2012 Q1" "2012 Q2" "2012 Q3" "2012 Q4" "2013 Q1" "2013 Q2"
## [29] "2013 Q3" "2013 Q4" "2014 Q1" "2014 Q2" "2014 Q3" "2014 Q4" "2015 Q1"
## [36] "2015 Q2" "2015 Q3" "2015 Q4" "2016 Q1" "2016 Q2" "2016 Q3" "2016 Q4"
## [43] "2017 Q1" "2017 Q2" "2017 Q3" "2017 Q4" "2018 Q1" "2018 Q2" "2018 Q3"
## [50] "2018 Q4" "2019 Q1" "2019 Q2" "2019 Q3" "2019 Q4" "2020 Q1" "2020 Q2"
## [57] "2020 Q3" "2020 Q4" "2021 Q1" "2021 Q2" "2021 Q3"
date <- as.Date(as.yearqtr(format(date), "Q%q %Y"))
rpo <- cbind(date, rpo)
rpt <- cbind(date, rpt)
rwo<- cbind(date, rwo)
rwt <- cbind(date, rwt)Dodano także utworzony manualnie wektor łączący poszczególne podokresy w ujęcie roczne. Wektor “ROK” został także dodany do poszczególnych ramek.
ROK <- c(2006,
2006,
2007,
2007,
2007,
2007,
2008,
2008,
2008,
2008,
2009,
2009,
2009,
2009,
2010,
2010,
2010,
2010,
2011,
2011,
2011,
2011,
2012,
2012,
2012,
2012,
2013,
2013,
2013,
2013,
2014,
2014,
2014,
2014,
2015,
2015,
2015,
2015,
2016,
2016,
2016,
2016,
2017,
2017,
2017,
2017,
2018,
2018,
2018,
2018,
2019,
2019,
2019,
2019,
2020,
2020,
2020,
2020,
2021,
2021,
2021)
ROK <- as.factor(ROK)
rpo <-cbind(ROK, rpo)
rpt <- cbind(ROK, rpt)
rwo<- cbind(ROK, rwo)
rwt <- cbind(ROK, rwt)Tym samym dane są w pełni gotowe do analizy.
head(rpo)head(rpt)head(rwo)head(rwt)Zebrano ostateczne ramki danych, które zostaną wykorzystane do analizy. W celu zapobieżenia błędom, utworzono kopie zapasowe w postaci kopii ramek danych.
rpo_backup <- rpo
rpt_backup <- rpt
rwo_backup <- rwo
rwt_backup <- rwtZ racji szerokich możliwości przygotowanych danych, autorzy zdecydowali się na zaledwie kilka analiz ukazujących możliwości prezentacyjne oraz wizualizacyjne względem badanych rynków. Analizy są dobrane subiektywnie mają za zadanie pokazać badany zbiór cen z kilku perspektyw. Wykresy zostały wykonane z pomocą pakietów “ggplot2” oraz “gridExtra”.
Pierwszym elementem badanym jest rozkład przeciętnej ceny każdego kwartału za pomocą histogramu na rynku wtórnym, wśród cen ofertowych.
library(ggplot2)
sum_av <- ggplot(data=rwo, aes(x=mean)) +
geom_histogram(bindwidth =10, fill="White", colour="Blue") +
xlab("Wartość uśrednionej ceny mieszkań na rwo") +
ylab("") +
ggtitle("Rozkład średniej ceny za m2") +
theme(plot.title = element_text(hjust = 0.5))## Warning: Ignoring unknown parameters: bindwidth
sum_av## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
Jak można zauważyć z wykresu, rozkład uśrednionych cen za metr kwadratowy na rynku wtórnym (spośród cen ofertowych) przybierał włąściwości rozkładu normalnego skupiając się wokół centrum w okolicach 5500 złotych za metr kwadratowy. Uzasadnienie faktyczne takiego stanu odnajduje się w rzeczywistości. Spośród najbardziej zamożnych miast, kilka wyróżnia się wysoką ceną za metr kwadratowy, jak na przykład Gdańsk czy Poznań. Istnieją jednak także miasta, które nie są dla większości pierwszym wyborem zamieszkania, relatywizując do zamożniejszych odpowiedników. Wówczas (w tym przypadku właściciele mieszkań) obniżają ceny oferowane aby zwiększyć popyt na sprzedawane dobro.
Rozkład nie jest jedynym elementem, dzięki któremu można odczytać wartości danych. Kolejnym krokiem w analizie jest uporządkowanie maksymalnych cen ofertowych mieszkań na rynku pierwotnym od najmniejszej do największej z uwzględnieniem kwartału, w jakim wystąpiła dana cena. W tym celu autorzy posłużyli się pakietem “dplyr”.
library(dplyr)##
## Dołączanie pakietu: 'dplyr'
## Następujące obiekty zostały zakryte z 'package:stats':
##
## filter, lag
## Następujące obiekty zostały zakryte z 'package:base':
##
## intersect, setdiff, setequal, union
ex_1 <- rpo %>% select(max, date) %>% arrange((max))
ex_1Dane zaprezentowano także za pomocą wykresu:
vis_ex_1 <- ggplot(data=ex_1, aes(x=date, y=max)) +
geom_line() +
geom_point(aes(size=max)) +
xlab("Czas") +
ylab("Maks. cena ofertowa na r. pierwotnym") +
ggtitle("Kształtowanie cen ofertowych na rynku pierwotnym") +
theme(plot.title = element_text(hjust = 0.5))
vis_ex_1Wizualizacja pokrywa się z otrzymanymi danymi zmiennej ex_1. Od 2009 roku, rynek nie zaobserwował tak wysokich cen za metr kwadratowy jak w ostatnich podokresach. Tym samym widać zarówno okres spekulacji pomiędzy 2008-10 oraz załamanie cen na rynku pierwotnym, którego efektem był kryzys mieszkaniowy w 2012 roku, a także niebezpieczną tendencję wzrostu cen, która trwa aż do ostatniego badanego kwartału. Zauważa się tym samym niebezpieczeństwo powstania bańki na rynku nieruchomości oraz związanych z nią potencjalnych kryzysów. Innym wytłumaczeniem powstałego trendu, według niektórych analityków, jest moda mieszkaniowa oraz boom na rynku deweloperskim.
Według portalu samorządowego, najdroższe mieszkania w Polsce, zarówno na rynku pierwotnym jak i wtórnym, konsument może nabyć w Warszawie oraz Gdańsku. Potwierdzają to także dane zebrane na potrzeby raportu. Interesującym aspektem wydaje się jednak kształtowanie różnic pomiędzy cenami, gdyż w świadomości publicznej, stolica Polski była zdecydowanie kojarzona z najwyższymi cenami.
W tym celu przygotowano pogrupowane względem odchylenia standardowego zestawienie porównawcze w formie listy o malejącej cenie ofertowej z uwzględnieniem daty danej obserwacji na rynku wtórnym:
ex_2 <- rwo %>% select(Warszawa, Gdańsk, sd, date) %>% group_by(sd) %>% arrange(desc(date))
ex_2Należy dostrzec pewne odniesienia względem wcześniejszych badań. Najwyższą cenę za metr kwadratowy czytelnik zaobserwuje w pierwszych rzędach, które kształtują się odwrotną chronologią. Oznacza to, że wspomniana wcześniej bańka mieszkaniowa wciąż się napełnia, a tendencja wzrostowa, na bazie różnic pomiędzy kolejnymi obserwacjami w ujęciu łańcuchowym wciąż się rozpędza.
Do zaobserwowania różnic pomiędzy odchyleniami, autorzy wykorzystali kolejny wykres:
vis_ex_2 <- ggplot(data=ex_2, aes(x=Warszawa, y=Gdańsk, color=sd)) +
geom_line(size=2) +
geom_smooth() +
ggtitle("Porównanie odchylenia standardowego ceny Warszawy i Gdańska") +
theme(plot.title = element_text(hjust = 0.5))
vis_ex_2## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
Na bazie obserwacji dwóch przedstawionych zestawień należy zauważyć, że największe odchylenia cen między miastami przypadały w okresie, gdy ceny różniły się o niecałe 2000 złotych za metr kwadratowy w okresie stagnacji rynkowej zauważonej w poprzednich badaniach. Wówczas ceny ofertowe w Warszawie na rynku wtórnym utrzymywały stabilną, relatywnie wysoką cenę, zaś dopiero w ostatnich 5 latach, odpowiedniki cenowe w Gdańsku zdecydowanie wzrosły, wyrównując tym samym wyniki osiągane w stolicy. W ostatnich latach Gdańsk zyskał na popularności zawdzięczając ten ewenement szeregowi czynników takich jak ekologia, rozwój infrastruktury czy stabilna polityka samorządowa. Być może podobne elementy w przyszłości posłużą do oszacowania odpowiednich predykcji w analogicznych przypadkach.
Cena transakcyjna nierzadko różni się od ofert przedstawianych przez deweloperów. Wynika to przede wszystkim z możliwości negocjacyjnych obydwu stron, planowanej rozbudowy infrastruktury czy potencjalnego dostępu do obiektów inwestycyjnych czy obiektów niosących ze sobą pożytek publiczny. Niniejsze zestawienie zostało przygotowane w formie boxplot - narzędzia przedstawiającego nie tylko kształtowanie się średniej ceny rocznej, ale przedstawienie wahań wewnątrz podokresów w formie rozproszonej ceny względem “pudełek” oraz ich wielkości. W tym celu przygotowano odpowiednią ramkę danych uwzględniającą jedynie ceny średnie wszystkich rynków wraz z kwartalną datą obserwacji.
rpo_mean <- rpo$mean
rpt_mean <- rpt$mean
rwo_mean <- rwo$mean
rwt_mean <- rwt$mean
av_price <- data.frame(rpo_mean, rpt_mean, rwo_mean, rwt_mean, ROK)
head(av_price)Wyniki przykładu, jakim są ceny transakcyjne dotyczące rynku pierwotnego przedstawiono na wykresie:
vis_ex_3 <- ggplot(data=av_price, aes(x=ROK, y=rpt_mean, colour=ROK)) +
geom_boxplot(size=0.5, alpha=0.5) +
geom_jitter() +
xlab("Rok") +
ylab("Przeciętna cena transakcyjna na rynku pierwotnym") +
ggtitle("Kształtowanie przeciętnej ceny mieszkań w ujęciu rocznym w Polsce") +
theme(plot.title = element_text(hjust = 0.5))
vis_ex_3Należy zauważyć zasadniczą wadę wykresu w postaci niepełnych wartości dwóch okresów. Dane zebrane na potrzeby raportu uwzględniają dwa lata, w których przedstawienie kwartalnych cen jest niepełne - rok 2006 zawierał jedynie dwa ostatnie kwartały, zaś ostatni badany okres - trzy. Interesującą obserwacją jest rok 2007, czyli moment zmiany władzy w Polsce po wielomiesięcznych kryzysach pośrednio związanych także z rynkiem nieruchomości, co przekłada się na wielkość pudełka oraz wąsów w tym okresie. Kolejne lata niosły ze sobą względnie stabilne (w odniesieniu do rozproszenia pomiędzy kwartałami) ceny. Istotne wahania międzykwartałowe zauważa się od początku 2017 roku, gdy międzykwartylowe wartości zaczynają się od siebie regularnie oddalać. Wynika to z gwałtownego i regularnego wzrostu cen przeciętnych, co zaobserwowano także we wcześniejszej części pracy.
Dla pełniejszego obrazu, ten trend (widoczny także na pozostałych rynkach) pokazano na przykładzie gdańskich cen transakcyjnych na rynku wtórnym:
vis_ex_4 <- ggplot(data = rwt, aes(x=date, y=Gdańsk)) +
geom_area(aes(fill=ROK)) +
geom_smooth(alpha=2.5, color="Black", size=2) +
xlab("Rok") +
ylab("Cena za metr kwadratowy") +
ggtitle("Przeciętna cena transakcyjna na rynku wtórnym w Gdańsku") +
theme(plot.title = element_text(hjust = 0.5))
vis_ex_4## `geom_smooth()` using method = 'loess' and formula 'y ~ x'
Widoczna jest zarówno tendencja wzrostowa, którą należy także odnieść do wcześniejszego zestawienia z Warszawą jak kształtowanie ceny pomiędzy kwartałami.
Jak wspomniano, stołeczne miasto w badanym okresie charakteryzowało się najwyższą ceną w przeliczeniu za metr kwadratowy na wszystkich rynkach. Interesującym wydaje się, na ile pozostałe, powszechnie popularne destynacje mieszkaniowe plasowały się względem średniej. Miasta zostały arbitralnie wybrane przez instytucję, która zapewniła dostęp do danych, czyli NBP. Wśród nich znalazły się Gdynia, Gdańsk, Kraków, Łódź, Poznań oraz Wrocław. Wyniki przedstawiono na poniższym wykresie:
kolory <- c("Gdynia" = "Red", "Kraków" = "Purple", "Gdańsk" = "DarkBlue", "Łódź" = "DarkGreen", "Poznań" = "DarkRed", "Wrocław" = "Grey")
vis_ex_5 <- ggplot(data = rpo, aes(x=date, y=mean), color="Black", size=1.3) +
geom_line(aes(x=date, y=Gdynia, color = "Gdynia")) +
geom_line(aes(x=date, y=Kraków, color= "Kraków")) +
geom_line(aes(x=date, y=Gdańsk, color = "Gdańsk")) +
geom_line(aes(x=date, y=Łódź, color = "Łódź")) +
geom_line(aes(x=date, y=Poznań, color = "Poznań")) +
geom_line(aes(x=date, y=Wrocław, color = "Wrocław")) +
geom_jitter() +
xlab("Rok") +
ylab("Cena ofertowa na rynku pierwotnym") +
ggtitle("Zestawienie cen ofertowych w 6 miastach względem średniej") +
theme(plot.title = element_text(hjust = 0.5)) +
labs(color = "Legenda")
scale_color_manual(values = kolory)## <ggproto object: Class ScaleDiscrete, Scale, gg>
## aesthetics: colour
## axis_order: function
## break_info: function
## break_positions: function
## breaks: waiver
## call: call
## clone: function
## dimension: function
## drop: TRUE
## expand: waiver
## get_breaks: function
## get_breaks_minor: function
## get_labels: function
## get_limits: function
## guide: legend
## is_discrete: function
## is_empty: function
## labels: waiver
## limits: Gdynia Kraków Gdańsk Łódź Poznań Wrocław
## make_sec_title: function
## make_title: function
## map: function
## map_df: function
## n.breaks.cache: NULL
## na.translate: TRUE
## na.value: grey50
## name: waiver
## palette: function
## palette.cache: NULL
## position: left
## range: <ggproto object: Class RangeDiscrete, Range, gg>
## range: NULL
## reset: function
## train: function
## super: <ggproto object: Class RangeDiscrete, Range, gg>
## rescale: function
## reset: function
## scale_name: manual
## train: function
## train_df: function
## transform: function
## transform_df: function
## super: <ggproto object: Class ScaleDiscrete, Scale, gg>
vis_ex_5Niemal wszystkie z sześciu wybranych miast znajdowały się ponad średnią (czarne punkty na wykresie) przez większą część badanego okresu. Oznacza to, że w podanym ujęciu przeciętne ceny ofertowe na rynku pierwtonym były większe niż pozostałych miast. Wyjątkiem niniejszego zestawienia jest Łódź, która niemal cały okres znajdowała się pod linią przeciętnej ceny. Można zatem wnioskować, że pozostałe z wybranych miast w dużym stopniu przyczyniają się do kształtowania przeciętnej ceny ofertowej na rynku pierwotnym.
Ostatnim zestawieniem przygotowanym na potrzeby raportu jest zestawienie porównawcze przeciętnych cen mieszkaniowych w najzamożniejszym mieście pod tym względem - Warszawie. Porównanie zostało przeprowadzone na wszystkich rynkach. W tym celu utworzono nową ramkę danych na potrzeby zestawienia oraz wykorzystano pakiet “gridExtra”, by przedstawić wyniki w jednym oknie.
Poniższy wykres przedstawia porównanie wszystkich rynków:
library(gridExtra)##
## Dołączanie pakietu: 'gridExtra'
## Następujący obiekt został zakryty z 'package:dplyr':
##
## combine
W_rpo <- rpo$Warszawa
W_rpt <- rpt$Warszawa
W_rwo <- rwo$Warszawa
W_rwt <- rwt$Warszawa
Warsaw <- data.frame(date, W_rpo, W_rpt, W_rwo, W_rwt)
p1 <- ggplot(data = Warsaw, aes(x=date, y=W_rpo)) +
geom_area(aes(x=date, y=W_rpo), alpha=0.5, color="Red", fill="Red") +
ylab("C. ofert., r. pierwotny") +
xlab("Czas")
p2 <- ggplot(data = Warsaw, aes(x=date, y=W_rpo)) +
geom_area(aes(x=date, y=W_rpt), alpha=0.5, color="Blue", fill="Blue") +
ylab("C. trans., r. pierwotny") +
xlab("Czas")
p3 <- ggplot(data = Warsaw, aes(x=date, y=W_rpo)) +
geom_area(aes(x=date, y=W_rwo), alpha=0.5, color="DarkGreen", fill="DarkGreen") +
ylab("C. ofert., r. wtórny") +
xlab("Czas")
p4 <- ggplot(data = Warsaw, aes(x=date, y=W_rpo)) +
geom_area(aes(x=date, y=W_rwt), alpha=0.5, color="Grey", fill="Grey") +
ylab("C. trans., r. wtórny") +
xlab("Czas")
Wars_comp <- grid.arrange(p1, p2, p3, p4, top = "Porównanie cen mieszkań w Warszawie")Należy zwrócić uwagę na kilka tendencji, które odnoszą się także do pozostałych miast w Polsce, gdyż mimo specyfiki cenowej Warszawy, należy uznać przykład miasta za reprezentatywny wobec społeczności wielkomiejskiej w Polsce:
Ceny transakcyjne są przeważająco niższe na rynku transakcyjnym w porównaniu do odpowiedników ofertowych.
Większa rozpiętość cenowa zauważalna jest na rynku wtórnym pomiędzy ofertą a faktyczną ceną.
Krzywa cenowa na rynku wtórnym jest bardziej płaska, co oznacza, że na tym rynku następują mniejsze wahania.
Tendencja wzrostowa jest podobna na wszystkich rynkach.
Kształtowanie przeciętnych cen transakcyjnych wiąże się z ograniczeniami w postaci pominięcia trendów sezonowych, lukratywnych inwestycji nowych deweloperów czy kryzysów społecznościowych (migracje, wahania demograficzne w dłuższym okresie). Niemniej jednak, wartości przekazane z zestawienia stanowią istotny obraz kształtowania cen na rynkach nieruchomościowych.
Jak wspomniano, w zakresie raportu badanie cen jest ograniczone przez szereg czynników. Autorzy przyjęli jednak, że same wartości stanowią pewnego rodzaju odzwierciedlenie rynku nieruchomości w Polsce, a na tej podstawie należy wysunąć kilka wniosków.
Przede wszystkim, rynek ukierunkowany jest na tendencję wzrostową. Zakres danych ogranicza możliwość określenia szacunku przyczynowego takiego stanu rzeczy, jednak dopuszczalne hipotezy wiążą się z otoczeniem ekonomicznym, jak rosnąca inflacja (choć dotyczy ona końcowych lat) oraz bańka spekulacyjna. Należy jednocześnie uwzględnić czynniki społeczne, takie jak moda na posiadanie własnego lokum oraz coraz popularniejsze źródło dodatkowego dochodu w postaci wynajmu kolejnego mieszkania.
Kolejnym wnioskiem jest zestawienie cenowe wśród najbogatszych miast. Jak pokazano, wahania odchyleń standardowych są zauważalne w coraz mniejszym stopniu. Potwierdzał to także wykres, który zestawiał 6 najzamożniejszych miast, gdzie w ostatnich okresach, przeciętne ceny zaczęły coraz mniej się różnić. Oznacza to zarówno wzrost poziomu życia w wielkich miastach w Polsce jak i spadek znaczenia Warszawy jako wyznacznika tego poziomu.
Ostatni wniosek wiąże się ze zwiększającą się rozpiętością pomiędzy cenami ofertowymi oraz transakcyjnymi na rynkach. Narastająca tendencja może wskazywać na mechanizmy spekulatywne w podażowej części rynku, a więc deweloperów oraz właścicieli mieszkań na sprzedaż. Rynki są ze sobą ściśle związane, zatem narastające spekulacje odnoszą się wzajemnie do siebie, co tworzy niebezpieczeństwo kryzysu i załamania się rynku nieruchomości w przewidywalnym okresie.
Badanie było ograniczone do danych cenowych. Istotnym wzbogaceniem mogłoby być uwzględnienie mierzalnych aspektów ekonomicznych, takich jak przeciętne wynagrodzenie, inflacja czy też dane związane z rynkiem najemczym. Nie dokonywano także większych obliczeń cenowych ze względu na ograniczony zakres raportu, przykładowym rozwinięciem mogłoby być zbadanie jednego miasta lub porównanie dwóch względem modelu rynkowego.