L’obiettivo è fornire insight statistici e visivi che supportino le
decisioni strategiche di vendita e ottimizzazione delle inserzioni
immobiliari.
# Iniziamo con il caricare i pacchetti necessari per l'analisi di mercato in questione.
library(ggplot2)
library(dplyr)
##
## Caricamento pacchetto: 'dplyr'
## I seguenti oggetti sono mascherati da 'package:stats':
##
## filter, lag
## I seguenti oggetti sono mascherati da 'package:base':
##
## intersect, setdiff, setequal, union
library(readr)
library(moments) # per gli indici di asimmetria e curtosi
library(ineq) # per l'indice di Gini
# Importiamo il dataset "Real Estate Texas"
ds <- read_csv("realestate_texas.csv")
## Rows: 240 Columns: 8
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## chr (1): city
## dbl (7): year, month, sales, volume, median_price, listings, months_inventory
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
### 1. ANALISI DELLE VARIABILI
# Osserviamo la struttura del dataset, con un focus principale sulle variabili a disposizione
summary(ds)
## city year month sales
## Length:240 Min. :2010 Min. : 1.00 Min. : 79.0
## Class :character 1st Qu.:2011 1st Qu.: 3.75 1st Qu.:127.0
## Mode :character Median :2012 Median : 6.50 Median :175.5
## Mean :2012 Mean : 6.50 Mean :192.3
## 3rd Qu.:2013 3rd Qu.: 9.25 3rd Qu.:247.0
## Max. :2014 Max. :12.00 Max. :423.0
## volume median_price listings months_inventory
## Min. : 8.166 Min. : 73800 Min. : 743 Min. : 3.400
## 1st Qu.:17.660 1st Qu.:117300 1st Qu.:1026 1st Qu.: 7.800
## Median :27.062 Median :134500 Median :1618 Median : 8.950
## Mean :31.005 Mean :132665 Mean :1738 Mean : 9.193
## 3rd Qu.:40.893 3rd Qu.:150050 3rd Qu.:2056 3rd Qu.:10.950
## Max. :83.547 Max. :180000 Max. :3296 Max. :14.900
glimpse(ds)
## Rows: 240
## Columns: 8
## $ city <chr> "Beaumont", "Beaumont", "Beaumont", "Beaumont", "Beau…
## $ year <dbl> 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010, 2010,…
## $ month <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 1, 2, 3, 4, 5,…
## $ sales <dbl> 83, 108, 182, 200, 202, 189, 164, 174, 124, 150, 150,…
## $ volume <dbl> 14.162, 17.690, 28.701, 26.819, 28.833, 27.219, 22.70…
## $ median_price <dbl> 163800, 138200, 122400, 123200, 123100, 122800, 12430…
## $ listings <dbl> 1533, 1586, 1689, 1708, 1771, 1803, 1857, 1830, 1829,…
## $ months_inventory <dbl> 9.5, 10.0, 10.6, 10.6, 10.9, 11.1, 11.7, 11.6, 11.7, …
# Analizziamo dunque le variabili a disposizione
# - city: città (Texana) di riferimento - variabile qualitativa nominale
# Essa permette di effettuare confronti tra le città: frequenze, volumi, medie condizionate...
# - year: anno di riferimento - variabile quantitativa discreta (temporale)
# Con essa si possono condurre analisi di trend nel tempo , confronti storici e variazioni per anno
# - month: mese di riferimento - var. quant. discreta (temporale) che può essere convertita comodamente in una variabile qualitativa ordinale (utilizzando delle etichette, ES: Jan, Feb, ...)
# Permette di svolgere analisi di tipo stagionale (es: line chart mensili)
# - sales: numero totale di vendite - var. quant. discreta
# Oltre che calcolarvi indici di posizione e variabilità, è possibile confrontare le vendite per città e/o mese e/o anno
# - volume: valore tot ($) delle vendite - var. quant. continua
# Si potrebbe effettuare un'analisi di correlazione con sales e/o median_price
# - median_price: prezzo mediano ($) di vendita - var. quant. continua
# Può essere utilizzata per confrontare le città ed i "periodi storici"
# - listings: numero totale di annunci attvi - var. quant. discreta
# Permette di svolgere un'analisi di rapporto tra l'offerta di mercato e le vendite, ottenendo dunque un focus sull'efficacia degli annunci
# - months_inventory: quantità di tempo (in mesi) necessaria per vendere tutte le inserzioni correnti - var. quant. discreta
# Permette di misurare la velocità del mercato, dunque avrebbe senso analizzare la correlazione con "sales".
# CONSIDERAZIONE GENERALE:
# Nel dataset in questione (ds) sono presenti sia misure quantitative (vendite) che caratteristiche qualitative (città).
# Le prime consentono analisi di tipo descrittivo ed analisi di correlazione.
# Le seconde, invece, permettono di effettuare raggruppamenti per confronti.
# Infine, con "year" e "month", è possibile analizzare trend storici e stagionalità per vendite, volumi, etc.
# Prima di procedere allo step successivo convertiamo i mesi (a numero) in sigle, per comodità
ds$month <- factor(ds$month, levels=1:12,
labels=c("Jan","Feb","Mar","Apr",
"May","Jun","Jul","Aug","Sep","Oct","Nov","Dec")
)
head(ds$month)
## [1] Jan Feb Mar Apr May Jun
## Levels: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec
### 2. INDICI DI POSIZIONE, VARIABILITA' E FORMA
# Per comodità selezioniamo dal dataset le variabili (colonne) sul quale ha senso calcolare gli indici, e le raggruppiamo.
ds_num_vars <- ds[, c("sales","volume","median_price","listings","months_inventory")]
# Calcoliamo, comodamente (summary), alcuni degli indici di posizione ossia: i quartili, il minimo, il massimo, la mediana e la media
summary(ds_num_vars)
## sales volume median_price listings
## Min. : 79.0 Min. : 8.166 Min. : 73800 Min. : 743
## 1st Qu.:127.0 1st Qu.:17.660 1st Qu.:117300 1st Qu.:1026
## Median :175.5 Median :27.062 Median :134500 Median :1618
## Mean :192.3 Mean :31.005 Mean :132665 Mean :1738
## 3rd Qu.:247.0 3rd Qu.:40.893 3rd Qu.:150050 3rd Qu.:2056
## Max. :423.0 Max. :83.547 Max. :180000 Max. :3296
## months_inventory
## Min. : 3.400
## 1st Qu.: 7.800
## Median : 8.950
## Mean : 9.193
## 3rd Qu.:10.950
## Max. :14.900
# Con sapply, lavorando sul raggruppamento di colonne appena creato, calcoliamo gli indici mancanti
moda <- sapply(ds_num_vars, function(x) names(which.max(table(x))))
# Di seguito calcoliamo, invece, gli indici di variabilità
range_val <- sapply(ds_num_vars, function(x) max(x,na.rm=T) - min(x,na.rm=T))
range_iqr <- sapply(ds_num_vars, IQR, na.rm=T)
varianza <- sapply(ds_num_vars, var, na.rm=T)
dev_std <- sapply(ds_num_vars, sd, na.rm=T)
var_coeff <- sapply(ds_num_vars, function(x) sd(x, na.rm=T)/mean(x,na.rm=T)*100)
gini_index <- sapply(ds_num_vars, function(x) Gini(x, na.rm=T))
# Calcoliamo gli indici di FORMA
asimmetria <- sapply(ds_num_vars, skewness, na.rm=T)
curtosi <- sapply(ds_num_vars, kurtosis, na.rm=T)
# Adesso, per comodità, raggruppiamo tutti gli indici in una tabella
tab_indici <- data.frame(
Media=round(sapply(ds_num_vars, mean, na.rm=T),2),
Mediana=round(sapply(ds_num_vars, median, na.rm=T),2),
Moda=moda,
Min=sapply(ds_num_vars, min, na.rm=T),
Q1=round(sapply(ds_num_vars, function(x) quantile(x,probs=0.25,na.rm=T)),2),
Q3=round(sapply(ds_num_vars, function(x) quantile(x,probs=0.75,na.rm=T)),2),
Max=sapply(ds_num_vars, max, na.rm=T),
Range=round(range_val,2),
IQR=round(range_iqr,2),
Var=round(varianza,2),
Dev_Std=round(dev_std,2),
Var_Coeff=round(var_coeff,2),
Gini=round(gini_index,3),
Asimmetria=round(asimmetria,3),
Curtosi=round(curtosi,3)
)
# Visualizziamola
tab_indici
## Media Mediana Moda Min Q1 Q3
## sales 192.29 175.50 124 79.000 127.00 247.00
## volume 31.01 27.06 14.003 8.166 17.66 40.89
## median_price 132665.42 134500.00 130000 73800.000 117300.00 150050.00
## listings 1738.02 1618.50 1581 743.000 1026.50 2056.00
## months_inventory 9.19 8.95 8.1 3.400 7.80 10.95
## Max Range IQR Var Dev_Std Var_Coeff
## sales 423.000 344.00 120.00 6.34430e+03 79.65 41.42
## volume 83.547 75.38 23.23 2.77270e+02 16.65 53.71
## median_price 180000.000 106200.00 32750.00 5.13573e+08 22662.15 17.08
## listings 3296.000 2553.00 1029.50 5.66569e+05 752.71 43.31
## months_inventory 14.900 11.50 3.15 5.31000e+00 2.30 25.06
## Gini Asimmetria Curtosi
## sales 0.231 0.718 2.687
## volume 0.296 0.885 3.177
## median_price 0.097 -0.365 2.377
## listings 0.238 0.649 2.208
## months_inventory 0.141 0.041 2.826
# Creiamo le distribuzioni di frequenza per le variabili qualitative (city, year, month) e visualizziamole
# City
freq_ass_city <- table(ds$city)
freq_rel_city <- round(prop.table(freq_ass_city)*100,2)
cum_ass_city <- cumsum(freq_ass_city)
cum_rel_city <- cumsum(freq_rel_city)
freq_table_city <- data.frame(
City=names(freq_ass_city),
n_i=as.numeric(freq_ass_city),
f_i=as.numeric(freq_rel_city),
N_i=as.numeric(cum_ass_city),
F_i=as.numeric(cum_rel_city)
)
#Year
freq_ass_year <- table(ds$year)
freq_rel_year <- round(prop.table(freq_ass_year)*100,2)
cum_ass_year <- cumsum(freq_ass_year)
cum_rel_year <- cumsum(freq_rel_year)
freq_table_year <- data.frame(
Year=names(freq_ass_year),
n_i=as.numeric(freq_ass_year),
f_i=as.numeric(freq_rel_year),
N_i=as.numeric(cum_ass_year),
F_i=as.numeric(cum_rel_year)
)
#Month
freq_ass_month <- table(ds$month)
freq_rel_month <- round(prop.table(freq_ass_month)*100,2)
cum_ass_month <- cumsum(freq_ass_month)
cum_rel_month <- cumsum(freq_rel_month)
freq_table_month <- data.frame(
Month=names(freq_ass_month),
n_i=as.numeric(freq_ass_month),
f_i=as.numeric(freq_rel_month),
N_i=as.numeric(cum_ass_month),
F_i=as.numeric(cum_rel_month)
)
# Visualizziamole
freq_table_city
## City n_i f_i N_i F_i
## 1 Beaumont 60 25 60 25
## 2 Bryan-College Station 60 25 120 50
## 3 Tyler 60 25 180 75
## 4 Wichita Falls 60 25 240 100
freq_table_year
## Year n_i f_i N_i F_i
## 1 2010 48 20 48 20
## 2 2011 48 20 96 40
## 3 2012 48 20 144 60
## 4 2013 48 20 192 80
## 5 2014 48 20 240 100
freq_table_month
## Month n_i f_i N_i F_i
## 1 Jan 20 8.33 20 8.33
## 2 Feb 20 8.33 40 16.66
## 3 Mar 20 8.33 60 24.99
## 4 Apr 20 8.33 80 33.32
## 5 May 20 8.33 100 41.65
## 6 Jun 20 8.33 120 49.98
## 7 Jul 20 8.33 140 58.31
## 8 Aug 20 8.33 160 66.64
## 9 Sep 20 8.33 180 74.97
## 10 Oct 20 8.33 200 83.30
## 11 Nov 20 8.33 220 91.63
## 12 Dec 20 8.33 240 99.96
# OSSERVAZIONI:
# 1. la variabile per il quale si ha la variabilità più bassa è il prezzo mediano di vendita (median_price), con il coeff. di var. pari a 17.08% (Gini=0.097);
# 2. la variabile con la più alta variabilità è il valore totale delle vendite (volume), con il coeff. di var. 53.71%;
# 3. la variabile più "vicina" alla distribuzione normale è months_inventory (asimmetria=0.041 , curtosi=2.83);
# 4. anche sales e listings mostrano un'alta variabilità
# 5. Il dataset risulta essere bilanciato. ossia, le variabili city, year e month le loro distribuzioni sono uniformi e le varie modalità sono equiprobabili.
# Dunque prendendo un riga casuale dal dataset, ogni città ha la stessa probabilità di essere estratta, ogni anno ha la stessa probabilità di comparire e lo stesso vale per "month", con ogni mese che ha la stessa probabilità di comparire.
### 3. IDENTIFICAZIONE DELLE VARIABILI CON MAGGIORE VARIABILITA' E ASIMMETRIA
# Riprendiamo la tabella tab_indici ed osserviamo qual è l'argomento del massimo, ed il massimo, della colonna legata al CV
rownames(tab_indici)[which.max(tab_indici$Var_Coeff)]; max(tab_indici$Var_Coeff)
## [1] "volume"
## [1] 53.71
# Dunque è possibile affermare che il volume (valore totale delle vendite) si disperde molto attorno alla propria media.
# Da ciò si intuisce che il mercato immobiliare del Texas vede importanti oscillazioni nel valore economico complessivo delle vendite.
# Osservando i valori più alti in valore assoluto per l'asimmetria, dalla stessa tabella è possibile osservare come i parametri sales, volume e listing siano caratterizzati da asimmetria positiva (>0).
tab_indici[order(abs(tab_indici$Asimmetria), decreasing=T), "Asimmetria", drop=F]
## Asimmetria
## volume 0.885
## sales 0.718
## listings 0.649
## median_price -0.365
## months_inventory 0.041
# Nel dettaglio, la più asimmetrica è la variabile legata al volume.
# L'asimmetria positiva, in questo caso, ci lascia intuire che la maggior parte delle osservazioni ha valori medio bassi
### 4. CREAZIONE DI CLASSI PER UNA VARIABILE QUANTITATIVA
# Selezioniamo la variabile "sales" che indica il numero totale di vendite.
# Suddividiamola in classi.
max_sales <- max(ds$sales, na.rm=T)
breaks_sales <- seq(50, max_sales+50, by=50)
ds$sales_class <- cut(ds$sales, breaks=breaks_sales,
include.lowest=T,
right=F)
# Prendiamo le frequenze assolute
freq_sales <- table(ds$sales_class)
freq_sales
##
## [50,100) [100,150) [150,200) [200,250) [250,300) [300,350) [350,400) [400,450]
## 20 69 58 33 34 14 9 3
# Lo converto in dataframe per comodità
freq_sales_ds <- as.data.frame(freq_sales)
colnames(freq_sales_ds) <- c("sales_class", "freq")
# Costruiamo il grafico a barre
ggplot(freq_sales_ds, aes(x=sales_class, y=freq))+
geom_col(fill="green")+
geom_text(aes(label=freq), vjust=-0.1)+
labs(title="Distribuzione delle vendite per classi",
x="Classi di vendite (da 50)",
y="Frequenza")

# Ora calcoliamo l'indice di Gini
gini_sales_class <- Gini(freq_sales_ds$freq)
gini_sales_class
## [1] 0.40625
# Con un indice di Gini a 0.4 è possibile affermare che la distribuzione (delle frequenze rispetto le classi di sales) sia moderatamente diseguale.
# Ossia, alcune classi contengono più righe del dataset (di partenza) mentre altre poche.
# La maggior parte dei record si concentra in alcune fasce, come si può notare anche dal grafico precedente: [100, 150), [150, 200)
### 5. CALCOLO DELLA PROBABILITA'
# Riprendendo il punto 2, relativo alle distribuzioni di frequenza di city year e month, potremmo già indicare la probabilità di pescare un record con città ed un record con mese Luglio
# Ricordiamo, infatti, che ogni modalità (per ciascuna variabile qualitativa) ha la stessa probabilità di essere estratta
# A prescindere da ciò, calcoliamo a mano le probabilità sopra citate
n <- nrow(ds)
# city deve essere di tipo character
ds$city <- as.character(ds$city)
# Prob. city=Beaumont
prob_beaumont <- round((sum(ds$city=="Beaumont")/n)*100, 2)
prob_beaumont
## [1] 25
# Prob. month=Luglio
prob_july <- round((sum(ds$month=="Jul")/n)*100, 2)
prob_july
## [1] 8.33
# Prob. Dic 2012
prob_dec2012 <- round((sum(ds$month=="Dec" & ds$year==2012)/n)*100, 2)
prob_dec2012
## [1] 1.67
### 6. CREAZIONE DI NUOVE VARIABILI
# Creo la variabile average_price, che indica il prezzo medio degli immobili.
# La ottengo tramite il rapporto tra volume (valore totale delle vendite) e sales (numero di vendite)
ds <- ds %>%
mutate(average_price = (volume*1e6)/sales)
# Ho moltiplicato per 10^6 in quanto volume è il valore totale in milioni di dollari, dunque per il nostro calcolo era opportuno avere il valore per intero.
# Osserviamo:
head(ds[, c("volume", "sales", "average_price")])
## # A tibble: 6 × 3
## volume sales average_price
## <dbl> <dbl> <dbl>
## 1 14.2 83 170627.
## 2 17.7 108 163796.
## 3 28.7 182 157698.
## 4 26.8 200 134095
## 5 28.8 202 142738.
## 6 27.2 189 144016.
# Per misurare l'efficacia degli annunci di vendita, invece, creo una variabile (colonna) utilizzando sales e listings (totale di annunci attivi).
# Tramite il rapporto tra vendite ed annunci attivi è possibile, di fatto, avere una percezione dell'efficacia degli annunci.
# Se il valore è vicino a 100(%) allora l'efficacia è alta, altrimenti più ci si avvicina allo 0 e più essa è bassa.
ds <- ds %>%
mutate(efficacy = (sales/listings)*100)
# Osserviamo:
head(ds[, c("sales", "listings", "efficacy")])
## # A tibble: 6 × 3
## sales listings efficacy
## <dbl> <dbl> <dbl>
## 1 83 1533 5.41
## 2 108 1586 6.81
## 3 182 1689 10.8
## 4 200 1708 11.7
## 5 202 1771 11.4
## 6 189 1803 10.5
max(ds$efficacy)
## [1] 38.71278
# L'efficacia massima, osservata nel dataset, è pari al 38.7%. Dunque per ogni riga, nel caso migliore, circa il 39% degli annunci attivi porta ad effettive vendite.
# Valori tanto inferiori, avvicinandosi allo 0%, possono suggerire una bassa richiesta ed un'ampia disponibilità.
### 7. ANALISI CONDIZIONATA
# Iniziamo "condizionando" per città
city_summary <- ds %>%
group_by(city) %>%
summarise(
mean_sales = mean(sales),
sd_sales = sd(sales),
mean_volume = mean(volume),
sd_volume = sd(volume),
mean_median_price = mean(median_price),
sd_median_price = sd(median_price),
mean_listings = mean(listings),
sd_listings = sd(listings)
)
city_summary
## # A tibble: 4 × 9
## city mean_sales sd_sales mean_volume sd_volume mean_median_price
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Beaumont 177. 41.5 26.1 6.97 129988.
## 2 Bryan-College Sta… 206. 85.0 38.2 17.2 157488.
## 3 Tyler 270. 62.0 45.8 13.1 141442.
## 4 Wichita Falls 116. 22.2 13.9 3.24 101743.
## # ℹ 3 more variables: sd_median_price <dbl>, mean_listings <dbl>,
## # sd_listings <dbl>
# La città con la media più alta di vendite, in termini assoluti ed economici, risulta essere Tyler.
# In aggiunta, Bryan-College Station mostra la dev. standard più alta tra le città. Ciò indica che c'è una maggiore dispersione attorno alla media, ossia il mercato risultà più "volatile" e meno prevedibile.
# Il mercato è più stabile, invece, per Wichita Falls che mostra una variabilità più contenuta.
# Osserviamone un grafico riguardante la media delle vendite per città
ggplot(city_summary, aes(x=reorder(city, mean_sales), y=mean_sales))+
geom_col(fill="blue")+
labs(title="Media delle vendite per città", x="Città", y="Vendite medie")

# Procediamo "condizionando" per anno
year_summary <- ds %>%
group_by(year) %>%
summarise(
mean_sales = mean(sales),
sd_sales = sd(sales),
mean_volume = mean(volume),
sd_volume = sd(volume),
mean_median_price = mean(median_price),
sd_median_price = sd(median_price),
mean_listings = mean(listings),
sd_listings = sd(listings)
)
year_summary
## # A tibble: 5 × 9
## year mean_sales sd_sales mean_volume sd_volume mean_median_price
## <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2010 169. 60.5 25.7 10.8 130192.
## 2 2011 164. 63.9 25.2 12.2 127854.
## 3 2012 186. 70.9 29.3 14.5 130077.
## 4 2013 212. 84.0 35.2 17.9 135723.
## 5 2014 231. 95.5 39.8 21.2 139481.
## # ℹ 3 more variables: sd_median_price <dbl>, mean_listings <dbl>,
## # sd_listings <dbl>
# L'anno con il valore medio di vendite maggiore è stato il 2014.
# In generale, la media di vendite presenta un andamento crescente rispetto al passare degli anni. Dunque il mercato immobiliare del Texas risulta essere in una fase espansiva.
ggplot(year_summary, aes(x=year, y=mean_sales))+
geom_line(color="orange", size=1.5)+
geom_point(color="red")+
labs(title="Trend delle vendite medie per anno", x="Anno", y="vendite medie")
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

# Concludiamo "condizionando" per mese
month_summary <- ds %>%
group_by(month) %>%
summarise(
mean_sales = mean(sales),
sd_sales = sd(sales),
mean_volume = mean(volume),
sd_volume = sd(volume),
mean_median_price = mean(median_price),
sd_median_price = sd(median_price),
mean_listings = mean(listings),
sd_listings = sd(listings)
)
month_summary
## # A tibble: 12 × 9
## month mean_sales sd_sales mean_volume sd_volume mean_median_price
## <fct> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Jan 127. 43.4 19.0 8.37 124250
## 2 Feb 141. 51.1 21.7 10.1 130075
## 3 Mar 189. 59.2 29.4 12.0 127415
## 4 Apr 212. 65.4 33.3 14.5 131490
## 5 May 239. 83.1 39.7 19.0 134485
## 6 Jun 244. 95.0 41.3 21.1 137620
## 7 Jul 236. 96.3 39.1 21.4 134750
## 8 Aug 231. 79.2 38.0 18.0 136675
## 9 Sep 182. 72.5 29.6 15.2 134040
## 10 Oct 180. 75.0 29.1 15.1 133480
## 11 Nov 157. 55.5 24.8 11.2 134305
## 12 Dec 169. 60.7 27.1 12.6 133400
## # ℹ 3 more variables: sd_median_price <dbl>, mean_listings <dbl>,
## # sd_listings <dbl>
# I mesi che vanno da Maggio ad Agosto non solo presentano le vendite medie più alte ma bensì anche le dev. standard maggiori.
# Ciò indica che la stagionalità non è perfettamente regolare per ciascun anno : in alcuni anni il picco estivo è stato meno marcato rispetto agli altri.
# Nonostante ciò, traspare una certa stagionalità, ossia le vendite sono maggoori da Maggio ad Agosto per poi calare.
ggplot(month_summary, aes(x=month, y=mean_sales))+
geom_col(fill="red")+
labs(title="Media delle vendite per mese", x="Mese", y="Vendite medie")

### 8. CREAZIONE DI VISUALIZZAZIONI CON GGPLOT2
# Vediamo alcuni grafici personalizzati.
# Iniziamo con un boxplot per confrontare la distribuzione del prezzo mediano (median_price) tra le città.
ggplot(ds, aes(x=city, y=median_price))+
geom_boxplot(fill="lightgreen", outlier.color="orange")+
coord_flip()+
labs(title="Distribuzione del prezzo mediano per città", x="Città", y="Prezzo mediano di vendita ($)")

# Alcune città, come Bryan_College Station e Tyler, presentano prezzi medi più alti e distribuzioni abbastanza compatte.
# Discorso diverso per Wichita Falls che presenta il prezzo medio di vendita più basso e la distribuzione più ampia.
# Osserviamo, ora, il boxplot del volume per città e per anno
ggplot(ds, aes(x=city, y=volume))+
geom_boxplot(fill="lightblue", outlier.color="red")+
facet_wrap(~ year, ncol=3)+
theme(axis.text.x = element_text(angle=75, hjust=1))+
labs(title="Distribuzione del volume delle vendite per Città ed Anno", x="Città", y="Volume (milioni di dollari)")

# Confrontando il volume di vendite per anno e città, si osserva che per ogni anno l'ordinamento delle città in base al valore medio rimane pressoché invariato.
# Dunque per ciascuna città, al variare dell'anno, il valore centrale (del volume) non subisce stravolgimenti.
# La distribuzione più ampia, per ogni anno (eccetto il 2011), risulta essere quella di Bryan-College Station.
# Pertanto, quello di Bryan-College Station, risulta essere il mercato più instabile e presenta la maggiore variabilità.
# A seguire, per ampiezza, vi è la distribuzione di Tyler.
# Maggiore è l'ampiezza del boxplot e maggiore è la dispersione dei volumi, indice di un mercato meno prevedibile e più eterogeneo.
# Vediamo ora un grafico a barre sovrapposte per confrontare il totale delle vendite nei vari mesi, pur sempre considerando le città.
ggplot(ds, aes(x=month, y=sales, fill=city))+
geom_bar(stat="identity")+
labs(title="Vendite mensili per città", x="Mese", y="Vendite")

# Si osserva che, ad eccezione di Wichita Falls, tutte le altre città vedono il picco di vendite nel mese di Giugno (più in generale nella stagione estiva).
# Adesso, facciamo lo stesso grafico a barre ma questa volta normalizzandolo. Il tutto per avere una percezione più limpida.
ggplot(ds, aes(x=month, y=sales, fill=city))+
geom_bar(stat="identity", position="fill")+
facet_wrap(~ year, ncol=2)+
theme(axis.text.x = element_text(angle=75, hjust=1))+
labs(title="Distribuzione percentuale delle vendite per mese e città", x="Mese", y="Percentuale")

# Si nota che, per ogni mese, le vendite mensili sono composte per oltre il 50% da vendite sulle città di Bryant-College Station e Tyler. A seguire, per ordine percentuale decrescente vi sono Beaumont e Wichita Falls.
# In generale, il mercato (immobiliare sul Texas) risulta essere dominato da Bryant-College Station. Per i mesi di Maggio, Giugno, Luglio tale dominio viene condiviso con Tyler.
# In ultimo osserviamo l'andamento, nel tempo, delle vendite.
# Per farlo devo prima creare una variabile che mi indichi mese ed anno di riferimento.
ds$month_num <- match(ds$month, c("Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"))
ds$year_month <- as.Date(paste(ds$year, ds$month_num, "01", sep="-"), format="%Y-%m-%d")
ggplot(ds, aes(x=year_month, y=sales, color=city)) +
geom_line(size=1) +
geom_point(size=1) +
labs(title="Andamento temporale delle vendite immobiliari per città",
x="Tempo", y="Vendite") +
theme_minimal() +
theme(axis.text.x = element_text(angle=90, hjust=1))

# L'andamento vede picchi più "marcati" (sia positivi che negativi) per le città di Tyler e Bryan-College Station.
# Per le altre due l'andamento risulta essere più regolare.
# In generale, per ogni città eccetto Wichita Falls, si osserva una crescita in termini di valori assoluti.
# Dunque il mercato è in crescita con determinate cadenze stagionali.