Для начала подгрузим необходимые библиотеки для работы с данными и графиками.

library(readr)   #для выгрузки данных
library(e1071)   #для некоторых стат. функций
library(ggplot2) #для графиков
library(dplyr)   #для работы с данными
library(stringr) #для работы с текстом
library(scales)  #для работы с масштабом в графиках
library(kableExtra) #для построения таблиц в html
library(DescTools) #для рассчета моды

df = read_csv("SPb_dwellings_for_rent_EMLS_sample_1.csv", locale = locale(encoding = "WINDOWS-1251"))
df$Floor = as.character(df$Floor)

Группировка данных по виду

Числовые данные

numeric_df = df %>% select_if(is.numeric) 
knitr::kable(head(numeric_df)) %>% kable_styling()
Dist_metro_ad Price Area_total Area_living Area_kitchen Latitude Longitude Year_construction
1660 20000 35 20 10 NA NA NA
470 55000 51 15 19 59.99358 30.19342 NA
420 35000 45 30 6 59.96418 30.28862 1980
1170 130000 100 86 12 NA NA NA
1550 30000 40 17 14 NA NA NA
30 40000 70 45 NA 59.86925 30.45781 NA

Номинальные данные

nominal_df = df %>% select_if(is.character)
knitr::kable(head(nominal_df)) %>% kable_styling() %>% scroll_box(width = "900px")
Region District_ad Address Metro Rooms Minimum_duration No_agents Building Floor NFloor Lift Furnished Bath Refurbished Balcony
Leningradskaya oblast’ Всеволожский р-н Кудрово дер., Ленинградская ул. 5 Dybenko ul. 1 31 mes. NA Panel’nyi 7 14 Net NA NA NA Balkon
gorod Sankt-Peterburg Приморский Мебельная ул., 49 Staraya Derevnya 2 6 mes. NA Monolit 17 23 Net Sbor.+kuh.garn. NA Proizveden Lodjiya
gorod Sankt-Peterburg Петроградский Лодейнопольская ул., 2 Chkalovskaya 2 11 mes. NA Kirpichnyi 2 5 Net NA Dush Proizveden Balkon
gorod Sankt-Peterburg Центральный Шпалерная ул. 60 Chernyshevskaya 3 NA NA NA 5 9 Net Sbornaya Sovr. NA NA NA
gorod Sankt-Peterburg Московский Обводного канала наб. 46 Obvodnyi Kanal 1 NA NA NA 2 7 Net Sbornaya Sovr. NA Evrostandart NA
gorod Sankt-Peterburg Невский Обуховской Обороны пр., 195 Proletarskaya 2 11 mes. NA Individual’nyi proekt 4 24 Net NA NA NA NA

Создадим функцию для генерации таблицы с описательными статистиками для количественных переменных.

descriptive = function(data){data.frame(sapply(data, function(x) c(
                            "Min" = round(min(x, na.rm = TRUE),1),
                            "Max" = round(max(x, na.rm = TRUE),1),
                            "First quartile" = round(quantile(x,0.25, na.rm = TRUE),1),
                            "Mean"= round(mean(x,na.rm=TRUE),1),
                            "Median" = round(median(x, na.rm = TRUE),1),
                            "Mode" = round(Mode(x, na.rm = TRUE),1),
                            "Third quartile" = round(quantile(x,0.75, na.rm = TRUE),1),
                            "Standard deviation" = round(sd(x, na.rm = TRUE),1),
                            "Range" = round(max(x, na.rm = TRUE)-min(x, na.rm = TRUE),1),
                            "Skewness" = round(skewness(x, na.rm = TRUE),1),
                            "Kurtosis" = round(kurtosis(x, na.rm = TRUE),1)         )))   }

Таблица с описательными статистиками количественных данных до очистки выборки от ошибок.

knitr::kable(descriptive(numeric_df)) %>% kable_styling()
Dist_metro_ad Price Area_total Area_living Area_kitchen Latitude Longitude Year_construction
Min 0.0 16.0 15.0 2.0 1.0 59.5 30.0 1832.0
Max 44100.0 900000.0 45000.0 332.0 200.0 60.1 30.7 2017.0
First quartile.25% 300.0 22000.0 39.0 19.0 8.0 59.9 30.3 2002.0
Mean 1402.8 45516.2 85.6 36.8 13.9 59.9 30.3 2001.2
Median 770.0 30000.0 50.0 30.0 10.0 59.9 30.3 2011.0
Mode 50.0 20000.0 40.0 18.0 10.0 60.0 30.3 2016.0
Third quartile.75% 1500.0 50000.0 71.0 45.0 15.0 60.0 30.4 2015.0
Standard deviation 2622.3 48956.2 947.3 26.1 12.3 0.1 0.1 26.5
Range 44100.0 899984.0 44985.0 330.0 199.0 0.6 0.7 185.0
Skewness 6.7 5.9 42.5 2.9 4.9 -0.2 0.1 -3.5
Kurtosis 65.0 61.1 1896.7 15.2 39.2 -0.1 0.3 15.2

Удалим наблюдения, которые содержат выбросы. Рассмотрим некоторые переменные и найдем ошибки.

df_outliers = df %>% subset(Dist_metro_ad >= 44100 | Dist_metro_ad <= 10 | Price <= 30 | Area_total >= 1000 
                            | Area_total <= 9 |Area_kitchen >= 150 | Rooms == 47 | Area_living <= 10 |
                            Minimum_duration == c('11000 mes.','2000 mes.') |
                            Refurbished == c('Sovmeshchennaya', 'Dush'))
knitr::kable(df_outliers[,c(6,7,8,9,12,13,14,20)]) %>% kable_styling()%>% scroll_box(height = "600px")
Dist_metro_ad Rooms Price Minimum_duration Area_total Area_living Area_kitchen Refurbished
10 1 35000 11 mes. 46 16.0 12.0 NA
0 2 60000 12 mes. 90 50.0 15.0 Evrostandart
1190 2 30000 11 mes. 65 10.0 NA Evrostandart
200 1 25000 2000 mes. 50 NA NA NA
1230 1 16 11 mes. 33 18.0 6.0 Proizveden
0 1 39000 11 mes. 60 20.0 15.0 Evrostandart
1510 1 35000 NA 25 10.0 8.0 Proizveden
10 3 100000 NA 127 43.0 53.0 NA
44100 1 10000 10 mes. 31 17.5 5.5 NA
0 2 40000 NA 52 38.0 9.0 Ne trebuetsya
2250 2 2500 NA NA 54.0 30.4 Sovmeshchennaya
800 1 30000 6 mes. NA 32.0 18.0 Sovmeshchennaya
10 2 60000 11 mes. 61 40.0 12.0 NA
0 1 37000 11 mes. 40 20.0 10.0 Evrostandart
0 1 18000 11 mes. 34 18.0 8.0 Proizveden
0 1 25000 11 mes. 36 18.0 NA NA
10 1 (studiya) 23000 NA 27 27.0 NA NA
730 1 25000 11 mes. 40 10.0 10.0 NA
0 1 27000 1 mes. 39 19.0 NA NA
10 1 18000 11 mes. 40 20.1 8.3 Ne trebuetsya
0 2 50000 NA 80 40.0 16.0 NA
0 3 95000 11 mes. 115 77.0 15.0 NA
0 1 21000 11 mes. 31 18.0 9.0 Proizveden
0 1 26000 NA 45 20.0 12.0 Evrostandart
10 3 37000 11 mes. 73 44.0 9.0 Evrostandart
0 1 (studiya) 15000 NA 28 25.0 NA NA
2520 1 (studiya) 17000 11 mes. NA 26.0 NA Sovmeshchennaya
0 1 45000 NA 32 15.0 10.0 Proizveden
10 7 220000 11 mes. 304 212.0 31.0 NA
0 2 25000 1 mes. 52 25.0 8.0 Proizveden
0 2 65000 NA 65 55.0 12.0 NA
10 3 25000 11 mes. 55 39.0 6.0 Trebuetsya
0 1 30000 NA 47 20.0 9.0 NA
0 2 25000 NA 53 33.0 9.0 NA
710 47 23000 11 mes. 37 18.0 NA NA
0 4 300000 NA 100 73.0 14.0 NA
10 2 35000 11 mes. 60 36.0 10.0 Evrostandart
0 2 50000 NA 65 30.0 10.0 NA
0 2 80000 NA 65 42.0 1.0 NA
10 3 35000 NA 80 41.0 11.0 NA
10 3 50000 11 mes. 75 46.0 13.0 NA
0 1 25000 11 mes. 39 18.0 NA NA
10 1 30000 NA 43 17.0 12.0 NA
810 2 23000 12 mes. 23000 22.0 7.0 Proizveden
0 1 (studiya) 19000 NA 32 25.0 NA Ne trebuetsya
10 1 35000 11 mes. 45 18.0 10.0 NA
0 2 45000 NA 56 33.0 8.0 NA
0 2 33000 11 mes. 64 32.0 18.0 NA
0 2 30000 NA 60 40.0 10.0 NA
0 1 20000 11 mes. 45 17.0 14.0 NA
10 2 27000 NA 52 33.0 11.0 Evrostandart
480 5 500000 NA NA 332.0 200.0 NA
2980 1 28000 6 mes. NA 37.0 18.0 Sovmeshchennaya
10 2 85000 1 mes. 70 50.0 10.0 Evrostandart
1110 2 24000 11 mes. 52 2.0 10.0 Evrostandart
0 3 42000 11 mes. 90 54.0 16.0 Evrostandart
1450 1 20 11 mes. 44 22.0 13.0 Evrostandart
0 2 35000 11 mes. 57 24.0 25.0 NA
0 2 100000 6 mes. 78 49.0 35.0 Evrostandart
3950 2 28000 14 mes. NA 58.0 33.0 Sovmeshchennaya
10 2 35000 NA 60 32.0 14.0 NA
10 2 36000 11 mes. 70 38.0 10.0 Proizveden
0 2 35000 11 mes. 54 38.0 NA Evrostandart
10 1 20000 12 mes. 35 17.0 12.0 NA
10 2 70000 NA 113 70.0 18.0 NA
0 1 30000 11 mes. 30 20.0 1.0 NA
10 2 55000 6 mes. 50 16.0 12.0 Proizveden
0 1 18000 NA 42 18.0 10.0 NA
0 2 60000 11 mes. 80 30.0 35.0 NA
0 2 50000 NA 80 38.0 14.0 NA
3490 2 35000 11 mes. NA 55.0 31.0 Sovmeshchennaya
10 1 18000 1 mes. 39 20.0 8.5 Ne trebuetsya
10 1 22000 NA 25 12.0 7.0 NA
10 5 60000 11 mes. 89 63.0 9.0 Ne trebuetsya
10 2 43000 1 mes. 70 40.0 15.0 Proizveden
0 2 22000 11 mes. 65 34.0 11.0 Proizveden
10 1 (studiya) 18000 10 mes. 26 17.3 NA Evrostandart
920 1 20000 14 mes. NA 30.0 18.0 Sovmeshchennaya
0 3 120000 NA 96 56.0 14.0 NA
0 2 35000 11 mes. 41 23.0 NA NA
3340 1 30000 12 mes. 40 10.0 18.0 Evrostandart
10 3 50000 NA 77 50.0 9.0 NA
10 1 16000 11 mes. 32 16.0 7.0 Proizveden
10 1 25000 11 mes. 45 19.0 12.0 NA
10 1 55000 1 mes. 40 20.0 10.0 Proizveden
4920 1 22000 11000 mes. NA 22.0 NA Ne trebuetsya
10 1 48000 11 mes. 41 19.0 9.0 NA
10 1 15000 NA 35 17.0 6.0 Ne trebuetsya
10 1 22000 11 mes. 30 18.0 6.0 Ne trebuetsya
0 1 20000 1 mes. 37 18.0 NA Evrostandart
10 1 35000 11 mes. 43 16.0 10.0 Evrostandart
10 1 30000 NA 52 17.0 14.0 NA
0 1 (studiya) 22000 11 mes. 29 20.0 NA Proizveden
10 3 60000 1 mes. 80 44.0 10.0 Evrostandart
1050 1 22000 6 mes. 32 10.0 11.0 Evrostandart
10 3 70000 6 mes. 110 53.0 15.0 NA
10 2 60000 NA 65 36.0 10.0 Ne trebuetsya
770 1 25000 12 mes. NA 36.0 17.0 Sovmeshchennaya
10 1 19000 12 mes. NA 40.0 20.0 Sovmeshchennaya
10 1 35000 11 mes. 43 20.0 NA NA
210 1 (studiya) 22000 11 mes. 42 8.0 NA NA
950 1 (studiya) 18000 NA 26 2.0 NA NA
0 3 55000 11 mes. 85 33.0 30.0 Evrostandart
0 2 41000 NA 49 30.0 9.0 NA
60 2 45000 11 mes. 45000 29.0 NA Proizveden
590 2 25 6 mes. 50 24.0 6.0 Proizveden
0 3 35000 NA 80 54.0 16.0 NA
2470 1 35000 1 mes. NA 32.0 18.0 Sovmeshchennaya
10 2 52000 11 mes. 70 43.0 12.0 NA
0 2 130000 NA 85 38.0 17.0 NA
0 1 18000 11 mes. 45 45.0 10.0 Proizveden
10 3 25000 11 mes. 56 42.0 8.0 NA
0 2 35000 NA 60 34.0 10.0 NA
10 1 20000 11 mes. 35 18.0 7.0 Ne trebuetsya
0 3 45000 11 mes. 97 51.0 15.0 NA
370 2 30000 11 mes. NA 56.0 33.0 Dush
0 1 40000 11 mes. 43 17.0 10.0 NA
10 2 40000 NA 58 35.0 12.0 NA
0 1 21000 NA 37 17.0 9.0 Proizveden
10 4 200000 11 mes. 150 93.0 18.0 NA
10 1 23000 11 mes. 40 19.0 NA NA
0 4 90000 NA 115 85.0 10.0 NA
10 1 25500 11 mes. 53 24.0 10.0 NA
3160 2 30 11 mes. 62 39.0 10.0 Evrostandart
10 1 20000 NA 34 20.0 9.0 Ne trebuetsya
2090 1 17000 6 mes. 19 10.0 NA Proizveden
0 2 40000 6 mes. 64 33.0 17.5 Evrostandart
10 2 45000 NA 60 29.0 9.0 NA
1550 1 19000 11 mes. NA 29.0 18.0 Sovmeshchennaya
0 2 42000 NA 60 40.0 10.0 Proizveden
10 1 24000 11 mes. 40 20.0 10.0 Ne trebuetsya
0 2 25000 NA 42 30.0 7.0 Ne trebuetsya
0 1 25000 NA 51 40.0 11.0 NA
640 2 38000 NA 54 8.0 NA Proizveden

В таблице выше можно видеть наблюдения, в которых содержатся ошибки. Исключим их из нашей выборки и построим таблицы с описательными статистиками снова.

clear_numeric_df =  df %>% 
  anti_join(df_outliers) %>% 
  select_if(is.numeric)

clear_nominal_df =  df %>% 
  anti_join(df_outliers) %>% 
  select_if(is.character)

knitr::kable(descriptive(clear_numeric_df)) %>% kable_styling()
Dist_metro_ad Price Area_total Area_living Area_kitchen Latitude Longitude Year_construction
Min 20.0 1500.0 15.0 11.0 1.0 59.5 30.0 1832.0
Max 37630.0 900000.0 600.0 251.0 126.0 60.1 30.7 2017.0
First quartile.25% 370.0 22000.0 39.0 19.0 8.0 59.9 30.3 2002.0
Mean 1436.9 45599.3 61.9 36.9 13.8 59.9 30.3 2000.9
Median 800.0 30000.0 50.0 30.0 10.0 59.9 30.3 2011.0
Mode 50.0 20000.0 40.0 18.0 10.0 60.0 30.3 2016.0
Third quartile.75% 1520.0 50000.0 71.0 45.0 15.0 60.0 30.4 2015.0
Standard deviation 2542.4 48669.2 39.2 25.7 11.9 0.1 0.1 26.7
Range 37610.0 898500.0 585.0 240.0 125.0 0.6 0.7 185.0
Skewness 6.0 6.0 3.9 2.6 4.1 -0.2 0.1 -3.4
Kurtosis 48.8 62.6 30.1 10.4 23.6 -0.4 0.3 14.8

Таблицы с частотой значений

Создадим функцию для генерации таблиц с частотой значений номинальных переменных.

freq_tab = function(var, name, rows = 5){
  freq = data.frame( sort( table( var ), decreasing =T ) ) %>% head(rows)
  names(freq) = c(name,'Count')
  knitr::kable(freq)} %>% kable_styling(full_width = F,position = "left")

Построим таблицу показывающую частоту различных значений для ближайших станций метро. Покажем наиболее часто встречающиеся.

freq_tab(var = clear_nominal_df$Metro, name = 'Metro') 
Metro Count
Primorskaya 146
Komendantskii pr. 120
Moskovskaya 110
Chernyshevskaya 106
Leninskii pr. 102

Построим таблицу показывающую частоту различных значений для районов. Покажем наиболее часто встречающиеся.

freq_tab(var = clear_nominal_df$District_ad, name = 'District') 
District Count
Центральный 355
Московский 329
Приморский 322
Петроградский 262
Выборгский 244

Построим таблицу показывающую частоту различных значений для количества комнат. Покажем наиболее часто встречающиеся.

freq_tab(var = clear_nominal_df$Rooms, name = 'Rooms') 
Rooms Count
1 1126
2 948
3 506
1 (studiya) 111
4 97

Построим таблицу показывающую частоту различных значений для типа здания. Покажем наиболее часто встречающиеся.

freq_tab(var = clear_nominal_df$Building, name = 'Building') 
Building Count
Kirpichnyi 939
Kirp.Monolit 568
Monolit 315
Panel’nyi 176
Blochnyi 121

Построим таблицу показывающую частоту различных значений для типа балкона. Покажем наиболее часто встречающиеся.

freq_tab(var = clear_nominal_df$Balcony, name = 'Balcony') 
Balcony Count
Balkon 745
Lodjiya 339
Net 248
Zasteklennaya lodjiya 233
est’ 124

Построим таблицу показывающую частоту различных значений для количества этажей в доме. Покажем наиболее часто встречающиеся. Можно видеть что пяти- и девятиэтажки наиболее распространены.

freq_tab(var = clear_nominal_df$NFloor, name = 'NFloor') 
NFloor Count
5 442
9 367
12 215
16 193
6 175

Функции плотности

Создадим функции плотности для генерации диаграмм распределения значений количественных переменных.

density_plot = function(column, title="title", name="name"){
  ggplot(data =clear_numeric_df, aes(x=column)) +
    geom_histogram(aes(y=..density..)) +
    geom_density(col='red')+
    labs(title=title, x=name)+
    theme_minimal()
    }
density_plot(clear_numeric_df$Dist_metro_ad, title = 'Distribution of Distance to metro station', name = 'Distance')
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

length(which( clear_numeric_df$Dist_metro_ad < 6000 ))/nrow(df) 
## [1] 0.8983333

Можно видеть, что 94% квартир находятся ближе чем 6 км от метро.

density_plot(clear_numeric_df$Price, title = 'Distribution of Mounthly rent price', name = 'Price')
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

На графике изображен общий вид гистограммы распределения цены аренды квартиры. Давайте посмотрим поближе на кваритры с ценой аренды меньше 100к.

density_plot(clear_numeric_df$Price, title = 'Distribution of Mounthly rent price', name = 'Price')
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

sh_mult5 = length(which( (df$Price/5000)%%1 == 0 ) ) / nrow(clear_numeric_df) # доля квартир с ценой кратной 5000
sh_less30_mult5 = length(which( (df$Price/5000)%%1 != 0 & df$Price < 30000) ) / nrow(clear_numeric_df) # доля квартир с ценой менее 30к при это мне кратной 5000
sh_less30_in_not_mult5 = length(which( (df$Price/5000)%%1 != 0 & df$Price < 30000) ) / 
  length(which( (df$Price/5000)%%1 != 0) )      # доля квартир с ценой менее 30к среди квартир с ценой не кратной 5000
sh_not_mult5_in_less30 = length(which( (df$Price/5000)%%1 != 0 & df$Price < 30000) )/length(which( df$Price < 30000 ) ) # доля квартир с ценой не кратной 5000 среди квартир цена которых меньше 30к
sh_not_mult5_in_more30 = length(which( (df$Price/5000)%%1 != 0 & df$Price > 30000) )/length(which( df$Price > 30000 ) ) # доля квартир с ценой не кратной 5000 среди квартир цена которых больше 30к
##  Доля квартир с ценой кратной 5000: 0.64 
##  Доля квартир с ценой менее 30к при это мне кратной 5000: 0.32 
##  Доля квартир с ценой менее 30к среди квартир с ценой не кратной 5000: 0.78 
##  Доля квартир с ценой не кратной 5000 среди квартир цена которых меньше 30к: 0.64 
##  Доля квартир с ценой не кратной 5000 среди квартир цена которых больше 30к: 0.17

На диаграмме видно что очень часто значения цены кратны числу 5000 – более 61% всех квартир имеют именно такую “круглую” цену. Доля квартир с ценой менее 30к среди тех, чья цена не кратна 5000 составляет 78%. Таким образом, люди чаще указывают “круглую” цену, однако если цена аренды невелика, то арендодатель с большей вероятностью укажет цену не кратную 5000 – для квартир с ценой менее и более 30к доля квартир с ценой не кратной 5000 составляет 64% и 17% соответственно.

density_plot(clear_numeric_df$Area_total, title = 'Distribution of Total area', name = 'Total area')
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

length(which( clear_numeric_df$Area_total < 100 ))/
  nrow(clear_numeric_df[complete.cases(clear_numeric_df[ , 3]),])
## [1] 0.875781

88% всех квартир имеют общую площадь меньше 100 кв.м.

density_plot(clear_numeric_df$Area_living, title = 'Distribution of Living area', name = 'Living area')
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

На диаграмме явно видно что однокомнатный квартиры и студии с маленькой жилой площадью наиболее распространены. Еще одна мода - двухкомнатный кваритры, который также сдают в наем, но не так часто как однокомнатные.

density_plot(clear_numeric_df$Area_kitchen, title = 'Distribution of Kitchen area', name = 'Kitchen area')
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

length(which( clear_numeric_df$Area_kitchen <= 20 ))/
  nrow(clear_numeric_df[complete.cases(clear_numeric_df[ , 5]),])
## [1] 0.8810555

Как правило площадь кухни в сдаваемых в наем кваритрах небольшая – в 88% кваритир площадь кухни не больше 20 кв.м.

density_plot(clear_numeric_df$Year_construction, title = "Distribution of Year construction", name = "Year construction")
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Можно заметить что чаще всего сдают квартиры в новостройках.

Столбчатые диаграммы

Создадим функции генерации столбчатых диаграмм для описания категориальных переменных.

bar_plot = function(var, title, name, width = 1){step_df = data.frame(table(var))
  names(step_df) = c('x', 'count')
  ggplot(data=step_df, aes(x=x, y=count)) +
  geom_bar(stat="identity", fill="black", alpha = 0.8,width = width)+
  geom_text(aes(label=count), vjust=-0.05, color="black", size=3)+ 
  labs(title=title, x=name, y="Count") + theme_minimal()}
bar_plot_ordered = function(var, title, name, width = 1){ggplot(var, aes(x = Var1, y = Freq)) + 
  geom_bar(stat="identity", color='black',fill='black', alpha = 0.8,width = width) +
  geom_text(aes(label=Freq), vjust=-0.05, color="black", size=3)+
  labs(title=title, x=name, y="Count")}

Регион

bar_plot(clear_nominal_df$Region, title = 'Region', name = 'Region', width = 0.5)

На диаграмме видно, что подавляющее большинство квартир сдаются в Санкт-Петербурге.

Ремонт

ref = data.frame( sort( table( clear_nominal_df$Refurbished ), decreasing =T ) )
bar_plot_ordered(ref, "Refurbished", 'Refurbished', width = 0.95)

Минимальный срок аренды

dur = data.frame( sort( table( clear_nominal_df$Minimum_duration ), decreasing =T ) )
bar_plot_ordered(dur, "Minimum duration", 'Minimum duration', width = 0.95)

Три наиболее распространенных значения - на год (11 или 12 месяцев) или на полгода.

Наличие мебели

fur = data.frame( sort( table( clear_nominal_df$Furnished ), decreasing =T ) )
bar_plot_ordered(fur, "Furnished", 'Furnished', width = 0.8)

Большинство сдаваемых в наем кваритр меблированы.

Наличие лифта

lifty = data.frame( sort( table( clear_nominal_df$Lift ), decreasing =T ) )
bar_plot_ordered(lifty, "Lift", 'Lift', width = 0.4)

Более чем в половине домов, в которых сдают в наем квартиры, есть лифт.

Диаграммы рассеяния

Напишем функцию для рисовки графика рассеяния между ценой квартир и остальными переменными.

plot_scatter_price = function(column, description){
  ggplot() +
    geom_point(aes(x=column, y=clear_numeric_df$Price),alpha = 0.5) +
    labs(title = paste("The dependence of housing prices and",str_to_lower(description))) +
    xlab(description) +
    ylab("Price") +
    scale_y_continuous(labels = label_number(scale = 1/1000, suffix = "K")) +
    theme_minimal()
}

Далее, смотрим, что у нас получилось.

Расстояние до ближайшего метро

plot_scatter_price(clear_numeric_df$Dist_metro_ad , "Distance to the nearest metro station\n(in meters)")

cor(clear_numeric_df$Price, clear_numeric_df$Dist_metro_ad, use = "complete.obs")
## [1] -0.06850234

В данном случае у нас наблюдается нелинейная зависимость. Можно точно сказать, что чем дальше квартира от метро, тем она дешевле. Если же кваритра находится рядом с метро то она может быть как и дешевой, так и дорогой. Коэффициент корреляции равен -0.06, что указывает на то, что взаимосвязи нет. Однако корреляция показывает только линейную зависимость.

Общая площадь квартиры

plot_scatter_price(clear_numeric_df$Area_total, "Total area")

cor(clear_numeric_df$Price, clear_numeric_df$Area_total, use = "complete.obs")
## [1] 0.79851

Как видно из полученного графика, у нас есть положительная зависимость, то есть чем больше общая площадь квартиры, тем дороже сама квартира. Корреляция равна 0.80, что доказывает вышесказанное.

Жилая площадь

plot_scatter_price(clear_numeric_df$Area_living, "Living area (m^2)")

cor(clear_numeric_df$Price, clear_numeric_df$Area_living, use = "complete.obs")
## [1] 0.7224522

Аналогично общей площади квартиры, цена квартиры положительно зависит от жилой площади. Коэффициент корреляции равено 0.73, то есть чем больше жилая площадь, тем дороже квартира.

Площадь кухни

plot_scatter_price(clear_numeric_df$Area_kitchen, "Kitchen area (m^2)")

cor(clear_numeric_df$Price, clear_numeric_df$Area_kitchen, use = "complete.obs")
## [1] 0.4685179

Сложно сказать о какой-либо зависимости, но небольшой положительный тренд наблюдается. Коэффициент корреляции, равный 0.50, подтверждает о неявной положительной зависимости.

Этаж

ggplot() +
    geom_point(aes(x=as.numeric(df$Floor), y=df$Price, color = df$Lift)) +
    labs(title = paste("The dependence of housing prices and",str_to_lower("Floor")),
         color = "Lift") +
    xlab("Floor") +
    ylab("Price") +
    scale_y_continuous(labels = label_number(scale = 1/1000, suffix = "K")) +
    theme_minimal()

cor(df$Price, as.numeric(df$Floor), use = "complete.obs")
## [1] -0.117608

В нашей выборке получилось так, что чем выше расположена квартира, тем дешевле она стоит, даже несмотря на то, что в большинстве случаев в доме присутствует лифт. Касательно нижних этажов, цена квартиры ранжируется от дешевых до дорогих. Однако коэффициент корреляции равен -0.11, ввиду нелинейной зависимости.

Год постройки

plot_scatter_price(clear_numeric_df$Year_construction, "Year construction")

cor(clear_numeric_df$Price, clear_numeric_df$Year_construction, use = "complete.obs")
## [1] 0.0104036

Очевидно, что квартиры в старых домах будут дешевыми. Чем позже построен дом, тем размах цены выше, то есть он может быть как и дешевым, так и дорогим, в то время как старые дома строго дешевы по цене. Из-за нелинейности, вновь получаем коэффициент корреляция близкий к 0.

Долгота и широта

plot_scatter_price(clear_numeric_df$Latitude, "Latitude")

cor(clear_numeric_df$Price, clear_numeric_df$Latitude, use = "complete.obs")
## [1] 0.05450633

В середине скопления точек размах цены гораздно высок, чем на краях графика. Можно предположить, что в данной широте расположены квартиры Петербурга, следовательно и цены широко варьируются. Мы можем утверждать о нелинейной независимости, которую, однако, коэффициент корреляции не сможет уловить. К слову, корреляция равна 0.05.

plot_scatter_price(clear_numeric_df$Longitude, "Longitude")

cor(clear_numeric_df$Price, clear_numeric_df$Longitude, use = "complete.obs")
## [1] -0.1060449

Аналогично и для долготы. в середине есть промежуток, который указывает нам на город Петербург (за промежутком, следовательно, расположены области). Вывод такой же как и с широтой. Чем ближе к городу, то есть ближе к определенному промежутку долготы, тем дороже квартиры. Коэффициент корреляции -0.1.

Еще корреляция

knitr::kable(round(cor(clear_numeric_df, use = "pairwise.complete.obs"),2)) %>% kable_styling()
Dist_metro_ad Price Area_total Area_living Area_kitchen Latitude Longitude Year_construction
Dist_metro_ad 1.00 -0.07 -0.04 -0.06 -0.06 -0.09 -0.19 0.08
Price -0.07 1.00 0.80 0.72 0.47 0.05 -0.11 0.01
Area_total -0.04 0.80 1.00 0.91 0.59 0.07 -0.08 0.01
Area_living -0.06 0.72 0.91 1.00 0.60 0.04 -0.09 -0.03
Area_kitchen -0.06 0.47 0.59 0.60 1.00 0.03 -0.08 0.09
Latitude -0.09 0.05 0.07 0.04 0.03 1.00 0.04 0.05
Longitude -0.19 -0.11 -0.08 -0.09 -0.08 0.04 1.00 -0.07
Year_construction 0.08 0.01 0.01 -0.03 0.09 0.05 -0.07 1.00

Из полученной матрицы коэффициентов корреляции можно выделить несколько сильно-зависимые переменные: Area_total и Price (0.8), Area_living и Price (0.73), Area_total и Area living (0.91), Area_living и Area kitchen (0.62).

Можно сделать вывод, что в основном наблюдается положительная линейная попарная зависимость между площадями комнат, жилой площадью и квартиры вцелом, а также ценой квартиры.