Wprowadzenie

Rynek nieruchomości odgrywa kluczową rolę w gospodarce, zaspokajając równocześnie potrzeby mieszkaniowe jak i inwestycyjne. W naszej pracy przeanalizujemy dane dotyczące cen mieszkań w Polsce w czerwcu 2024. Analizę wykonamy za pomocą wyznaczania najważniejszych wskaźników statystycznych oraz wizualizacji na wykresach. W pracy zostaną omówione główne czynniki wpływające na kształtowanie się cen nieruchomości, a także ich potencjalne skutki dla przyszłości rynku mieszkaniowego w Polsce. Analiza ta pozwoli określić występujące trendy i problemy kształtujące się na rynku mieszkaniowym.

Przygotowanie do data cleansing, data wrangling

Wczytanie oraz wyświetlenie danych

data <- read_csv("apartments_pl_2024_06.csv")
head(data)

Sprawdzenie jakie mamy typy danych

glimpse(data)
## Rows: 21,501
## Columns: 28
## $ id                   <chr> "811891f98a870dfd6e414374a0a85560", "adaf636d0c44…
## $ city                 <chr> "szczecin", "szczecin", "szczecin", "szczecin", "…
## $ type                 <chr> "blockOfFlats", "apartmentBuilding", "apartmentBu…
## $ squareMeters         <dbl> 47.00, 88.22, 117.00, 33.31, 56.00, 68.61, 101.25…
## $ rooms                <dbl> 2, 3, 5, 1, 3, 3, 4, 1, 4, 1, 4, 3, 4, 3, 1, 2, 3…
## $ floor                <dbl> 6, 1, 4, 1, 7, 4, NA, 7, NA, 4, 4, 3, 2, NA, 1, 2…
## $ floorCount           <dbl> 12, 2, 4, 4, 7, 4, 2, 11, 3, 5, 4, 4, 6, 4, 10, 3…
## $ buildYear            <dbl> 1981, 2000, NA, 1963, 2018, 1997, 1930, 1970, 193…
## $ latitude             <dbl> 53.42854, 53.44909, 53.44310, 53.43610, 53.44746,…
## $ longitude            <dbl> 14.55281, 14.51684, 14.56135, 14.54120, 14.55781,…
## $ centreDistance       <dbl> 0.79, 4.09, 2.19, 1.93, 2.68, 3.94, 7.95, 2.52, 1…
## $ poiCount             <dbl> 67, 0, 10, 39, 10, 7, 14, 15, 18, 25, 5, 5, 9, 47…
## $ schoolDistance       <dbl> 0.288, 0.509, 0.216, 0.073, 0.268, 0.139, 0.201, …
## $ clinicDistance       <dbl> 0.285, 1.039, 0.611, 0.326, 0.771, 1.336, 2.454, …
## $ postOfficeDistance   <dbl> 0.268, 0.998, 0.743, 0.284, 0.676, 0.926, 0.315, …
## $ kindergartenDistance <dbl> 0.245, 0.676, 0.280, 0.089, 0.260, 0.930, 0.250, …
## $ restaurantDistance   <dbl> 0.068, 0.661, 0.298, 0.180, 0.322, 0.071, 0.216, …
## $ collegeDistance      <dbl> 0.593, 1.192, 1.522, 0.041, 1.643, 0.786, NA, 1.2…
## $ pharmacyDistance     <dbl> 0.085, 0.668, 0.229, 0.388, 0.178, 0.304, 0.316, …
## $ ownership            <chr> "condominium", "condominium", "udział", "cooperat…
## $ buildingMaterial     <chr> "concreteSlab", "brick", "brick", "brick", "brick…
## $ condition            <chr> NA, "premium", "premium", NA, "premium", NA, "pre…
## $ hasParkingSpace      <chr> "no", "yes", "yes", "yes", "yes", "no", "yes", "n…
## $ hasBalcony           <chr> "yes", "yes", "yes", "no", "yes", "yes", "yes", "…
## $ hasElevator          <chr> "yes", "no", "no", "no", "yes", "no", "no", "yes"…
## $ hasSecurity          <chr> "no", "no", "no", "yes", "yes", "no", "no", "no",…
## $ hasStorageRoom       <chr> "yes", "no", "no", "yes", "yes", "yes", "yes", "y…
## $ price                <dbl> 449000, 950000, 1099000, 380000, 799000, 599000, …

Sprawdzenie czy mamy prakujące obserwacje oraz ile ich jest

n_miss(data)
## [1] 37990

Występują brakujące obserwacje.

Sprawdzenie ile brakujących obserwacji jest w każdej kolumnie

miss_var_summary(data)

Największe braki danych w kolumnach condition, buildingMaterial, type, floor oraz buildYear (w każdym powyżej 15%).

Pokazanie ile jest brakujących obserwacji w wierszach

miss_case_table(data)

Większość obserwacji ma od 1 do 3 braków, co pozwala na zastosowanie imputacji brakujących danych.

Wizualizacja braków danych

vis_miss(data, cluster = TRUE, sort_miss = TRUE)

Graficzne ukazanie, w których kolumnach mamy najwięcej brakujacych danych. Wykres potwierdza, że są to kolumny condition (74%), building material (41%), type (20%), floor (17%) oraz buildYear (16%).

Wykres przedstawiający wzorce braków danych

gg_miss_upset(data)

Z wykresu możemy odczytać, że najwięcej braków danych występuje jedynie w kolumnie condition, bez współwystępowania braku w innych kolumnach. Większa liczba braków danych występuje też zależnie zarówno w kolumnie condition jak i buildingMaterial oraz w kolumnach condition, buildingMaterial i type.

Grupowanie braków według miasta

data %>% 
  group_by(city) %>% 
  miss_var_summary() %>% 
  View()

Nie ma istotnych różnic w brakach danych między miastami. We wszystkich największy odsetek brakujacych danych stanowi kolumna condition.

Sprawdzenie i analiza wartości odstających

library(ggplot2)
library(patchwork)

wykres1 <- ggplot(data, aes(y = price)) +
  geom_boxplot(fill = "lightblue") +
  ggtitle("Boxplot cena")

wykres2 <- ggplot(data, aes(y = squareMeters)) +
  geom_boxplot(fill = "lightblue") +
  ggtitle("Boxplot metry kwadratowe")

combined_plots <- wykres1 + wykres2
combined_plots

Cena -> wartości odstające powyżej 2mln, do 3mln - brak podstaw do usuwania danych odstających, gdyż są to realne ceny za mieszkania.

Metry kwadratowe -> wartości odstające do max 140m2 - mają sens.

library(ggplot2)
library(patchwork)

wykres1 <- ggplot(data, aes(y = rooms)) +
  geom_boxplot(fill = "lightblue") +
  ggtitle("Boxplot pokoje")

wykres2 <- ggplot(data, aes(y = floor)) +
  geom_boxplot(fill = "lightblue") +
  ggtitle("Boxplot piętro")


combined_plots <- wykres1 + wykres2 
combined_plots

wykres3 <- ggplot(data, aes(y = floorCount)) +
  geom_boxplot(fill = "lightblue") +
  ggtitle("Boxplot liczba pięter")

wykres4 <- ggplot(data, aes(y = buildYear)) +
  geom_boxplot(fill = "lightblue") +
  ggtitle("Boxplot rok budowy")

combined_plots <- wykres3 + wykres4 
combined_plots

Pokoje, piętra oraz liczba pięter -> niewielka liczba możliwych wartości odstających, piętro na którym jest mieszkanie nie przewyższa ogólnej liczby pięter.

Rok budowy -> wartości odstające poniżej roku 1900, lecz powyżej roku 1850 - mają sens

library(ggplot2)
library(patchwork)

wykres1 <- ggplot(data, aes(y = centreDistance)) +
  geom_boxplot(fill = "lightblue") +
  ggtitle("Boxplot dystans do centrum")

wykres2 <- ggplot(data, aes(y = schoolDistance)) +
  geom_boxplot(fill = "lightblue") +
  ggtitle("Boxplot dystans do szkoły")

combined_plots <- wykres1 + wykres2 
combined_plots

wykres3 <- ggplot(data, aes(y = clinicDistance)) +
  geom_boxplot(fill = "lightblue") +
  ggtitle("Boxplot dystans do kliniki")


wykres4 <- ggplot(data, aes(y = postOfficeDistance)) +
  geom_boxplot(fill = "lightblue") +
  ggtitle("Boxplot dystans do poczty")

combined_plots <- wykres3 + wykres4 
combined_plots

wykres5 <- ggplot(data, aes(y = kindergartenDistance)) +
  geom_boxplot(fill = "lightblue") +
  ggtitle("Boxplot dystans do przedszkola")

wykres6 <- ggplot(data, aes(y = restaurantDistance)) +
  geom_boxplot(fill = "lightblue") +
  ggtitle("Boxplot dystans do restauracji")

combined_plots <- wykres5 + wykres6
combined_plots

wykres7 <- ggplot(data, aes(y = collegeDistance)) +
  geom_boxplot(fill = "lightblue") +
  ggtitle("Boxplot dystans do uniwersytetu")

wykres8 <- ggplot(data, aes(y = pharmacyDistance)) +
  geom_boxplot(fill = "lightblue") +
  ggtitle("Boxplot liczba dystans do apteki")

combined_plots <- wykres7 + wykres8 
combined_plots

Dużo wartości odstających w odległościach do różnych punktów usługowych, lecz poniżej 5km - wyniki mają sens.

Na podstawie powyższej analizy, możemy stwierdzić, że pomimo występowania wartości odstających nie wyglądają one na błędy i nasze dane są spójne, brak konieczności usuwania danych odstających.

Imputacja danych

  1. Condition

Z racji tego, że stan normalny zazwyczaj nie jest określany w ogłoszeniach nieruchomości (chcemy się pochwalić stanem premium lub zaznaczyć niski standard mieszkania), z logicznego punktu widzenia, możemy uzupełnić braki danych w tej kolumnie jako ‘standard’.

data1Condition <- data %>% 
  mutate(condition = ifelse(is.na(condition), "Standard", condition))
View(data1Condition)
na_count_condition <- sum(is.na(data1Condition$condition))
print(na_count_condition)
## [1] 0

Brak wartości NA

  1. Building Material

Zmienna ta nie powinna mieć istotnego wpływu na cenę, kupujący zazwyczaj nie zwacają uwagi na aspekt materiałów użytych do budowy domu, w którym znajduje się mieszkanie. Aby zastąpić brakujące obserwacje użyjemy sformułowania “Material is not known/different building material”.

data2Condition.buildingMaterial <- data1Condition %>% 
  mutate(buildingMaterial = ifelse(is.na(buildingMaterial), "Material is not known/different building material", buildingMaterial))
View(data2Condition.buildingMaterial)
na_count_condition <- sum(is.na(data2Condition.buildingMaterial$buildingMaterial))
print(na_count_condition)
## [1] 0

Brak wartości NA

3.Type

Brakujące wartości zostaną uzupełnione z użyciem metody k-NN (k-Nearest Neighbors), która zastąpi nam brakujące wartości na podstawie sąsiadujących obserwacji, które są najbardziej podobne do brakującego wiersza.

dataCBT <- kNN(data2Condition.buildingMaterial,
                    variable = c("type"),        
                    k = 5,                       
                    weightDist = TRUE)          
View(dataCBT)

na_count_condition <- sum(is.na(dataCBT$type))
print(na_count_condition)
## [1] 0

Brak wartości NA

  1. Floor Count

Brakujące wartości uzupełnione na podstawie grupowania oraz wyliczania mediany wartości w tychże grupach. Do porównania zostały użyte zmienne city, type oraz condition.

dataCBTFC <- dataCBT %>%
  group_by(city, type, condition) %>%  
  mutate(floorCount = ifelse(is.na(floorCount), median(floorCount, na.rm = TRUE), floorCount)) %>%
  ungroup()
View(dataCBTFC)
na_count_condition <- sum(is.na(dataCBTFC$floorCount))
print(na_count_condition)
## [1] 0

Brak wartości NA

5.Floor

Brakujące wartości uzupełnione na podstawie grupowania oraz wyliczania mediany wartości w tychże grupach. Do porównania zostały użyte zmienne floorCount oraz type.

data2 <- dataCBTFC %>%
  group_by(floorCount, type) %>%
  mutate(floor = ifelse(is.na(floor), median(floor, na.rm = TRUE), floor)) %>%
  ungroup()
View(data2)
na_count_condition <- sum(is.na(data2$floor))
print(na_count_condition)
## [1] 0

Brak wartości NA

  1. Build Year

Brakujące wartości uzupełnione na podstawie grupowania oraz wyliczania mediany wartości w tychże grupach. Do porównania zostały użyte zmienne floorCount, type, city.

data3 <- data2 %>%
  group_by(floorCount, type, city) %>%
  mutate(buildYear = ifelse(is.na(buildYear), median(buildYear, na.rm = TRUE), buildYear)) %>%
  ungroup()
View(data3)
na_count_condition <- sum(is.na(data3$buildYear))
print(na_count_condition)
## [1] 37

37 wartości NA, ponawiamy imputację danych za pomocą mediany, lecz tym razem dla całego zbioru danych (liczba brakujących obserwacji jest bardzo mała).

data4 <- data3 %>%
  mutate(buildYear = ifelse(is.na(buildYear), 
                            median(buildYear, na.rm = TRUE), 
                            buildYear))
na_count_condition <- sum(is.na(data4$buildYear))
print(na_count_condition)
## [1] 0

Brak wartości NA

7.has Elevator

Brakujące wartości zostaną uzupełnione z użyciem metody k-NN (k-Nearest Neighbors), która zastąpi nam brakujące wartości na podstawie sąsiadujących obserwacji, które są najbardziej podobne do brakującego wiersza.

data5 <- kNN(data4, 
                variable = c("hasElevator"),
                k = 5, 
                weightDist = TRUE)
View(data5)

na_count_condition <- sum(is.na(data5$hasElevator))
print(na_count_condition)
## [1] 0

Brak wartości NA

  1. Distance - college, clinic, restaurant, pharmacy, postoffice, kindergarten, school

Mała liczba wartości NA, imputacja może być wyliczana na podstawie mediany dla wszystkich obserwacji.

data1 <- data5 %>%
  mutate(collegeDistance = ifelse(is.na(collegeDistance), median(collegeDistance, na.rm = TRUE), collegeDistance))

miss_var_summary(data1)
data2 <- data1 %>%
  mutate(clinicDistance = ifelse(is.na(clinicDistance), median(clinicDistance, na.rm = TRUE), clinicDistance))

miss_var_summary(data2)
data3 <- data2 %>%
  mutate(restaurantDistance = ifelse(is.na(restaurantDistance), median(restaurantDistance, na.rm = TRUE), restaurantDistance))

miss_var_summary(data3)
data4 <- data3 %>%
  mutate(pharmacyDistance = ifelse(is.na(pharmacyDistance), median(pharmacyDistance, na.rm = TRUE), pharmacyDistance))

miss_var_summary(data4)
data5 <- data4 %>%
  mutate(postOfficeDistance = ifelse(is.na(postOfficeDistance), median(postOfficeDistance, na.rm = TRUE), postOfficeDistance))

miss_var_summary(data5)
data6 <- data5 %>%
  mutate(kindergartenDistance = ifelse(is.na(kindergartenDistance), median(kindergartenDistance, na.rm = TRUE), kindergartenDistance))

miss_var_summary(data6)
data7 <- data6 %>%
  mutate(schoolDistance = ifelse(is.na(schoolDistance), median(schoolDistance, na.rm = TRUE), schoolDistance))
miss_var_summary(data7)

BRAK WARTOŚCI ODSTAJĄCYCH W NASZYM ZBIORZE DANYCH

Wizualizacja danych

Wykres 1: Histogram cen mieszkań

p1 <- ggplot(data7, aes(x = price)) +
  geom_histogram(bins = 30, fill = "skyblue", color = "black") +
  labs(title = "Rozkład cen mieszkań", x = "Cena (PLN)", y = "Liczba mieszkań") +
  theme_minimal()
ggplotly(p1)
  1. Prawostronna skośność rozkładu – większość mieszkań ma ceny skoncentrowane w niższych przedziałach cenowych natomiast pojedyncze, drogie mieszkania powodują wydłużenie się ogona rozkładu w prawą stronę.

  2. Największa liczba mieszkań ma ceny w przedziale od ok. 500 tys. zł do 1 mln zł. Liczba dostępnych mieszkań maleje wraz ze wzrostem ceny.

Wykres 2: Odległość od centrum vs cena

p2 <- ggplot(data7, aes(x = centreDistance, y = price)) +
  geom_point(alpha = 0.6, color = "blue") +
  geom_smooth(method = "lm", se = FALSE, color = "red") +
  labs(title = "Odległość od centrum a cena", 
       x = "Odległość od centrum (km)", 
       y = "Cena (PLN)") +
  theme_minimal() +
  facet_wrap(~ city)
ggplotly(p2)
  1. Widoczna jest ogólna tendencja spadku cen mieszkań wraz ze wzrostem odległości od centrum miasta. Ceny mieszkań są najwyższe w centralnych lokalizacjach, a następnie stopniowo maleją.

  2. W miastach takich jak Białystok, Częstochowa, Łódź czy Lublin zależność ta może się różnić. Najbardziej natomiast uwydatnia się w największych miastach, czyli Warszawie, Gdańsku i Gdyni.

Wykres 3: Cena w zależności od odległości od uczelni

p3 <- ggplot(data7, aes(x = collegeDistance, y = price)) +
  geom_point(alpha = 0.6, color = "purple") +
  geom_smooth(method = "lm") +
  labs(title = "Cena w zależności od odległości od uczelni", 
       x = "Odległość od uczelni (km)", 
       y = "Cena (PLN)") +
  theme_minimal() +
  facet_wrap(~ city)
ggplotly(p3)
  1. Ceny mieszkań przeciętnie są tym wyższe, im bliżej uczelni znajduje się jego lokalizacja. Najlepiej tę zależność widać w największych miastach: Gdańsk, Warszawa, Kraków.
  2. Różnice w cenach mogą wynikać z charakterystyki poszczególnych miast oraz znaczenia uczelni dla lokalnego rynku nieruchomości.

Wykres 4: Liczba mieszkań według liczby pokoi

p4 <- ggplot(data7, aes(x = as.factor(rooms))) +
  geom_bar(fill = "orange", color = "black") +
  labs(title = "Liczba mieszkań według liczby pokoi", x = "Liczba pokoi", y = "Liczba mieszkań") +
  theme_minimal()
ggplotly(p4)
  1. Najliczniejsza grupa mieszkań to mieszkania 2 i 3 pokojowe.
  2. Mieszkania posiadające 1, 5 oraz 6 pokoi występują najrzadziej.

Wykres 5: Cena w zależności od stanu mieszkania

p5 <- ggplot(data7, aes(x = condition, y = price, fill = condition)) +
  geom_boxplot(outlier.color = "red") +
  labs(title = "Cena w zależności od stanu mieszkania", x = "Stan mieszkania", y = "Cena (PLN)") +
  theme_minimal()
ggplotly(p5)
  1. Średnie ceny mieszkań różnią się w zależności od ich stanu – mieszkania w lepszym stanie (premium) są droższe średnio o 170 000 złotych.

Wykres 6: Cena w zależności od piętra

p6 <- ggplot(data7, aes(x = as.factor(floor), y = price)) +
  geom_boxplot(fill = "lightblue", outlier.color = "red") +
  labs(title = "Cena w zależności od piętra", x = "Piętro", y = "Cena (PLN)") +
  theme_minimal()
ggplotly(p6)
  1. Ceny mieszkań znacząco różnią się w zależności od piętra, na którym się znajdują. Droższe mieszkania znajdują się na wyższych piętrach, co może wynikać z lepszego widoku oraz większej prywatności.
  2. Ceny mieszkań na piętrach od 1 do 10 utrzymują się na stosunkowo podobnym poziomie.

Wykres 7: Cena w zależności od liczby pięter w budynku

p7 <- ggplot(data7, aes(x = as.factor(floorCount), y = price)) +
  geom_boxplot(fill = "lightpink", outlier.color = "darkred") +
  labs(title = "Cena w zależności od liczby pięter w budynku", x = "Liczba pięter", y = "Cena (PLN)") +
  theme_minimal()
ggplotly(p7)
  1. Wysokość budynku ma wpływ na cenę mieszkań – w budynkach o większej liczbie pięter ceny mieszkań są wyższe.
  2. W budynkach o liczbie pięter od 1 do 10 ceny są bardziej zróżnicowane, co może wynikać z różnych standardów budownictwa.
  3. Możliwe jest także, że wyższe budynki znajdują się w bardziej prestiżowych lokalizacjach, co podnosi wartość mieszkań.

Wykres 8: Cena w zależności od roku budowy

p8 <- ggplot(data7, aes(x = buildYear, y = price)) +
  geom_point(alpha = 0.6, color = "darkgreen") +
  geom_smooth(method = "lm") +
  labs(title = "Cena w zależności od roku budowy", 
       x = "Rok budowy", 
       y = "Cena (PLN)") +
  theme_minimal()
ggplotly(p8)
  1. Widoczna jest tendencja wzrostu cen mieszkań w nowszych budynkach, co może wynikać z ich lepszego standardu.
  2. Mieszkania w starszych budynkach również potrafią mieć wysokie ceny, jeśli znajdują się w atrakcyjnej lokalizacji lub są po renowacjach.
  3. Mieszkania w najstarszych budynkach (wybudowanych przed 1900 rokiem) mają najniższe ceny, co może wynikać z niższego standardu lub konieczności przeprowadzenia remontu.

Analiza opisowa

Obliczenie statystyk opisowych dla ceny mieszkania w zależności od miast, liczby pokoi oraz typu budynku.

Tabela 1 - Rozkład cen w zależności od liczby pokoi

library(cardx)
data7 %>%
  select(price, rooms) %>%
  tbl_summary(
    by = rooms,  # Grupowanie wg liczby pokoi
    type = all_continuous() ~ "continuous2",  # Określenie typu zmiennej ciągłej
    statistic = all_continuous() ~ c(
      "{N_nonmiss}",  # Liczba niebrakujących wartości
      "{mean}",        # Średnia
      "{sd}",          # Odchylenie standardowe
      "{median} ({p25}, {p75})",  # Mediana i kwartyle
      "{min}, {max}"   # Minimalna i maksymalna wartość
    ),
    missing = "no",  # Brakujące dane ignorowane
    label = price ~ "Cena"  # Zmiana nazwy etykiety dla kolumny 'price'
  ) %>%
  modify_header(label ~ "**Zmienna**") %>%  # Nagłówek dla etykiety zmiennej
  modify_caption("**Tabela 1. Rozkład cen wg liczby pokoi**") %>%  # Nagłówek tabeli
  bold_labels() %>%  # Pogrubienie etykiet
  add_p(pvalue_fun = ~style_pvalue(.x, digits = 2)) 
Tabela 1. Rozkład cen wg liczby pokoi
Zmienna 1
N = 1,308
2
N = 9,310
3
N = 7,842
4
N = 2,404
5
N = 496
6
N = 141
p-value1
Cena





<0.001
    N Non-missing 1,308 9,310 7,842 2,404 496 141
    Mean 504,602 671,582 890,556 1,187,753 1,410,322 1,864,664
    SD 160,881 259,875 401,467 566,970 641,572 696,688
    Median (Q1, Q3) 517,000 (399,000, 599,500) 649,000 (499,000, 799,000) 799,000 (628,000, 1,070,000) 1,049,000 (759,000, 1,495,000) 1,249,000 (879,000, 1,950,000) 1,999,000 (1,249,000, 2,470,000)
    Min, Max 191,000, 970,000 195,000, 2,000,000 249,000, 3,000,000 299,000, 3,000,000 375,000, 2,999,000 550,000, 3,000,000
1 Kruskal-Wallis rank sum test

W przypadku rozkładu cen w zależności od liczby pokoi zauważyć można, że: ilość pokoi ma wpływ na cenę mieszkania. W przypadku mieszkania w którym znajduje się jeden pokój (1308 obserwacji), średnia cena mieszkania wynosiła 504tys.Odchylenie standardowe ceny mieściło się w granicy 161 tys.zł. Minimalna cena mieszkania to 191tys.zł., maksymalna 970tys.zł.

W przypadku mieszkania w którym znajdują się trzy pokoje, (7842 obserwacje) średnia cena mieszkania wynosiła 890tys., odchylenie standardowe ceny mieściło się w granicy 402 tys.zł. Minimalna cena mieszkania to 249 tys.zł., maksymalna 3 mln zł.

W przypadku mieszkań w którym znajduje się 6 pokoi (największa liczba pokoi), mieliśmy tylko 141 obserwacji. Średnia cena mieszkania wynosiła 1,864 mln., odchylenie standardowe ceny mieściło się w granicy 697 tys.zł. Minimalna cena mieszkania to 550 tys.zł., maksymalna 3mln zł.

Tabela 2 - Rozkład cen w zależności od miejscowości

data7 %>%
  select(price, city) %>%
  tbl_summary(
    by = city,  # Grupowanie wg miejscowości
    type = all_continuous() ~ "continuous2",  # Określenie typu zmiennej ciągłej
    statistic = all_continuous() ~ c(
      "{N_nonmiss}",  # Liczba niebrakujących wartości
      "{mean}",        # Średnia
      "{sd}",          # Odchylenie standardowe
      "{median} ({p25}, {p75})",  # Mediana i kwartyle
      "{min}, {max}"   # Minimalna i maksymalna wartość
    ),
    missing = "no",  # Brakujące dane ignorowane
    label = price ~ "Cena"  # Zmiana nazwy etykiety dla kolumny 'price'
  ) %>%
  modify_header(label ~ "**Zmienna**") %>%  # Nagłówek dla etykiety zmiennej
  modify_caption("**Tabela 2. Rozkład cen w zależności od miejscowości**") %>%  # Nagłówek tabeli
  bold_labels() %>%  # Pogrubienie etykiet
  add_p(pvalue_fun = ~style_pvalue(.x, digits = 2))
Tabela 2. Rozkład cen w zależności od miejscowości
Zmienna bialystok
N = 231
bydgoszcz
N = 937
czestochowa
N = 385
gdansk
N = 1,986
gdynia
N = 828
katowice
N = 593
krakow
N = 3,245
lodz
N = 1,691
lublin
N = 574
poznan
N = 793
radom
N = 195
rzeszow
N = 163
szczecin
N = 647
warszawa
N = 6,962
wroclaw
N = 2,271
p-value1
Cena














<0.001
    N Non-missing 231 937 385 1,986 828 593 3,245 1,691 574 793 195 163 647 6,962 2,271
    Mean 511,691 433,865 380,797 891,338 884,685 528,240 942,169 442,187 581,739 647,102 380,920 636,871 572,549 1,053,134 745,965
    SD 129,829 147,926 129,638 390,898 449,348 214,606 425,023 156,476 151,530 200,509 122,718 199,785 173,852 468,091 231,863
    Median (Q1, Q3) 498,900 (409,500, 599,000) 395,000 (329,000, 529,000) 355,000 (280,000, 450,000) 765,000 (629,000, 1,025,000) 720,000 (589,450, 1,045,000) 475,000 (379,000, 650,000) 805,000 (660,000, 1,080,000) 400,000 (330,000, 515,700) 554,700 (475,000, 660,000) 599,000 (510,000, 749,000) 350,000 (299,000, 433,000) 590,000 (498,000, 699,000) 540,000 (449,000, 660,000) 899,000 (735,000, 1,225,000) 695,000 (589,999, 849,000)
    Min, Max 299,000, 875,000 199,999, 949,000 195,000, 780,000 415,000, 2,499,000 409,000, 2,800,000 195,000, 1,315,000 399,000, 2,790,000 191,000, 986,000 335,000, 1,149,990 325,000, 1,395,000 198,000, 810,000 330,000, 1,250,000 309,000, 1,200,000 499,000, 3,000,000 399,000, 1,600,000
1 Kruskal-Wallis rank sum test

W przypadku rozkładu cen w zależności od miejscowości warto zauważyć, że: średnie ceny mieszkań mniejsze niż 400tys zł znajdują się w Białymstoku, Częstochowie, Rzeszowie oraz Radomiu.

Najwyższe średnie mieszkań są w Warszawie, następnie Krakowie oraz Gdańsku i Gdyni.

Odchylenie standardowe cen mieszkań najwyższe jest w Gdyni, Krakowie oraz Warszawie.

Najniższe ceny minimalne mieszkań są w Białymstoku, Częstochowie, Katowicach, Łodzi oraz Radomiu. W przypadku cen maksymalnych najwyższe ceny są w Warszawie (3mln zł), Gdyni (2,8mln zł),Krakowie (2,79 mln zł) oraz Gdańsku (2,499 mln zł).

Największa ilość ofert mieszkań znajduje się w Warszawie (6962) oraz Krakowie (3245), natomiast najmniejsza ilość ofert mieszkań znajduje się w Radomiu oraz Rzeszowie (poniżej 200) oraz Białymstoku (231).

Tabela 3 - Rozkład cen w zależności od typu mieszkania

data7 %>%
  select(price, type) %>%
  tbl_summary(
    by = type,  # Grupowanie wg miejscowości
    type = all_continuous() ~ "continuous2",  # Określenie typu zmiennej ciągłej
    statistic = all_continuous() ~ c(
      "{N_nonmiss}",  # Liczba niebrakujących wartości
      "{mean}",        # Średnia
      "{sd}",          # Odchylenie standardowe
      "{median} ({p25}, {p75})",  # Mediana i kwartyle
      "{min}, {max}"   # Minimalna i maksymalna wartość
    ),
    missing = "no",  # Brakujące dane ignorowane
    label = price ~ "Cena"  # Zmiana nazwy etykiety dla kolumny 'price'
  ) %>%
  modify_header(label ~ "**Zmienna**") %>%  # Nagłówek dla etykiety zmiennej
  modify_caption("**Tabela 3. Rozkład cen w zależności od typu **") %>%  # Nagłówek tabeli
  bold_labels() %>%  # Pogrubienie etykiet
  add_p(pvalue_fun = ~style_pvalue(.x, digits = 2))  
**Tabela 3. Rozkład cen w zależności od typu **
Zmienna apartmentBuilding
N = 3,648
blockOfFlats
N = 14,549
tenement
N = 3,304
p-value1
Cena


<0.001
    N Non-missing 3,648 14,549 3,304
    Mean 1,103,844 738,029 892,729
    SD 512,168 339,271 538,039
    Median (Q1, Q3) 979,000 (736,175, 1,330,000) 678,000 (527,000, 860,000) 745,000 (524,500, 1,100,000)
    Min, Max 230,000, 3,000,000 191,000, 3,000,000 194,000, 3,000,000
1 Kruskal-Wallis rank sum test

W zależności od typu mieszkania ceny maksymalne oraz minimalne kształtują się na zbliżonym poziomie: minimalne ok. 200tys zł, maksymalne 3mln zł.

W przypadku kamienic średnia cena mieszkań kształtuje się na poziomie ok 900tys zł. Odchylenie standardowe tej ceny to 538tys zł. Ilość mieszkań do zakupu to 3304.

W przypadku mieszkań w bloku średnia cena mieszkań wynosi 738tys zł. Odchylenie standardowe wynosi 339tys zł. Najwięskza ilość dostępych mieszkań do zakupu (ponad 14,5 tys.).

W przypadku apartamentów średnia cena mieszkań wynosi 1,1mln zł. Odchylenie rozkładu tej ceny to ponad 512 tys zł. Ilość oferty wynosi 3648.

Wnioskowanie statystyczne

Sprawdzenie czy średnie ceny różnią się między miastami (test ANOVA)

anova_model <-aov(price ~ city, data = data7)
summary(anova_model)
##                Df    Sum Sq   Mean Sq F value Pr(>F)    
## city           14 1.119e+15 7.995e+13   597.1 <2e-16 ***
## Residuals   21486 2.877e+15 1.339e+11                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
if(summary(anova_model)[[1]]$`Pr(>F)`[1]<0.05) {
  tukey_result <- TukeyHSD(anova_model)
  print(tukey_result)}
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = price ~ city, data = data7)
## 
## $city
##                               diff         lwr         upr     p adj
## bydgoszcz-bialystok    -77825.6667 -168993.336   13342.003 0.1983009
## czestochowa-bialystok -130893.8615 -234181.707  -27606.016 0.0016321
## gdansk-bialystok       379647.3275  293372.827  465921.828 0.0000000
## gdynia-bialystok       372993.4769  280646.637  465340.317 0.0000000
## katowice-bialystok      16548.4223  -79707.063  112803.907 0.9999996
## krakow-bialystok       430477.6482  345964.990  514990.306 0.0000000
## lodz-bialystok         -69504.1401 -156559.219   17550.939 0.2998269
## lublin-bialystok        70047.7003  -26653.357  166748.757 0.4721004
## poznan-bialystok       135411.0461   42620.739  228201.353 0.0000757
## radom-bialystok       -130770.6829 -251462.193  -10079.173 0.0192828
## rzeszow-bialystok      125179.6572   -1773.509  252132.823 0.0579823
## szczecin-bialystok      60857.8055  -34264.933  155980.544 0.6866967
## warszawa-bialystok     541443.0406  458443.202  624442.879 0.0000000
## wroclaw-bialystok      234274.1754  148565.593  319982.758 0.0000000
## czestochowa-bydgoszcz  -53068.1947 -128197.744   22061.355 0.5179694
## gdansk-bydgoszcz       457472.9943  408286.009  506659.980 0.0000000
## gdynia-bydgoszcz       450819.1437  391624.473  510013.814 0.0000000
## katowice-bydgoszcz      94374.0890   29249.681  159498.497 0.0000902
## krakow-bydgoszcz       508303.3150  462276.589  554330.041 0.0000000
## lodz-bydgoszcz           8321.5266  -42222.088   58865.141 0.9999998
## lublin-bydgoszcz       147873.3670   82092.180  213654.554 0.0000000
## poznan-bydgoszcz       213236.7129  153352.564  273120.862 0.0000000
## radom-bydgoszcz        -52945.0162 -150630.792   44740.760 0.8826678
## rzeszow-bydgoszcz      203005.3240   97681.174  308329.474 0.0000000
## szczecin-bydgoszcz     138683.4723   75245.270  202121.675 0.0000000
## warszawa-bydgoszcz     619268.7074  576082.559  662454.855 0.0000000
## wroclaw-bydgoszcz      312099.8421  263912.382  360287.302 0.0000000
## gdansk-czestochowa     510541.1890  441431.171  579651.207 0.0000000
## gdynia-czestochowa     503887.3384  427331.188  580443.488 0.0000000
## katowice-czestochowa   147442.2838   66214.064  228670.503 0.0000000
## krakow-czestochowa     561371.5097  494473.867  628269.152 0.0000000
## lodz-czestochowa        61389.7214   -8692.317  131471.760 0.1649326
## lublin-czestochowa     200941.5618  119185.830  282697.294 0.0000000
## poznan-czestochowa     266304.9076  189214.400  343395.415 0.0000000
## radom-czestochowa         123.1786 -108960.944  109207.301 1.0000000
## rzeszow-czestochowa    256073.5187  140099.333  372047.704 0.0000000
## szczecin-czestochowa   191751.6670  111868.999  271634.335 0.0000000
## warszawa-czestochowa   672336.9021  607360.918  737312.886 0.0000000
## wroclaw-czestochowa    365168.0368  296765.797  433570.276 0.0000000
## gdynia-gdansk           -6653.8506  -57993.450   44685.749 1.0000000
## katowice-gdansk       -363098.9052 -421175.871 -305021.939 0.0000000
## krakow-gdansk           50830.3207   15472.083   86188.558 0.0001098
## lodz-gdansk           -449151.4676 -490217.298 -408085.637 0.0000000
## lublin-gdansk         -309599.6272 -368412.126 -250787.128 0.0000000
## poznan-gdansk         -244236.2814 -296369.348 -192103.214 0.0000000
## radom-gdansk          -510418.0105 -603553.698 -417282.323 0.0000000
## rzeszow-gdansk        -254467.6703 -355586.027 -153349.314 0.0000000
## szczecin-gdansk       -318789.5220 -374969.153 -262609.891 0.0000000
## warszawa-gdansk        161795.7131  130223.751  193367.675 0.0000000
## wroclaw-gdansk        -145373.1522 -183501.576 -107244.728 0.0000000
## katowice-gdynia       -356445.0546 -423210.191 -289679.918 0.0000000
## krakow-gdynia           57484.1713    9163.840  105804.503 0.0049145
## lodz-gdynia           -442497.6170 -495138.399 -389856.835 0.0000000
## lublin-gdynia         -302945.7766 -370351.707 -235539.846 0.0000000
## poznan-gdynia         -237582.4308 -299246.895 -175917.966 0.0000000
## radom-gdynia          -503764.1598 -602551.334 -404976.986 0.0000000
## rzeszow-gdynia        -247813.8197 -354160.289 -141467.351 0.0000000
## szczecin-gdynia       -312135.6714 -377257.100 -247014.243 0.0000000
## warszawa-gdynia        168449.5637  122826.781  214072.346 0.0000000
## wroclaw-gdynia        -138719.3016 -189102.098  -88336.505 0.0000000
## krakow-katowice        413929.2259  358503.294  469355.158 0.0000000
## lodz-katowice          -86052.5624 -145282.888  -26822.237 0.0000846
## lublin-katowice         53499.2780  -19169.416  126167.972 0.4425141
## poznan-katowice        118862.6238   51485.434  186239.814 0.0000001
## radom-katowice        -147319.1052 -249769.509  -44868.701 0.0001091
## rzeszow-katowice       108631.2349   -1126.457  218388.927 0.0557659
## szczecin-katowice       44309.3832  -26245.418  114864.185 0.7147829
## warszawa-katowice      524894.6183  471803.962  577985.275 0.0000000
## wroclaw-katowice       217725.7531  160492.845  274958.661 0.0000000
## lodz-krakow           -499981.7883 -537204.126 -462759.451 0.0000000
## lublin-krakow         -360429.9479 -416626.122 -304233.774 0.0000000
## poznan-krakow         -295066.6021 -344229.155 -245904.049 0.0000000
## radom-krakow          -561248.3312 -652754.376 -469742.287 0.0000000
## rzeszow-krakow        -305297.9910 -404917.376 -205678.606 0.0000000
## szczecin-krakow       -369619.8427 -423054.391 -316185.294 0.0000000
## warszawa-krakow        110965.3924   84585.689  137345.096 0.0000000
## wroclaw-krakow        -196203.4729 -230157.511 -162249.435 0.0000000
## lublin-lodz            139551.8404   79600.131  199503.550 0.0000000
## poznan-lodz            204915.1862  151500.262  258330.110 0.0000000
## radom-lodz             -61266.5428 -155125.765   32592.680 0.6548315
## rzeszow-lodz           194683.7973   92898.634  296468.960 0.0000000
## szczecin-lodz          130361.9456   72990.799  187733.092 0.0000000
## warszawa-lodz          610947.1807  577300.691  644593.670 0.0000000
## wroclaw-lodz           303778.3155  263915.122  343641.508 0.0000000
## poznan-lublin           65363.3458   -2648.872  133375.563 0.0749307
## radom-lublin          -200818.3832 -303687.530  -97949.237 0.0000000
## rzeszow-lublin          55131.9569  -55016.702  165280.616 0.9343143
## szczecin-lublin         -9189.8948  -80351.373   61971.584 1.0000000
## warszawa-lublin        471395.3403  417501.056  525289.624 0.0000000
## wroclaw-lublin         164226.4751  106247.326  222205.624 0.0000000
## radom-poznan          -266181.7290 -365383.583 -166979.875 0.0000000
## rzeszow-poznan         -10231.3889 -116963.173   96500.395 1.0000000
## szczecin-poznan        -74553.2406 -140302.025   -8804.456 0.0102881
## warszawa-poznan        406031.9945  359518.120  452545.869 0.0000000
## wroclaw-poznan          98863.1292   47672.032  150054.226 0.0000000
## rzeszow-radom          255950.3401  124238.256  387662.425 0.0000000
## szczecin-radom         191628.4884   90241.595  293015.382 0.0000000
## warszawa-radom         672213.7235  582103.014  762324.433 0.0000000
## wroclaw-radom          365044.8583  272433.153  457656.564 0.0000000
## szczecin-rzeszow       -64321.8517 -173087.508   44443.805 0.7953892
## warszawa-rzeszow       416263.3834  317924.145  514602.622 0.0000000
## wroclaw-rzeszow        109094.5181    8458.572  209730.465 0.0191575
## warszawa-szczecin      480585.2351  429577.051  531593.419 0.0000000
## wroclaw-szczecin       173416.3698  118109.745  228722.994 0.0000000
## wroclaw-warszawa      -307168.8653 -337159.873 -277177.858 0.0000000

W testach Tukeya większość dużych miast (Warszawa, Kraków, Gdańsk, Wrocław, Poznań) wykazuje istotnie wyższe ceny niż mniejsze ośrodki (Białystok, Częstochowa, Radom, Łódź). Największe różnice cenowe występują między Warszawą a mniejszymi miastami, takimi jak Białystok i Częstochowa.

Przeprowadzenie testu ANOVA, aby sprawdzić, czy średnie ceny różnią się między typami mieszkań

anova_type <- aov(price ~ type, data = data7)
summary(anova_type)
##                Df    Sum Sq   Mean Sq F value Pr(>F)    
## type            2 4.088e+14 2.044e+14    1225 <2e-16 ***
## Residuals   21498 3.587e+15 1.669e+11                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Istnieją istotne różnice w cenach mieszkań.

Przeprowadzenie testu Tukeya w celu określenia, które pary typów mieszkań mają istotne różnice w cenach.

tukey_result <- TukeyHSD(anova_model)
print(tukey_result)
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = price ~ city, data = data7)
## 
## $city
##                               diff         lwr         upr     p adj
## bydgoszcz-bialystok    -77825.6667 -168993.336   13342.003 0.1983009
## czestochowa-bialystok -130893.8615 -234181.707  -27606.016 0.0016321
## gdansk-bialystok       379647.3275  293372.827  465921.828 0.0000000
## gdynia-bialystok       372993.4769  280646.637  465340.317 0.0000000
## katowice-bialystok      16548.4223  -79707.063  112803.907 0.9999996
## krakow-bialystok       430477.6482  345964.990  514990.306 0.0000000
## lodz-bialystok         -69504.1401 -156559.219   17550.939 0.2998269
## lublin-bialystok        70047.7003  -26653.357  166748.757 0.4721004
## poznan-bialystok       135411.0461   42620.739  228201.353 0.0000757
## radom-bialystok       -130770.6829 -251462.193  -10079.173 0.0192828
## rzeszow-bialystok      125179.6572   -1773.509  252132.823 0.0579823
## szczecin-bialystok      60857.8055  -34264.933  155980.544 0.6866967
## warszawa-bialystok     541443.0406  458443.202  624442.879 0.0000000
## wroclaw-bialystok      234274.1754  148565.593  319982.758 0.0000000
## czestochowa-bydgoszcz  -53068.1947 -128197.744   22061.355 0.5179694
## gdansk-bydgoszcz       457472.9943  408286.009  506659.980 0.0000000
## gdynia-bydgoszcz       450819.1437  391624.473  510013.814 0.0000000
## katowice-bydgoszcz      94374.0890   29249.681  159498.497 0.0000902
## krakow-bydgoszcz       508303.3150  462276.589  554330.041 0.0000000
## lodz-bydgoszcz           8321.5266  -42222.088   58865.141 0.9999998
## lublin-bydgoszcz       147873.3670   82092.180  213654.554 0.0000000
## poznan-bydgoszcz       213236.7129  153352.564  273120.862 0.0000000
## radom-bydgoszcz        -52945.0162 -150630.792   44740.760 0.8826678
## rzeszow-bydgoszcz      203005.3240   97681.174  308329.474 0.0000000
## szczecin-bydgoszcz     138683.4723   75245.270  202121.675 0.0000000
## warszawa-bydgoszcz     619268.7074  576082.559  662454.855 0.0000000
## wroclaw-bydgoszcz      312099.8421  263912.382  360287.302 0.0000000
## gdansk-czestochowa     510541.1890  441431.171  579651.207 0.0000000
## gdynia-czestochowa     503887.3384  427331.188  580443.488 0.0000000
## katowice-czestochowa   147442.2838   66214.064  228670.503 0.0000000
## krakow-czestochowa     561371.5097  494473.867  628269.152 0.0000000
## lodz-czestochowa        61389.7214   -8692.317  131471.760 0.1649326
## lublin-czestochowa     200941.5618  119185.830  282697.294 0.0000000
## poznan-czestochowa     266304.9076  189214.400  343395.415 0.0000000
## radom-czestochowa         123.1786 -108960.944  109207.301 1.0000000
## rzeszow-czestochowa    256073.5187  140099.333  372047.704 0.0000000
## szczecin-czestochowa   191751.6670  111868.999  271634.335 0.0000000
## warszawa-czestochowa   672336.9021  607360.918  737312.886 0.0000000
## wroclaw-czestochowa    365168.0368  296765.797  433570.276 0.0000000
## gdynia-gdansk           -6653.8506  -57993.450   44685.749 1.0000000
## katowice-gdansk       -363098.9052 -421175.871 -305021.939 0.0000000
## krakow-gdansk           50830.3207   15472.083   86188.558 0.0001098
## lodz-gdansk           -449151.4676 -490217.298 -408085.637 0.0000000
## lublin-gdansk         -309599.6272 -368412.126 -250787.128 0.0000000
## poznan-gdansk         -244236.2814 -296369.348 -192103.214 0.0000000
## radom-gdansk          -510418.0105 -603553.698 -417282.323 0.0000000
## rzeszow-gdansk        -254467.6703 -355586.027 -153349.314 0.0000000
## szczecin-gdansk       -318789.5220 -374969.153 -262609.891 0.0000000
## warszawa-gdansk        161795.7131  130223.751  193367.675 0.0000000
## wroclaw-gdansk        -145373.1522 -183501.576 -107244.728 0.0000000
## katowice-gdynia       -356445.0546 -423210.191 -289679.918 0.0000000
## krakow-gdynia           57484.1713    9163.840  105804.503 0.0049145
## lodz-gdynia           -442497.6170 -495138.399 -389856.835 0.0000000
## lublin-gdynia         -302945.7766 -370351.707 -235539.846 0.0000000
## poznan-gdynia         -237582.4308 -299246.895 -175917.966 0.0000000
## radom-gdynia          -503764.1598 -602551.334 -404976.986 0.0000000
## rzeszow-gdynia        -247813.8197 -354160.289 -141467.351 0.0000000
## szczecin-gdynia       -312135.6714 -377257.100 -247014.243 0.0000000
## warszawa-gdynia        168449.5637  122826.781  214072.346 0.0000000
## wroclaw-gdynia        -138719.3016 -189102.098  -88336.505 0.0000000
## krakow-katowice        413929.2259  358503.294  469355.158 0.0000000
## lodz-katowice          -86052.5624 -145282.888  -26822.237 0.0000846
## lublin-katowice         53499.2780  -19169.416  126167.972 0.4425141
## poznan-katowice        118862.6238   51485.434  186239.814 0.0000001
## radom-katowice        -147319.1052 -249769.509  -44868.701 0.0001091
## rzeszow-katowice       108631.2349   -1126.457  218388.927 0.0557659
## szczecin-katowice       44309.3832  -26245.418  114864.185 0.7147829
## warszawa-katowice      524894.6183  471803.962  577985.275 0.0000000
## wroclaw-katowice       217725.7531  160492.845  274958.661 0.0000000
## lodz-krakow           -499981.7883 -537204.126 -462759.451 0.0000000
## lublin-krakow         -360429.9479 -416626.122 -304233.774 0.0000000
## poznan-krakow         -295066.6021 -344229.155 -245904.049 0.0000000
## radom-krakow          -561248.3312 -652754.376 -469742.287 0.0000000
## rzeszow-krakow        -305297.9910 -404917.376 -205678.606 0.0000000
## szczecin-krakow       -369619.8427 -423054.391 -316185.294 0.0000000
## warszawa-krakow        110965.3924   84585.689  137345.096 0.0000000
## wroclaw-krakow        -196203.4729 -230157.511 -162249.435 0.0000000
## lublin-lodz            139551.8404   79600.131  199503.550 0.0000000
## poznan-lodz            204915.1862  151500.262  258330.110 0.0000000
## radom-lodz             -61266.5428 -155125.765   32592.680 0.6548315
## rzeszow-lodz           194683.7973   92898.634  296468.960 0.0000000
## szczecin-lodz          130361.9456   72990.799  187733.092 0.0000000
## warszawa-lodz          610947.1807  577300.691  644593.670 0.0000000
## wroclaw-lodz           303778.3155  263915.122  343641.508 0.0000000
## poznan-lublin           65363.3458   -2648.872  133375.563 0.0749307
## radom-lublin          -200818.3832 -303687.530  -97949.237 0.0000000
## rzeszow-lublin          55131.9569  -55016.702  165280.616 0.9343143
## szczecin-lublin         -9189.8948  -80351.373   61971.584 1.0000000
## warszawa-lublin        471395.3403  417501.056  525289.624 0.0000000
## wroclaw-lublin         164226.4751  106247.326  222205.624 0.0000000
## radom-poznan          -266181.7290 -365383.583 -166979.875 0.0000000
## rzeszow-poznan         -10231.3889 -116963.173   96500.395 1.0000000
## szczecin-poznan        -74553.2406 -140302.025   -8804.456 0.0102881
## warszawa-poznan        406031.9945  359518.120  452545.869 0.0000000
## wroclaw-poznan          98863.1292   47672.032  150054.226 0.0000000
## rzeszow-radom          255950.3401  124238.256  387662.425 0.0000000
## szczecin-radom         191628.4884   90241.595  293015.382 0.0000000
## warszawa-radom         672213.7235  582103.014  762324.433 0.0000000
## wroclaw-radom          365044.8583  272433.153  457656.564 0.0000000
## szczecin-rzeszow       -64321.8517 -173087.508   44443.805 0.7953892
## warszawa-rzeszow       416263.3834  317924.145  514602.622 0.0000000
## wroclaw-rzeszow        109094.5181    8458.572  209730.465 0.0191575
## warszawa-szczecin      480585.2351  429577.051  531593.419 0.0000000
## wroclaw-szczecin       173416.3698  118109.745  228722.994 0.0000000
## wroclaw-warszawa      -307168.8653 -337159.873 -277177.858 0.0000000

Test Tukeya potwierdza głębokie zróżnicowanie cen mieszkań w Polsce. Najwyższe ceny występują w dużych aglomeracjach, podczas gdy mniejsze miasta pozostają znacznie tańsze. Miasta o najwyższych cenach mieszkań: Warszawa, Kraków, Gdańsk, Wrocław i Poznań mają istotnie wyższe ceny mieszkań w porównaniu z większością innych miast (np. różnice sięgające nawet 500 000 PLN). Przykład: warszawa-bialystok: różnica +541 443 PLN (p < 0.0001). krakow-bialystok: różnica +430 477 PLN (p < 0.0001).

Przeprowadzenie testu ANOVA, aby sprawdzić, czy średnie ceny różnią się między typami mieszkań

anova_type <- aov(price ~ type, data = data7)
summary(anova_type)
##                Df    Sum Sq   Mean Sq F value Pr(>F)    
## type            2 4.088e+14 2.044e+14    1225 <2e-16 ***
## Residuals   21498 3.587e+15 1.669e+11                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
if (summary(anova_type)[[1]]$`Pr(>F)`[1] < 0.05) {
  tukey_type <- TukeyHSD(anova_type)
  print(tukey_type)
}
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = price ~ type, data = data7)
## 
## $type
##                                     diff       lwr       upr p adj
## blockOfFlats-apartmentBuilding -365815.5 -383544.2 -348086.7     0
## tenement-apartmentBuilding     -211114.9 -234109.7 -188120.1     0
## tenement-blockOfFlats           154700.6  136248.7  173152.5     0

Apartamentowce wymagają większego kapitału, bloki mieszkalne są bardziej przystępne cenowo, a kamienice stanowią pośrednią opcję. Porównanie: blok mieszkalny vs apartamentowiec: Bloki mieszkalne są średnio o 365 815 zł tańsze niż apartamentowce. Porównanie: kamienica vs apartamentowiec: Kamienice są średnio o 211 115 zł tańsze niż apartamentowce. Porównanie: kamienica vs blok mieszkalny: Kamienice są średnio o 154 701 zł droższe niż bloki mieszkalne.

Korelacja między ceną a odległością od uczelni

cor_test_college <- cor.test(data7$price, data7$collegeDistance, method = "pearson")
print(cor_test_college)
## 
##  Pearson's product-moment correlation
## 
## data:  data7$price and data7$collegeDistance
## t = -4.8757, df = 21499, p-value = 1.092e-06
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  -0.04658010 -0.01987628
## sample estimates:
##         cor 
## -0.03323412

Bliskość uczelni nie jest istotnym czynnikiem kształtującym ceny mieszkań.

Korelacja między ceną a odległością od centrum

cor_test_centre <- cor.test(data7$price, data7$centreDistance, method = "pearson")
print(cor_test_centre)
## 
##  Pearson's product-moment correlation
## 
## data:  data7$price and data7$centreDistance
## t = 10.144, df = 21499, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.05570257 0.08230859
## sample estimates:
##        cor 
## 0.06901786

Odległość od centrum ma bardzo niewielki wpływ na ceny mieszkań.

Korelacja między ceną a rokiem budowy

cor_test_buildYear <- cor.test(data7$price, data7$buildYear, method = "pearson")
print(cor_test_buildYear)
## 
##  Pearson's product-moment correlation
## 
## data:  data7$price and data7$buildYear
## t = 20.184, df = 21499, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.1232274 0.1494637
## sample estimates:
##       cor 
## 0.1363695

Nowsze budynki mają tendencję do wyższych cen.

Przeprowadzenie testu ANOVA, aby sprawdzić, czy średnie ceny różnią się między stanami mieszkań

anova_condition <- aov(price ~ condition, data = data7)
summary(anova_condition)
##                Df    Sum Sq   Mean Sq F value Pr(>F)    
## condition       2 6.846e+13 3.423e+13   187.3 <2e-16 ***
## Residuals   21498 3.928e+15 1.827e+11                   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Stan mieszkania ma znaczący wpływ na cenę.

if (summary(anova_condition)[[1]]$`Pr(>F)`[1] < 0.05) {
  tukey_condition <- TukeyHSD(anova_condition)
  print(tukey_condition)
}
##   Tukey multiple comparisons of means
##     95% family-wise confidence level
## 
## Fit: aov(formula = price ~ condition, data = data7)
## 
## $condition
##                       diff       lwr       upr p adj
## premium-low      219038.02  192141.6 245934.38     0
## Standard-low     138943.09  117698.6 160187.57     0
## Standard-premium -80094.93 -100049.2 -60140.64     0
ggplot(data7, aes(x = condition, y = price, fill = condition)) +
  geom_boxplot(outlier.color = "red") +
  labs(title = "Średnie ceny mieszkań w zależności od stanu", x = "Stan mieszkania", y = "Cena (PLN)") +
  theme_minimal()

Średnie ceny mieszkań znacząco różnią się w zależności od stanu mieszkania: Mieszkania w stanie premium mają najwyższe średnie ceny. Mieszkania w stanie Standard są droższe niż w stanie low, ale tańsze niż premium. Stan low wiąże się z najniższymi średnimi cenami mieszkań.

Tworzenie tabeli kontyngencji dla miasta i typu mieszkania

contingency_table <- table(data7$city, data7$type)

Przeprowadzenie testu Chi-kwadrat

chi_square_result <- chisq.test(contingency_table)
print(chi_square_result)
## 
##  Pearson's Chi-squared test
## 
## data:  contingency_table
## X-squared = 968.1, df = 28, p-value < 2.2e-16
print(chi_square_result$expected)
##              
##               apartmentBuilding blockOfFlats   tenement
##   bialystok            39.19297     156.3099   35.49714
##   bydgoszcz           158.97754     634.0362  143.98623
##   czestochowa          65.32161     260.5165   59.16190
##   gdansk              336.95772    1343.8591  305.18320
##   gdynia              140.48388     560.2796  127.23650
##   katowice            100.61225     401.2631   91.12469
##   krakow              550.56788    2195.7818  498.65030
##   lodz                286.90610    1144.2425  259.85136
##   lublin               97.38859     388.4064   88.20501
##   poznan              134.54556     536.5963  121.85815
##   radom                33.08497     131.9499   29.96512
##   rzeszow              27.65564     110.2966   25.04777
##   szczecin            109.77424     437.8030   99.42272
##   warszawa           1181.21836    4710.9501 1069.83154
##   wroclaw             385.31268    1536.7089  348.97837
mosaicplot(contingency_table, main = "Mozaikowy wykres zależności", color = TRUE, las = 3)

Przeprowadzenie testu t-Studenta, aby porównać ceny mieszkań z windą i bez windy

t_test_elevator <- t.test(price ~ hasElevator, data = data7)
print(t_test_elevator)
## 
##  Welch Two Sample t-test
## 
## data:  price by hasElevator
## t = -30.846, df = 21196, p-value < 2.2e-16
## alternative hypothesis: true difference in means between group no and group yes is not equal to 0
## 95 percent confidence interval:
##  -188245.8 -165751.4
## sample estimates:
##  mean in group no mean in group yes 
##          733594.6          910593.2

Wyniki testu wskazują, że obecność windy ma istotny wpływ na cenę mieszkań. Mieszkania z windą są średnio droższe od mieszkań bez windy o około 177 000 PLN. Może to wynikać z faktu, że winda jest istotnym udogodnieniem, szczególnie w budynkach wielopiętrowych. Wpływa na postrzeganą wartość nieruchomości.

ggplot(data7, aes(x = hasElevator, y = price, fill = hasElevator)) +
  geom_boxplot(outlier.color = "red") +
  labs(title = "Porównanie cen mieszkań z windą i bez windy",
       x = "Czy mieszkanie ma windę?",
       y = "Cena (PLN)") +
  theme_minimal()

Test Kruskala-Wallisa do porównania cen między miastami

kruskal_result <- kruskal.test(price ~ city, data = data7)
print(kruskal_result)
## 
##  Kruskal-Wallis rank sum test
## 
## data:  price by city
## Kruskal-Wallis chi-squared = 9367.1, df = 14, p-value < 2.2e-16

Wyniki testu Kruskala-Wallisa wskazują, że istnieją statystycznie istotne różnice w rozkładach cen mieszkań między miastami.

pairwise.wilcox.test(data7$price, data7$city, p.adjust.method = "bonferroni")
## 
##  Pairwise comparisons using Wilcoxon rank sum test with continuity correction 
## 
## data:  data7$price and data7$city 
## 
##             bialystok bydgoszcz czestochowa gdansk  gdynia  katowice krakow 
## bydgoszcz   2.9e-14   -         -           -       -       -        -      
## czestochowa < 2e-16   2.0e-08   -           -       -       -        -      
## gdansk      < 2e-16   < 2e-16   < 2e-16     -       -       -        -      
## gdynia      < 2e-16   < 2e-16   < 2e-16     0.17985 -       -        -      
## katowice    1.00000   6.8e-16   < 2e-16     < 2e-16 < 2e-16 -        -      
## krakow      < 2e-16   < 2e-16   < 2e-16     7.1e-06 2.8e-10 < 2e-16  -      
## lodz        2.0e-14   1.00000   3.4e-12     < 2e-16 < 2e-16 < 2e-16  < 2e-16
## lublin      1.6e-07   < 2e-16   < 2e-16     < 2e-16 < 2e-16 2.5e-11  < 2e-16
## poznan      < 2e-16   < 2e-16   < 2e-16     < 2e-16 < 2e-16 < 2e-16  < 2e-16
## radom       < 2e-16   0.00023   1.00000     < 2e-16 < 2e-16 < 2e-16  < 2e-16
## rzeszow     3.7e-09   < 2e-16   < 2e-16     < 2e-16 1.4e-12 8.1e-10  < 2e-16
## szczecin    0.00119   < 2e-16   < 2e-16     < 2e-16 < 2e-16 7.8e-07  < 2e-16
## warszawa    < 2e-16   < 2e-16   < 2e-16     < 2e-16 < 2e-16 < 2e-16  < 2e-16
## wroclaw     < 2e-16   < 2e-16   < 2e-16     < 2e-16 0.00048 < 2e-16  < 2e-16
##             lodz    lublin  poznan  radom   rzeszow szczecin warszawa
## bydgoszcz   -       -       -       -       -       -        -       
## czestochowa -       -       -       -       -       -        -       
## gdansk      -       -       -       -       -       -        -       
## gdynia      -       -       -       -       -       -        -       
## katowice    -       -       -       -       -       -        -       
## krakow      -       -       -       -       -       -        -       
## lodz        -       -       -       -       -       -        -       
## lublin      < 2e-16 -       -       -       -       -        -       
## poznan      < 2e-16 5.1e-07 -       -       -       -        -       
## radom       2.3e-06 < 2e-16 < 2e-16 -       -       -        -       
## rzeszow     < 2e-16 0.65692 1.00000 < 2e-16 -       -        -       
## szczecin    < 2e-16 1.00000 5.5e-12 < 2e-16 0.00955 -        -       
## warszawa    < 2e-16 < 2e-16 < 2e-16 < 2e-16 < 2e-16 < 2e-16  -       
## wroclaw     < 2e-16 < 2e-16 < 2e-16 < 2e-16 1.1e-09 < 2e-16  < 2e-16 
## 
## P value adjustment method: bonferroni

Większość miast różni się istotnie pod względem median cen mieszkań, co wskazuje na zróżnicowany rynek nieruchomości w zależności od lokalizacji.

ggplot(data7, aes(x = city, y = price, fill = city)) +
  geom_boxplot(outlier.color = "blue") +
  labs(title = "Porównanie cen mieszkań w różnych miastach",
       x = "Miasto",
       y = "Cena (PLN)") + theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Wykorzystanie pakietu ggstatsplot

library(ggstatsplot)
library(dplyr)
top_cities <- data7 %>%
  group_by(city) %>%
  summarise(mean_price = mean(price)) %>%
  arrange(desc(mean_price)) %>%
  slice(1:5) 

filtered_data <- data7 %>%
  filter(city %in% top_cities$city)

ggbetweenstats(
  data = filtered_data,
  x = city,
  y = price,
  type = "parametric",
  pairwise.comparisons = TRUE,
  pairwise.display = "significant", 
  mean.plotting = FALSE,           
  p.adjust.method = "bonferroni",
  ggtheme = ggplot2::theme_minimal(),
  title = "Porównanie cen mieszkań w wybranych miastach"
) +
  theme(axis.text.x = element_text(angle = 45, hjust = 1)) +
  scale_fill_brewer(palette = "Set2")

Dodanie testów zgodności rozkładu

library(nortest)
lillie.test(data7$price) 
## 
##  Lilliefors (Kolmogorov-Smirnov) normality test
## 
## data:  data7$price
## D = 0.14225, p-value < 2.2e-16

Analiza wielowymiarowa – rozszerzenie modelu regresji

lm_interaction <- lm(price ~ rooms * buildYear, data = data7)
summary(lm_interaction)
## 
## Call:
## lm(formula = price ~ rooms * buildYear, data = data7)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1025717  -237935   -55132   153937  2196056 
## 
## Coefficients:
##                   Estimate Std. Error t value Pr(>|t|)    
## (Intercept)     -2.094e+06  4.398e+05  -4.762 1.93e-06 ***
## rooms           -2.341e+05  1.520e+05  -1.540  0.12357    
## buildYear        1.149e+03  2.218e+02   5.180 2.24e-07 ***
## rooms:buildYear  2.403e+02  7.669e+01   3.134  0.00173 ** 
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 368300 on 21497 degrees of freedom
## Multiple R-squared:  0.2705, Adjusted R-squared:  0.2704 
## F-statistic:  2657 on 3 and 21497 DF,  p-value: < 2.2e-16
plot(lm_interaction)

Przykłady rozszerzonych analiz i wizualizacji

Porównanie odległości od uczelni i od centrum w kontekście cen mieszkań

ggscatterstats(
  data = data7,
  x = collegeDistance,
  y = price,
  title = "Korelacja między ceną a odległością od uczelni",
  xlab = "Odległość od uczelni (km)",
  ylab = "Cena (PLN)")

Podsumowanie i wnioski

Analiza cen mieszkań w Polsce ukazuje, że ich ceny są bardzo zróżnicowane. Największy wpływ na wartość nieruchomości mają lokalizacja, jej standard oraz liczba pokoi. Najwyższe ceny występują w dużych polskich miastach. Mieszkania w nowym budownictwie i na wyższych piętrach są droższe, co zazwyczaj wynika z lepszego standardu (premium), lepszych widoków czy większej prywatności. Na cenę mieszkań istotny wpływ ma także obecność windy, która jest szczególnie istotnym udogodnieniem w wysokich budynkach.W mniejszych miastach ceny są niższe, ale oferta jest bardziej ograniczona. Rok budowy oraz stan techniczny również wpływają na wartość nieruchomości, często w sposób negatywny. Większość cen nieruchomości zawiera się w przedziale od 500 tys. do 1 mln zł, lecz występują także mieszkania dużo droższe, w cenie nawet 2 mln zł. Najwięcej ofert dotyczy mieszkań 2- i 3-pokojowych, które także cieszą się największym zainteresowaniem wśród kupujących. Najmniej dostępnych jest mieszkań 1-, 5- oraz 6-pokojowych.

Prognozy wskazują na dalszy wzrost cen w dużych ośrodkach miejskich, zwłaszcza w atrakcyjnych, centralnych lokalizacjach. Czynniki takie jak rosnące koszty materiałów budowlanych, zmniejszanie się powierzchni na budowę nowych mieszkań czy rozwój infrastruktury mogą również mieć wpływ na kształtowanie się rynku nieruchomości w przyszłości.