Questa analisi esaminerà le tendenze del mercato immobiliare nello stato del Texas, sfruttando i dati storici relativi alle vendite di immobili, con l’obiettivo di fornire insight statistici e visivi che supportino le decisioni strategiche di vendita e ottimizzazione delle inserzioni immobiliari dell’azienda Texas Realty Insights.

Innanzitutto, importiamo il dataset e visualizziamone la struttura.

realestate_texas <- read.csv("realestate_texas.csv", sep=",")
str(realestate_texas)
## 'data.frame':    240 obs. of  8 variables:
##  $ city            : chr  "Beaumont" "Beaumont" "Beaumont" "Beaumont" ...
##  $ year            : int  2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 ...
##  $ month           : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ sales           : int  83 108 182 200 202 189 164 174 124 150 ...
##  $ volume          : num  14.2 17.7 28.7 26.8 28.8 ...
##  $ median_price    : num  163800 138200 122400 123200 123100 ...
##  $ listings        : int  1533 1586 1689 1708 1771 1803 1857 1830 1829 1779 ...
##  $ months_inventory: num  9.5 10 10.6 10.6 10.9 11.1 11.7 11.6 11.7 11.5 ...

1. Analisi delle variabili

Il dataset è costituito da 240 osservazioni con le seguenti 8 variabili.

Definiamo la variabile N, che descriverà la numerosità del campione.

N <- dim(realestate_texas)[1]

2. Indici di posizione, variabilità e forma

attach(realestate_texas)

Variabile city

Indici di posizione

Essendo una variabile qualitativa su scala nominale, la moda è l’unico indice di posizione che è possibile ricavare.

table(city)
## city
##              Beaumont Bryan-College Station                 Tyler 
##                    60                    60                    60 
##         Wichita Falls 
##                    60

La variabile risulta essere quadrimodale, in quanto le modalità in cui si presenta sono quattro, e ciascuna di esse presenta 60 osservazioni. In altre parole, nel dataset sono prese in esame quattro diverse città, e ciascuna di esse è ugualmente rappresentata.

Ora definiamo la distribuzione di frequenze assolute e relative della variabile.

n_city <- table(city)
f_city <- n_city/N

freq_distr_city <- cbind(n_city, f_city)
freq_distr_city
##                       n_city f_city
## Beaumont                  60   0.25
## Bryan-College Station     60   0.25
## Tyler                     60   0.25
## Wichita Falls             60   0.25

Indici di variabilità

Per le variabili qualitative può essere calcolato l’indice di eterogeneità di Gini, il quale misura la propensione di una variabile ad assumere le sue diverse modalità.

gini.index <- function(x){
  ni = table(x)
  fi = ni/length(x)
  fi2 = fi^2
  J = length(table(x))
  
  gini = 1-sum(fi2)
  gini.normalizzato = gini/((J-1)/J)
  
  return(gini.normalizzato)
}

gini.index(city)
## [1] 1

Coerentemente con quanto rilevato trovando la moda di questa variabile, essendo l’indice pari a 1 significa che l’eterogeneità è massima. In altre parole, le osservazioni sono equamente distribuite tra le modalità della variabile.

Variabile year

Indici di posizione

Essendo anche questa una variabile qualitativa, l’unico indice di posizione che è possibile ricavare è la moda.

table(year)
## year
## 2010 2011 2012 2013 2014 
##   48   48   48   48   48

La variabile year risulta essere pentamodale, in quanto si presenta in cinque modalità con 48 osservazioni ciascuna. Nello specifico, l’intervallo temporale osservato nel dataset è di cinque anni, dal 2010 al 2014.

Anche per questa variabile, definiamo la distribuzione di frequenze. Essendo year una variabile qualitativa su scala ordinale, in questo caso possiamo definire anche le frequenze cumulate e le frequenze relative cumulate.

n_year <- table(year)
f_year <- n_year/N
N_year <- cumsum(n_year)
F_year <- N_year/N 

freq_distr_year <- cbind(n_year, f_year, N_year, F_year)
freq_distr_year
##      n_year f_year N_year F_year
## 2010     48    0.2     48    0.2
## 2011     48    0.2     96    0.4
## 2012     48    0.2    144    0.6
## 2013     48    0.2    192    0.8
## 2014     48    0.2    240    1.0

Indici di variabilità

Anche per questa variabile, calcoliamo l’indice di eterogeneità di Gini. Avendo precedentemente rilevato che per ciascuna modalità sono presenti 48 osservazioni, l’indice di eterogeneità sarà pari a 1.

gini.index(year)
## [1] 1

Variabile month

Ora analizziamo la variabile month, anch’essa di tipo qualitativo su scala ordinale.

Indici di posizione

table(month)
## month
##  1  2  3  4  5  6  7  8  9 10 11 12 
## 20 20 20 20 20 20 20 20 20 20 20 20

Anche nel caso di questa variabile, le osservazioni sono equamente distribuite tra le 12 modalità in cui la variabile si presenta. Tutti i mesi dell’anno, quindi, sono presenti in egual misura.

Ora definiamo la distribuzione di frequenze.

n_month <- table(month)
f_month <- n_month/N

freq_distr_month <- cbind(n_month, f_month)
freq_distr_month
##    n_month    f_month
## 1       20 0.08333333
## 2       20 0.08333333
## 3       20 0.08333333
## 4       20 0.08333333
## 5       20 0.08333333
## 6       20 0.08333333
## 7       20 0.08333333
## 8       20 0.08333333
## 9       20 0.08333333
## 10      20 0.08333333
## 11      20 0.08333333
## 12      20 0.08333333

Indici di variabilità

Anche per questa variabile, calcoliamo l’indice di eterogeneità di Gini. Avendo precedentemente rilevato che per ciascuna modalità sono presenti 20 osservazioni, l’indice di eterogeneità sarà pari a 1.

gini.index(month)
## [1] 1

Ora passiamo alle variabili quantitative del dataset. Per ciascuna di esse, ricaviamo i principali indici di posizione, variabilità e forma.

Variabile sales

Indici di posizione

Innanzitutto, utilizziamo la funzione summary() per ricavare massimo e minimo, primo e terzo quartile, media aritmetica e mediana. Dopodiché, troviamo anche la moda.

summary(sales)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##    79.0   127.0   175.5   192.3   247.0   423.0
names(table(sales))[which.max(table(sales))]
## [1] "124"

Poiché la media è maggiore della mediana, la quale a sua volta è maggiore della moda, possiamo già affermare che la distribuzione di questa variabile è asimmetrica positiva.

Indici di variabilità

Calcoliamo innanzitutto l’intervallo di variazione, sottraendo il valore minimo della distribuzione al valore massimo.

max(sales)-min(sales)
## [1] 344

Ora calcoliamo invece la differenza interquartile, ovvero l’intervallo di variazione del corpo centrale della distribuzione.

IQR(sales)
## [1] 120

Ora quantifichiamo la dispersione dei dati attorno alla media, calcolando la varianza e la deviazione standard.

var(sales)
## [1] 6344.3
sd(sales)
## [1] 79.65111

Essendo la varianza e la deviazione standard degli indici assoluti, calcoliamo anche il coefficiente di variazione, che è invece una misura relativa e, quindi, può essere più utile per confrontare la variabilità di questa distribuzione con quella delle altre variabili del dataset.

Il coefficiente di variazione può essere un indice problematico in caso di valori negativi nella distribuzione o zero convenzionali nella scala di misura, ma con le variabili di questo dataset non si presenta nessuna delle due casistiche.

CV <- function(x){
  return(sd(x)/mean(x)*100)
}

CV(sales)
## [1] 41.42203

Indici di forma

Ora verifichiamo se la distribuzione della variabile sales sia effettivamente asimmetrica positiva calcolando l’indice di asimmetria di Fisher.

skewness(sales)
## [1] 0.718104

Il valore positivo dell’indice di asimmetria conferma che la distribuzione della variabile sales è asimmetrica positiva. In altre parole, la maggior parte dei dati è concentrata sui valori bassi a sinistra, con una coda lunga che si estende verso i valori alti a destra.

Ora invece calcoliamo il coefficiente di curtosi, per verificare il grado di schiacciamento/allungamento della forma della distribuzione rispetto alla normale.

kurtosis(sales)-3
## [1] -0.3131764

Essendo il valore negativo, la distribuzione è platicurtica, ovvero con una forma più appiattita rispetto alla distribuzione normale.

Ora procediamo a calcolare questi indici di posizione, variabilità e forma anche per le altre variabili quantitative.

Variabile volume

Indici di posizione

summary(volume)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   8.166  17.660  27.062  31.005  40.893  83.547
names(table(volume))[which.max(table(volume))]
## [1] "14.003"

Poiché la media è maggiore della mediana, la quale a sua volta è maggiore della moda, anche per questa variabile possiamo già affermare che la distribuzione è asimmetrica positiva.

Indici di variabilità

max(volume)-min(volume)
## [1] 75.381
IQR(volume)
## [1] 23.2335
var(volume)
## [1] 277.2707
sd(volume)
## [1] 16.65145
CV(volume)
## [1] 53.70536

Il coefficiente di variazione della variabile volume è del 53,7%, mentre per la variabile sales il valore era del 41,4%. Ciò significa, quindi, che la variabile volume presenta una maggiore variabilità.

Indici di forma

skewness(volume)
## [1] 0.884742

Anche in questo caso, essendo il valore dell’indice di asimmetria di Fisher maggiore di zero, la distribuzione si conferma essere asimmetrica positiva. Con un valore di 0,89, la variabile volume risulta essere maggiormente asimmetrica rispetto alla variabile sales, che invece presenta un indice di asimmetria di 0,72.

kurtosis(volume)-3
## [1] 0.176987

Essendo il valore maggiore di zero, la distribuzione della variabile volume è leptocurtica, ovvero con una forma più allungata rispetto alla normale.

Variabile median_price

Indici di posizione

summary(median_price)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   73800  117300  134500  132665  150050  180000
names(table(median_price))[which.max(table(median_price))]
## [1] "130000"

Poiché la media è minore della mediana, possiamo ipotizzare che la distribuzione sia asimmetrica negativa. Ciò significa che la maggior parte dei dati è concentrata sui valori alti, quindi a destra della distribuzione, con una coda lunga che si estende verso i valori bassi, quindi a sinistra. Questo aspetto sarà verificato quando calcoleremo l’indice di asimmetria di Fisher.

Indici di variabilità

max(median_price)-min(median_price)
## [1] 106200
IQR(median_price)
## [1] 32750
var(median_price)
## [1] 513572983
sd(median_price)
## [1] 22662.15
CV(median_price)
## [1] 17.08218

Il coefficiente di variazione della variabile median_price, quindi, è del 17,1%, quindi questa variabile presenta una variabilità decisamente minore rispetto a sales e volume.

Indici di forma

skewness(median_price)
## [1] -0.3645529

In questo caso, essendo il valore dell’indice di asimmetria di Fisher minore di zero, possiamo confermare che la distribuzione è asimmetrica negativa.

kurtosis(median_price)-3
## [1] -0.6229618

Come nel caso della variabile sales, essendo il valore dell’indice di curtosi negativo, la distribuzione è platicurtica, ovvero con una forma più appiattita rispetto alla distribuzione normale. Tuttavia, con un valore di -0,62, questa distribuzione è nettamente più appiattita rispetto alla distribuzione della variabile sales, che invece presenta un indice di curtosi di -0,31.

Variabile listings

Indici di posizione

summary(listings)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##     743    1026    1618    1738    2056    3296
names(table(listings))[which.max(table(listings))]
## [1] "1581"

Essendo la media maggiore della mediana, la quale a sua volta è maggiore della moda, possiamo già ipotizzare che la distribuzione sia asimmetrica positiva.

Indici di variabilità

max(listings)-min(listings)
## [1] 2553
IQR(listings)
## [1] 1029.5
var(listings)
## [1] 566569
sd(listings)
## [1] 752.7078
CV(listings)
## [1] 43.30833

Con un coefficiente di variazione del 43,3%, la variabile listings presenta una variabilità molto simile alla variabile sales.

Indici di forma

skewness(listings)
## [1] 0.6494982

Con un indice di asimmetria maggiore di zero, possiamo confermare che la distribuzione della variabile listings è asimmetrica positiva.

kurtosis(listings)-3
## [1] -0.79179

Con un indice di curtosi minore di zero, la distribuzione della variabile listings è platicurtica. Pertanto, la forma è più appiattita rispetto a quella della distribuzione normale.

Variabile months_inventory

Indici di posizione

summary(months_inventory)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   3.400   7.800   8.950   9.193  10.950  14.900
names(table(months_inventory))[which.max(table(months_inventory))]
## [1] "8.1"

Essendo la media maggiore della mediana, la quale a sua volta è maggiore della moda, la distribuzione è asimmetrica positiva. Ad ogni modo, lo andremo poi a verificare calcolando l’indice di asimmetria.

Indici di variabilità

max(months_inventory)-min(months_inventory)
## [1] 11.5
IQR(months_inventory)
## [1] 3.15
var(months_inventory)
## [1] 5.306889
sd(months_inventory)
## [1] 2.303669
CV(months_inventory)
## [1] 25.06031

Il coefficiente di variazione è del 25,1%, quindi la distribuzione di questa variabile presenta una variabilità maggiore di median_price, ma minore di sales, volume e listings.

Indici di forma

skewness(months_inventory)
## [1] 0.04097527

L’indice di asimmetria di Fisher per questa variabile è maggiore di zero, quindi possiamo confermare che la distribuzione è asimmetrica positiva. Tuttavia, vale la pena notare come l’indice sia molto vicino allo zero e come, quindi, la distribuzione di questa variabile sia molto meno asimmetrica rispetto alle altre.

kurtosis(months_inventory)-3
## [1] -0.1744475

L’indice di curtosi per questa variabile è minore di zero, quindi la distribuzione è platicurtica, ovvero presenta una forma più appiattita rispetto alla distribuzione normale.

3. Identificazione delle variabili con maggiore variabilità e asimmetria

Confrontiamo la variabilità della variabili quantitative del dataset, riepilogando di seguito il coefficiente di variazione di ciascuna:

La variabile che presenta la più alta variabilità risulta essere volume, ovvero il valore totale delle vendite. L’alta variabilità è indice di elevata dispersione dei dati all’interno della distribuzione e, di conseguenza, poca uniformità all’interno del campione. Essendo i dati molto dispersi attorno al valore medio, esso risulta quindi poco informativo sul comportamento della variabile.

Al contrario, la variabile che presenta la variabilità più bassa è median_price, ovvero il prezzo mediano di vendita. Ciò significa che le osservazioni del dataset sono concentrate attorno al valore medio e, pertanto, quest’ultimo è abbastanza rappresentativo del fenomeno.

Ora confrontiamo invece l’asimmetria delle distribuzioni, prendendo come riferimento l’indice di asimmetria di Fisher per ciascuna variabile quantitativa:

Possiamo innanzitutto notare che quattro distribuzioni su cinque sono asimmetriche positive, mentre solamente una è asimmetrica negativa.

La variabile con la distribuzione maggiormente asimmetrica risulta essere volume, che è asimmetrica positiva e, pertanto, presenta la maggior parte dei dati con valori bassi. In altre parole, la maggior parte delle osservazioni del dataset presenta un valore basso relativo al valore totale delle vendite.

La variabile con la distribuzione meno asimmetrica, invece, è months_inventory, ovvero il numero di mesi necessari per vendere tutte le inserzioni correnti. Infatti, questa distribuzione è asimmetrica positiva, ma l’indice di asimmetria è molto basso, quindi la distribuzione presenta maggior equilibrio tra valori bassi e valori alti.

Ora confrontiamo la curtosi delle distribuzioni, prendendo come riferimento il relativo indice per ciascuna variabile:

La prima cosa che notiamo è che quattro distribuzioni su cinque sono platicurtiche, quindi con una forma più appiattita, mentre solamente una è leptocurtica.

La variabile con la distribuzione più appiattita rispetto alla normale è listings, ovvero il numero totale di annunci attivi. Ciò significa che i dati sono più uniformemente distribuiti e presentano una concentrazione minore attorno al valore medio.

Al contrario, la variabile con la distribuzione più allungata rispetto alla normale è volume. Questo indica che una maggiore concentrazione di dati attorno alla media, nonché una minore probabilità di valori estremi, sia a destra che a sinistra. Pertanto, la media di questa variabile risulta essere più rappresentativa, rispetto alla media di una distribuzione platicurtica.

4. Creazione di classi per una variabile quantitativa

Poiché volume è la variabile con la variabilità più alta, e quindi con la maggior dispersione di dati attorno al valore medio, la suddividiamo in classi per poi costruirne la distribuzione di frequenze e rappresentarla con un grafico a barre. Infine, ne calcoleremo l’indice di eterogeneità di Gini.

Innanzitutto, ricaviamo il minimo e il massimo della distribuzione, per trovarne una suddivisione logica.

range(volume)
## [1]  8.166 83.547

Utilizziamo la funzione cut() per creare le classi, defininendole in una nuova variabile.

freq_distr_volume_cl <- cut(volume, breaks=c(0, 20, 40, 60, 80, 100))

Ora costruiamo la distribuzione di frequenze della variabile volume suddivisa in classi.

n_volume <- table(freq_distr_volume_cl)
f_volume <- n_volume/N
N_volume <- cumsum(n_volume)
F_volume <- N_volume/N

cbind(n_volume, f_volume, N_volume, F_volume)
##          n_volume    f_volume N_volume  F_volume
## (0,20]         78 0.325000000       78 0.3250000
## (20,40]        99 0.412500000      177 0.7375000
## (40,60]        44 0.183333333      221 0.9208333
## (60,80]        17 0.070833333      238 0.9916667
## (80,100]        2 0.008333333      240 1.0000000

Ora rappresentiamo la distribuzione di frequenze relative con un grafico a barre.

barplot(f_volume,
        main = "Distribuzione in classi del valore totale delle vendite",
        xlab = "Classi del valore totale delle vendite (mln $)",
        ylab = "Frequenze relative",
        col = "#453947",
        names.arg = rownames(freq_distr_volume_cl))

Da questa rappresentazione grafica risulta ancora più evidente l’asimmetria positiva della distribuzione, in quanto le prime due classi sono quelle contenenti la maggior parte delle osservazioni.

Ora calcoliamo l’indice di eterogeneità di Gini.

gini.index(freq_distr_volume_cl)
## [1] 0.856901

Poiché l’indice può assumere valori da 0 (eterogeneità nulla) a 1 (eterogeneità massima), questo valore pari a 0,86 significa un’elevata eterogeneità delle unità statistiche, le quali sono quindi abbastanza distribuite tra le modalità della variabile.

5. Calcolo della probabilità

Consideriamo la variabile city e calcoliamo la probabilità che, prendendo una riga a caso del dataset, riporti la città “Beaumont”. Per farlo, possiamo utilizzare il metodo classico e il metodo frequentista.

L’accezione classica prevede che la probabilità sia il numero di casi favorevoli sul numero di casi possibili. In questo caso, quindi, il numero di casi favorevoli è il numero di casi in cui la città sia Beaumont, mentre il numero di casi possibili è il totale delle osservazioni del dataset. Pertanto, la probabilità sarà la seguente:

table(city)["Beaumont"]/N
## Beaumont 
##     0.25

L’accezione frequentista, invece, prevede che, per un infinito numero di prove, la probabilità osservata converge al suo vero valore.

Creiamo, quindi, un vettore contenente le modalità della variabile city, per poi definire la variabile random_city come il risultato di un numero di estrazioni casuali.

cities_list <- unique(city)
random_city <- sample(cities_list, 1000000, replace = T)

Ora definiamo la funzione di probabilità con una rappresentazione grafica.

ggplot()+
  geom_bar(aes(x = random_city, 
               y = after_stat(count/sum(count))),
           stat = "count",
           col = "black",
           fill = "#476F84")+
  scale_y_continuous(labels = scales::percent,
                     limits = c(0, 0.3),
                     breaks = seq(0, 0.3, by = 0.05))+
  labs(title="Funzione di probabilità della variabile city",
       x="Città",
       y="Probabilità (%)")+
  theme_minimal()

La funzione di probabilità conferma che, anche secondo l’accezione frequentista, la probabilità che una riga del dataset presa a caso riporti la città “Beaumont” è del 25%. Come si può vedere, questa funzione di probabilità è uniforme, poiché tutti gli esiti hanno la stessa possibilità di verificarsi. In altre parole, ogni città ha il 25% di possibilità di essere estratta a caso.

Ora consideriamo la variabile month e calcoliamo la probabilità che, prendendo una riga a caso del dataset, riporti il mese di luglio. I casi favorevoli, quindi, sono quelli in cui la modalità della variabile è “7”.

table(month)["7"]/N
##          7 
## 0.08333333

La probabilità che una riga del dataset presa a caso riporti il mese di luglio è dell’8,3%. Applichiamo anche il metodo frequentista.

months_list <- unique(month)
random_month <- sample(months_list, 1000000, replace = T)

ggplot()+
  geom_bar(aes(x = random_month, 
               y = after_stat(count/sum(count))),
           stat = "count",
           col = "black",
           fill = "#476F84")+
  scale_x_continuous(limits = c(0.5, 12.5),
                     breaks = seq(1, 12, by = 1))+
  scale_y_continuous(labels = scales::percent,
                     limits = c(0, 0.1),
                     breaks = seq(0, 0.1, by = 0.01))+
  labs(title="Funzione di probabilità della variabile month",
       x="Mese",
       y="Probabilità (%)")+
  theme_minimal()

Come si evince dal grafico, eseguendo un numero di estrazioni casuali sufficientemente alto, la probabilità converge al valore calcolato tramite il metodo classico. Anche in questo caso, notiamo come la funzione di probabilità sia uniforme, in quanto tutti gli esiti convergono allo stesso valore di probabilità.

Ora, invece, calcoliamo la probabilità che una riga presa a caso dal dataset riporti il mese di dicembre 2012. In questo caso dovranno essere considerate due variabili, ovvero year e month, e la probabilità sarà data dal prodotto delle due singole probabilità.

(table(year)["2012"]/N)*(table(month)["12"]/N)
##       2012 
## 0.01666667

Pertanto, la probabilità che una riga estratta a caso dal dataset riporti il mese di dicembre dell’anno 2012 è dell’1,67%.

Definiamo la variabile mm_yy, che conterrà le informazioni su mese e anno concatenate.

mm_yy <- paste(month, year, sep = "-")
mm_yy_date <- as.Date(paste0("01-", mm_yy), format = "%d-%m-%Y")

Ora costruiamo la funzione di probabilità secondo l’accezione frequentista.

mm_yy_list <- unique(mm_yy_date)
random_mm_yy <- sample(mm_yy_list, 1000000, replace = T)

ggplot()+
  geom_bar(aes(x = random_mm_yy, 
               y = after_stat(count/sum(count))),
           stat = "count",
           col = "black",
           fill = "#476F84")+
  scale_x_date(breaks = seq(as.Date("2010-01-01"), as.Date("2014-01-01"), by = "1 year"),
               date_labels = "%Y")+
  scale_y_continuous(labels = scales::percent,
                     limits = c(0, 0.025),
                     breaks = seq(0, 0.025, by = 0.005))+
  labs(title="Funzione di probabilità di uno specifico mese ed anno",
       x="Mese",
       y="Probabilità (%)")+
  theme_minimal()

6. Creazione di nuove variabili

Aggiungiamo una colonna al dataset, che riporti il prezzo medio degli immobili. Per calcolarlo, dividiamo volume (valore totale delle vendite in milioni di dollari) per sales (numero totale di vendite).

realestate_texas$avg_price <- (volume*1000000)/sales
attach(realestate_texas)

summary(avg_price)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   97010  132939  156588  154320  173915  213234
summary(median_price)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   73800  117300  134500  132665  150050  180000

Confrontando i valori minimi e massimi del prezzo medio con quelli del prezzo mediano, possiamo vedere come la media sia maggiormente influenzata dai valori estremi della distribuzione. Infatti, il valore minimo del prezzo medio è molto più basso rispetto a quello del prezzo mediano, mentre il valore massimo è molto più alto.

Ora aggiungiamo un’ulteriore colonna al dataset, che misuri l’efficacia degli annunci di vendita. I valori della nuova variabile listing_efficiency saranno dati dal rapporto fra sales (numero totale di vendite) e listings (numero totale di annunci attivi). Dopo aver definito la nuova variabile, ordiniamo le righe del dataset per questa variabile in ordine decrescente, in modo da vedere chiaramente in quali casi gli annunci sono stati maggiormente efficaci.

realestate_texas %>%
  mutate(listing_efficiency = sales/listings) %>%
  select(city, year, sales, listings, listing_efficiency) %>%
  arrange(desc(listing_efficiency)) %>%
  slice_head(n = 15)
##                     city year sales listings listing_efficiency
## 1  Bryan-College Station 2014   403     1041          0.3871278
## 2  Bryan-College Station 2014   377     1152          0.3272569
## 3  Bryan-College Station 2014   298     1016          0.2933071
## 4  Bryan-College Station 2014   353     1212          0.2912541
## 5  Bryan-College Station 2013   402     1385          0.2902527
## 6  Bryan-College Station 2013   357     1462          0.2441860
## 7  Bryan-College Station 2014   303     1271          0.2383950
## 8  Bryan-College Station 2013   328     1385          0.2368231
## 9  Bryan-College Station 2014   200      882          0.2267574
## 10 Bryan-College Station 2014   275     1261          0.2180809
## 11 Bryan-College Station 2013   341     1581          0.2156863
## 12 Bryan-College Station 2014   218     1031          0.2114452
## 13 Bryan-College Station 2014   204     1022          0.1996086
## 14 Bryan-College Station 2012   296     1518          0.1949934
## 15         Wichita Falls 2010   167      904          0.1847345

Ciò che si può notare è che gli annunci risultano maggiormente efficaci nella città di Bryan-College Station, in particolare negli anni 2013 e 2014. Al contrario, gli anni in cui gli annunci risultano meno efficaci sono il 2010 e il 2011, in particolar modo nella città di Tyler. Nelle ultime righe, infatti, a fronte di un numero più alto di annunci rispetto alle prime righe, si registrano meno della metà delle vendite.

7. Analisi condizionata

Ora analizziamo l’andamento del numero e valore delle vendite e del prezzo degli immobili al variare delle modalità delle variabili qualitative city, year e month, con lo scopo di verificare l’esistenza di eventuali trend. Nello specifico, creiamo una tabella riassuntiva che permetta di confrontare le variabili quantitative sales, volume e median_price in base alla città, all’anno e al mese. Dopodiché, rappresentiamo graficamente i risultati.

Analisi condizionata per città

summary_by_city <- realestate_texas %>%
  group_by(city) %>%
  summarise(media_sales = mean(sales),
            dev_st_sales = sd(sales),
            media_median_price = mean(median_price),
            dev_st_median_price = sd(median_price))

summary_by_city
## # A tibble: 4 × 5
##   city           media_sales dev_st_sales media_median_price dev_st_median_price
##   <chr>                <dbl>        <dbl>              <dbl>               <dbl>
## 1 Beaumont              177.         41.5            129988.              10105.
## 2 Bryan-College…        206.         85.0            157488.               8852.
## 3 Tyler                 270.         62.0            141442.               9337.
## 4 Wichita Falls         116.         22.2            101743.              11320.

Rappresentiamo graficamente la media e la deviazione standard del numero di vendite condizionate per città.

ggplot(summary_by_city, aes(x = reorder(city, media_sales),
                            y = media_sales))+
  geom_col(col = "black",
           fill = "#453947")+
  geom_errorbar(aes(ymin = media_sales - dev_st_sales, 
                    ymax = media_sales + dev_st_sales), 
                width = 0.3,
                color = "black")+
  labs(title = "Media delle vendite per città, con dev. standard",
       x = "Città",
       y = "Numero medio di vendite")+
  theme_minimal()

Dal grafico si evince che la città con il maggior numero di vendite di immmobili in media è Tyler, mentre la città con il minor numero di vendite in media è Wichita Falls. Le linee nere mostrano la deviazione standard, da cui si può affermare che la città Bryan-College Station è quella che presenta la maggior variabilità nel numero di vendite. Ciò significa un’elevata fluttuazione nelle vendite, e quindi più volatilità nel mercato.

Ora rappresentiamo graficamente la media e la deviazione standard del prezzo mediano di vendita, sempre condizionato per città.

ggplot(summary_by_city, aes(x = reorder(city, media_median_price),
                            y = media_median_price))+
  geom_col(col = "black",
           fill = "#476F84")+
  geom_errorbar(aes(ymin = media_median_price - dev_st_median_price, 
                    ymax = media_median_price + dev_st_median_price), 
                width = 0.3,
                color = "black")+
  scale_y_continuous(labels = label_number(big.mark = ".", decimal.mark = ","))+
  labs(title = "Media del prezzo mediano di vendita per città, con dev. standard",
       x = "Città",
       y = "Media del prezzo mediano ($)")+
  theme_minimal()

Il grafico mostra che la città nella quale i prezzi degli immobili sono mediamente più alti è Bryan-College Station, mentre la città con i prezzi mediamente più bassi è Wichita Falls. Le linee nere sono abbastanza corte per tutte e quattro le città, indicando una ridotta volatilità dei prezzi in tutte le località.

Analisi condizionata per anno

summary_by_year <- realestate_texas %>%
  group_by(year) %>%
  summarise(media_sales = mean(sales),
            dev_st_sales = sd(sales),
            media_median_price = mean(median_price),
            dev_st_median_price = sd(median_price))

summary_by_year
## # A tibble: 5 × 5
##    year media_sales dev_st_sales media_median_price dev_st_median_price
##   <int>       <dbl>        <dbl>              <dbl>               <dbl>
## 1  2010        169.         60.5            130192.              21822.
## 2  2011        164.         63.9            127854.              21318.
## 3  2012        186.         70.9            130077.              21432.
## 4  2013        212.         84.0            135723.              21708.
## 5  2014        231.         95.5            139481.              25625.

Rappresentiamo graficamente la media e la deviazione standard del numero di vendite condizionate per anno.

ggplot(summary_by_year, aes(x = year,
                            y = media_sales))+
  geom_col(col = "black",
           fill = "#453947")+
  geom_errorbar(aes(ymin = media_sales - dev_st_sales, 
                    ymax = media_sales + dev_st_sales), 
                width = 0.3,
                color = "black")+
  labs(title = "Media delle vendite per anno, con dev. standard",
       x = "Anno", 
       y = "Numero medio di vendite")+
  theme_minimal()

Dalla rappresentazione grafica dei dati si può osservare un leggero calo nelle vendite dal 2010 al 2011, mentre si osserva un trend positivo negli anni successivi. L’anno con il maggior numero di vendite in media, quindi, risulta essere il 2014, seppur con un indice di variabilità molto elevato. Si può notare, infatti, che anche la deviazione standard risulta sempre maggiore dal 2010 al 2014, indicando quindi una minore stabilità e maggiore volatilità del mercato.

Ora rappresentiamo graficamente la media e la deviazione standard del prezzo mediano di vendita, sempre condizionato per anno.

ggplot(summary_by_year, aes(x = year,
                            y = media_median_price))+
  geom_col(col = "black",
           fill = "#476F84")+
  geom_errorbar(aes(ymin = media_median_price - dev_st_median_price, 
                    ymax = media_median_price + dev_st_median_price), 
                width = 0.3,
                color = "black")+
  scale_y_continuous(labels = label_number(big.mark = ".",
                                           decimal.mark = ","))+
  labs(title = "Media del prezzo mediano di vendita per anno, con dev. standard",
       x = "Anno",
       y = "Media del prezzo mediano ($)")+
  theme_minimal()

Il prezzo mediano di vendita non risulta essere particolarmente condizionato dall’anno; si notano infatti delle differenze molto limitate sia tra le barre del grafico (la media), che tra le linee nere (la deviazione standard).

Analisi condizionata per mese

summary_by_month <- realestate_texas %>%
  group_by(month) %>%
  summarise(media_sales = mean(sales),
            dev_st_sales = sd(sales),
            media_median_price = mean(median_price),
            dev_st_median_price = sd(median_price))

summary_by_month
## # A tibble: 12 × 5
##    month media_sales dev_st_sales media_median_price dev_st_median_price
##    <int>       <dbl>        <dbl>              <dbl>               <dbl>
##  1     1        127.         43.4             124250              25151.
##  2     2        141.         51.1             130075              22823.
##  3     3        189.         59.2             127415              23442.
##  4     4        212.         65.4             131490              21458.
##  5     5        239.         83.1             134485              18796.
##  6     6        244.         95.0             137620              19231.
##  7     7        236.         96.3             134750              21945.
##  8     8        231.         79.2             136675              22488.
##  9     9        182.         72.5             134040              24344.
## 10    10        180.         75.0             133480              26358.
## 11    11        157.         55.5             134305              24691.
## 12    12        169.         60.7             133400              22810.

Rappresentiamo graficamente la media e la deviazione standard del numero di vendite condizionate per mese.

ggplot(summary_by_month, aes(x = month,
                             y = media_sales))+
  geom_col(col = "black", fill = "#453947")+
  geom_errorbar(aes(ymin = media_sales - dev_st_sales, 
                    ymax = media_sales + dev_st_sales), 
                width = 0.3,
                color = "black")+
  scale_x_continuous(limits = c(0.5, 12.5),
                     breaks = seq(1, 12, by = 1))+
  labs(title = "Media delle vendite per mese, con dev. standard",
       x = "Mese",
       y = "Numero medio di vendite")+
  theme_minimal()

Considerando il mese, anziché l’anno, si può immediatamente notare come il numero delle vendite sia maggiormente condizionato. In particolare, i mesi in cui si registra il maggior numero di vendite medio sono quelli primaverili ed estivi, quindi da marzo ad agosto. Questi mesi, però, presentano anche un’elevata variabilità, molto maggiore rispetto a quella rilevata nei mesi invernali. Pertanto, nei periodi primaverili ed estivi il mercato risulta essere mediamente più proficuo, ma anche maggiormente instabile.

Ora rappresentiamo graficamente la media e la deviazione standard del prezzo mediano di vendita, sempre condizionato per mese.

ggplot(summary_by_month, aes(x = month,
                             y = media_median_price))+
  geom_col(col = "black",
           fill = "#476F84")+
  geom_errorbar(aes(ymin = media_median_price - dev_st_median_price, 
                    ymax = media_median_price + dev_st_median_price), 
                width = 0.3,
                col = "black")+
  scale_x_continuous(limits = c(0.5, 12.5),
                     breaks = seq(1, 12, by = 1))+
  scale_y_continuous(labels = label_number(big.mark = ".",
                                           decimal.mark = ","))+
  labs(title = "Media del prezzo mediano di vendita per mese, con dev. standard",
       x = "Mese",
       y = "Media del prezzo mediano ($)")+
  theme_minimal()

Il grafico mostra come il prezzo mediano di vendita sia molto meno condizionato dalla variabile month, sia per quanto riguarda la media, che per la deviazione standard. In generale, quindi, il prezzo mediano di vendita rimane stabile tra i vari mesi dell’anno.

8. Creazione di visualizzazioni con ggplot2

Prezzo mediano di vendita per città

palette_acadia_custom <- c("#FED789", "#A4BED5", "#72874E", "#476F84", "#453947")

ggplot(data = realestate_texas, aes(x = city,
                                    y = median_price))+
  geom_boxplot(aes(fill = city))+
  scale_fill_manual(values = palette_acadia_custom)+
  scale_y_continuous(labels = label_number(big.mark = ".",
                                           decimal.mark = ","))+
  labs(title = "Distribuzione del prezzo mediano di vendita per città",
       x = "Città",
       y = "Prezzo mediano di vendita ($)")+
  theme_minimal()+
  theme(legend.position = "none")

Questo grafico conferma che la città con il prezzo mediano di vendita più alto è Bryan-College Station, seguita in ordine da Tyler, Beaumont, e Wichita Falls. Bryan-College Station è anche la città che presenta il più basso range interquartile, indicando una bassa variabilità del corpo centrale dei dati osservati. Wichita Falls, al contrario, è la città che presenta il più alto range interquartile, pertanto il corpo centrale dei dati è maggiormente disperso attorno al valore medio. Un altro aspetto evidenziato dal grafico è la presenza di valori anomali in tre distribuzioni su quattro. In particolare, i valori anomali per le città di Beaumont e Wichita Falls sono molto distanti dal massimo relativo. Ciò significa che, per queste due distribuzioni, è più opportuno utilizzare la mediana come indice di posizione, anziché la media.

Numero di vendite per città

ggplot(data = realestate_texas, aes(x = city,
                                    y = sales))+
  geom_boxplot(aes(fill = city))+
  scale_fill_manual(values = palette_acadia_custom)+
  labs(title = "Distribuzione del numero di vendite per città",
       x = "Città",
       y = "Numero di vendite")+
  theme_minimal()+
  theme(legend.position = "none")

Come rilevato nelle precedenti analisi, questo grafico conferma che la città con il numero di vendite più alto è Tyler, seguita in ordine da Bryan-College Station, Beaumont, e Wichita Falls. La città che presenta il range interquartile più alto è Bryan-College Station (notare che invece, prendendo in esame il prezzo mediano di vendita, presentava il range interquartile più basso), indicando un’alta variabilità nel corpo centrale dei dati osservati. La città di Wichita Falls, invece, che per il prezzo mediano di vendita aveva il range interquartile più alto, nel caso del numero di vendite è la città con minore variabilità nel corpo centrale dei dati. In questo grafico non risultano punti neri, pertanto non sono presenti valori anomali nelle quattro distribuzioni.

Numero di vendite per anno

ggplot(data = realestate_texas, aes(x = factor(year),
                                    y = sales))+
  geom_boxplot(fill = "#A4BED5")+
  labs(title = "Distribuzione del numero di vendite per anno",
       x = "Anno",
       y = "Numero di vendite")+
  theme_minimal()+
  theme(legend.position = "none")

Questo grafico conferma l’andamento positivo del numero di vendite dal 2011 al 2014, in quanto si può osservare l’incremento sia del valore mediano che del range interquartile di anno in anno. Tuttavia, con l’aumento del numero delle vendite negli anni è aumentata anche la variabilità delle osservazioni; infatti, il range interquartile nel 2014 è decisamente maggiore rispetto a quello osservato nel 2011.

Valore totale delle vendite per mese

ggplot(realestate_texas, aes(x = month,
                             y = volume))+
  geom_col(fill = "#023743")+
  scale_x_continuous(limits = c(0.5, 12.5),
                     breaks = seq(1, 12, by = 1))+
  scale_y_continuous(labels = label_number(big.mark = ".",
                                           decimal.mark = ","))+
  labs(title = "Valore totale delle vendite per mese",
       x = "Mese",
       y = "Valore totale delle vendite (mln $)")+
  theme_minimal()

Dal grafico si evince che i mesi con il maggior volume di vendite di osservate sono maggio, giugno, luglio e agosto. I mesi estivi, quindi, risultano essere i più proficui per la vendita degli immobili, mentre i mesi di gennaio e febbraio sono quelli meno redditizi.

Valore totale delle vendite per mese e città

ggplot(data = realestate_texas, aes(x = month,
                                    y = volume,
                                    fill = city))+
  geom_col(position = "stack")+
  scale_fill_manual(values = palette_acadia_custom)+
  scale_x_continuous(limits = c(0.5, 12.5),
                     breaks = seq(1, 12, by = 1))+
  labs(title = "Valore totale delle vendite per mese e città",
       x = "Mese",
       y = "Valore totale delle vendite (mln $)",
       fill = "Città")+
  theme_minimal()+
  theme(legend.position = "bottom")

Questo grafico a barre sovrapposte mostra le stesse barre dell’ultimo grafico, ma con un’informazione in più, ovvero la suddivisione del valore totale delle vendite in un determinato mese per città. Il risultato conferma ciò che abbiamo già osservato in precedenza, ovvero che il maggior numero di vendite si concentra nelle città di Bryan-College Station e Tyler, indipendentemente dal mese.

Ora proviamo a rappresentare gli stessi dati, ma utilizzando un grafico normalizzato.

ggplot(data = realestate_texas, aes(x = month,
                                    y = volume,
                                    fill = city))+
  geom_col(position = "fill")+
  scale_fill_manual(values = palette_acadia_custom)+
  scale_x_continuous(limits = c(0.5, 12.5),
                     breaks = seq(1, 12, by = 1))+
  scale_y_continuous(breaks = seq(0, 1, 0.25))+
  labs(title = "Valore totale delle vendite per mese e città",
       x = "Mese",
       y = "Frequenze assolute",
       fill = "Città")+
  theme_minimal()+
  theme(legend.position = "bottom")

Questo grafico mostra con maggior chiarezza e in maniera più immediata che, indipendentemente dal periodo dell’anno, il valore totale delle vendite per ciascuna città rispetto al totale rimane pressoché invariato, con le città di Bryan-College Station e Tyler che risultano le più redditizie.

Valore totale delle vendite per mese, anno e città

ggplot(data = realestate_texas, aes(x = mm_yy_date,
                                    y = volume,
                                    fill = city))+
  geom_col(position = "fill")+
  scale_fill_manual(values = palette_acadia_custom)+
  scale_x_date(breaks = seq(as.Date("2010-01-01"), as.Date("2014-01-01"), by = "1 year"),
               date_labels = "%Y")+
  scale_y_continuous(breaks = seq(0, 1, 0.25))+
  labs(title = "Valore totale delle vendite per mese, anno e città",
       x = NULL,
       y = "Frequenze assolute",
       fill = "Città")+
  theme_minimal()+
  theme(legend.position = "bottom")

In questo grafico, ogni barra sovrapposta rappresenta il valore totale delle vendite per uno specifico mese tra gennaio 2010 e dicembre 2014, suddiviso per città. Pertanto, questo grafico fornisce un livello di dettaglio ancora maggiore rispetto a quello precedente, in quanto dà la possibilità di vedere l’andamento storico della variabile osservata, ovvero il valore totale delle vendite.

Valore totale delle vendite per città

ggplot(realestate_texas, aes(x = city,
                             y = volume))+
  geom_col(fill = "#023743")+
  scale_y_continuous(labels = label_number(big.mark = ".",
                                           decimal.mark = ","))+
  labs(title = "Valore totale delle vendite per città",
       x = "Città",
       y = "Valore totale delle vendite (mln $)")+
  theme_minimal()

Dal grafico si evince che il maggior volume di vendite osservate si concentra nella città di Tyler, nonostante la città con la distribuzione del prezzo mediano di vendita maggiore sia Bryan-College Station.

Andamento storico delle vendite per città

Per analizzare l’andamento storico di una variabile osservata, uno dei grafici più efficaci è il line chart.

ggplot(realestate_texas, aes(x = mm_yy_date, 
                             y = sales, 
                             col = city, 
                             group = city))+
  geom_line(linewidth = 0.8)+
  geom_point(size = 2)+
  scale_x_date(breaks = seq(as.Date("2010-01-01"), as.Date("2014-01-01"), by = "1 year"),
               date_labels = "%Y")+
  scale_color_manual(values = palette_acadia_custom)+
  labs(title = "Vendite per città nel periodo 2010-2014",
       x = NULL,
       y = "Numero di vendite",
       color = "Città")+
  theme_minimal()+
  theme(legend.position = "bottom")

Il grafico mostra, innanzitutto, dei picchi nel numero di vendite negli anni 2013 e 2014 per le città Bryan-College Station e Tyler, a conferma di quanto rilevato nelle analisi precedenti. Si può notare, inoltre, che per queste due città l’andamento delle vendite nel periodo 2010-2014 è stato molto instabile, indicando quindi un mercato poco prevedibile e ad alto rischio. La città di Wichita Falls, invece, presenta un numero di vendite decisamente minore nel periodo osservato, ma l’andamento risulta essere molto più stabile e meno soggetto a picchi, indicando una maggiore prevedibilità del mercato.

Andamento storico del prezzo mediano di vendita per città

ggplot(realestate_texas, aes(x = mm_yy_date, 
                             y = median_price, 
                             col = city, 
                             group = city))+
  geom_line(linewidth = 0.8)+
  geom_point(size = 2)+
  scale_x_date(breaks = seq(as.Date("2010-01-01"), as.Date("2014-01-01"), by = "1 year"),
               date_labels = "%Y")+
  scale_y_continuous(labels = label_number(big.mark = ".",
                                           decimal.mark = ","))+
  scale_color_manual(values = palette_acadia_custom)+
  labs(title = "Prezzo mediano di vendita per città nel periodo 2010-2014",
       x = NULL,
       y = "Prezzo mediano di vendita ($)",
       color = "Città")+
  theme_minimal()+
  theme(legend.position = "bottom")

Questo grafico mostra che, considerando il prezzo mediano di vendita anziché il numero di vendite, le città di Bryan-College Station e Tyler risultano essere quelle con l’andamento più stabile e meno soggetto a picchi. La città di Beaumont, invece, all’inizio del 2010 presentava un prezzo mediano di vendita più alto di tutte le altre città, per poi subire un crollo e rimanere quasi costantemente al di sotto del prezzo mediano delle città di Bryan-College Station e Tyler. Come nel caso del numero di vendite, la città di Wichita Falls risulta avere i valori più bassi anche per il prezzo mediano di vendita. Tuttavia, presenta una volatilità molto maggiore e svariati picchi, sia positivi che negativi. Per quanto riguarda il prezzo mediano di vendita, quindi, Bryan-College Station e Tyler risultano essere le città più affidabili e meno rischiose, mentre Beaumont e Wichita Falls presentano un mercato altamente imprevedibile.

Andamento storico dell’efficacia degli annunci di vendita per città

Innanzitutto, definiamo la variabile ratio_sales_listings come il rapporto tra il numero di vendite e il numero di annunci attivi, per misurare l’efficacia di questi ultimi e se influiscono sul numero totale delle vendite.

ratio_sales_listings <- sales/listings

Ora rappresentiamo graficamente l’andamento storico di questa variabile, distinguendo le città.

ggplot(data = realestate_texas, aes(x = mm_yy_date, 
                                   y = ratio_sales_listings, 
                                   group = city,
                                   col = city))+
  geom_line(linewidth = 0.8)+
  geom_point(size = 2)+
  scale_x_date(breaks = seq(as.Date("2010-01-01"), as.Date("2014-01-01"), by = "1 year"),
               date_labels = "%Y")+
  scale_color_manual(values = palette_acadia_custom)+
  labs(title = "Efficacia degli annunci di vendita per città nel periodo 2010-2014",
       x = NULL,
       y = "Rapporto vendite/annunci",
       col = "Città")+
  theme_minimal()+
  theme(legend.position = "bottom")

Il grafico conferma che gli annunci risultano più efficaci nella città di Bryan-College Station, nel periodo 2013-2014, mentre la città dove risultano meno efficaci è Tyler, specialmente nel 2011. In generale, non risulta esserci un rapporto significativo tra il numero di vendite e il numero di annunci, da cui si può ipotizzare una necessità di rivedere le strategie di marketing attuate per le inserzioni immobiliari.

9. Conclusioni

Dall’analisi statistica condotta si può concludere quanto segue: