library(knitr)
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(moments)
library(kableExtra)
## Warning: il pacchetto 'kableExtra' è stato creato con R versione 4.5.2
## 
## Caricamento pacchetto: 'kableExtra'
## Il seguente oggetto è mascherato da 'package:dplyr':
## 
##     group_rows
library(ggplot2)
df <- read.csv("C:/Users/alessandro.recchia/Downloads/realestate_texas.csv")

Definiamo le variabili singole per comodità.

median_price <- as.numeric(as.character(df$median_price))
sales <- as.numeric(as.character(df$sales))
volume <- as.numeric(as.character(df$volume))
listings <- as.numeric(as.character(df$listings))
months_inventory <- as.numeric(as.character(df$months_inventory))
str(df)
## '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 ...

Il dataframe presenta 240 osservazioni/righe e 8 colonne/variabili.

La tabella presenta 8 colonne in tutto. “city” qualitativa nominale (char) “year” quantitativa continua “mese” qualitativa nominale (char) “sales” quantitativa discreta “volume” quantitativa discreta “median_price” quantitativa continua “listings” quantitativa discreta “months_inventory” quantitativa continua

Considerate le variabili e la struttura dei dati le analisi possono essere condotte attraverso lo studio di time series.

Indici di posizione, variabilità e forma

kable(distinct(df, city)) %>%
  kable_styling() %>%
  column_spec(1, color = "blue")
city
Beaumont
Bryan-College Station
Tyler
Wichita Falls

Nel dataset a nostra disposizione la variabile city present 4 possibili valori.

summary(df)
##      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

Da una overview dei dati risulta che la variabile “median_price” riporta una asimmetria negativa con mediana superiore alla media dunque avremo una coda lunga a sinistra della distribuzione. Al contrario le variabili “sales”, “volume”, “listings” e “months_inventory” presentano una asimmetria positiva con mediana inferiore alla media.

L’IQR indica la distanza fra il terzo quartile e il primo quartile della variabile in esame. E’ stato calcolato per median_price e sales.

IQR(median_price)
## [1] 32750
IQR(sales)
## [1] 120

Per misurare la variabilità si è deciso di calcolare il coefficiente di variazione di sales e median_price. Concetto poi esteso e rappresentato graficamente.

n<-length(sales)
mu<-mean(sales)

sd(sales)
## [1] 79.65111
sd(median_price)
## [1] 22662.15

Di seguito la funzione individuata per il calcolo del coefficiente di variazione.

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


CV(sales)
## [1] 41.42203
n<-length(median_price)
mu<-mean(median_price)

CV(median_price)
## [1] 17.08218

Il Coefficiente di Variazone consente di paragorare la variabilità fra più variabili includendo deviazione standard e media. La variabilità di “median_price” si attesta al 17% della propria media ed è inferiore a alla variabilità della variabile “sales” al 41% della sua media.

  1. Identificazione delle variabili con maggiore variabilità e asimmetria

Si procede con lo studio della variabilità sfruttando la libreria moments. Di seguito si riportano i grafici con le densità delle variabili qualitative del dataset.

variabili <- c("sales", "median_price","volume", "months_inventory","listings")

for (var in variabili) {
  norm_values <- rnorm(length(get(var)), mean(get(var)), sd(get(var)))
  
  plot(density(norm_values), main = paste("Densità di", var))
  abline(v = mean(get(var)), col = 3)
  cat("CV -> ", var, ":", CV(get(var)), "\n")
  cat("Asimmetria -> ", var, ":", skewness(get(var)), "\n")
  cat("Curtosi -> ", var, ":", kurtosis(get(var)) - 3, "\n")
}

## CV ->  sales : 41.42203 
## Asimmetria ->  sales : 0.718104 
## Curtosi ->  sales : -0.3131764

## CV ->  median_price : 17.08218 
## Asimmetria ->  median_price : -0.3645529 
## Curtosi ->  median_price : -0.6229618

## CV ->  volume : 53.70536 
## Asimmetria ->  volume : 0.884742 
## Curtosi ->  volume : 0.176987

## CV ->  months_inventory : 25.06031 
## Asimmetria ->  months_inventory : 0.04097527 
## Curtosi ->  months_inventory : -0.1744475

## CV ->  listings : 43.30833 
## Asimmetria ->  listings : 0.6494982 
## Curtosi ->  listings : -0.79179

La variabile che presenta maggiore variabilità risulta essere “volume” col coefficiente di variazione del 54% rispetto alla propria media.

L’asimmetria maggiore si riscontra per la variabile “volume” che ha una leggera asimmetria positiva, come confermato anche dal grafico. Anche la variabile “listings” presenta asimmetria positiva.

Calcolando asimmetria e curtosi si può concludere che in linea generale tutte le variabili mostrano una distribuzione abbastanza vicina ad una normale. Lo si deduce dal grafico e dal fatto che entrambi i valori (asimmetria e curtosi) per tutte le variabili sono infatti molto vicini a 0.

  1. Creazione di classi per una variabile quantitativa

Si procede creando delle classi per la variabile sales dal valore 70 al valore 430 con intervalli di 40 unità.

df$sales_classi<- cut(sales, seq(70,430,40))
ni<-table(df$sales_classi)
fi<-ni/n
Ni<- cumsum(ni)
Fi<- Ni/n
distr_freq_classi_sales<-as.data.frame(cbind(ni, fi, Ni, Fi))
kable(distr_freq_classi_sales) %>%
  kable_styling() %>%
  column_spec(1, color = "blue")
ni fi Ni Fi
(70,110] 35 0.1458333 35 0.1458333
(110,150] 58 0.2416667 93 0.3875000
(150,190] 46 0.1916667 139 0.5791667
(190,230] 29 0.1208333 168 0.7000000
(230,270] 23 0.0958333 191 0.7958333
(270,310] 26 0.1083333 217 0.9041667
(310,350] 11 0.0458333 228 0.9500000
(350,390] 9 0.0375000 237 0.9875000
(390,430] 3 0.0125000 240 1.0000000

Si riporta come sono distribuiti i valori delle sales/vendite nelle varie city/città e classi appena create.

length(df$city)
## [1] 240
length(df$sales_classi)
## [1] 240
kable(table(df$city, df$sales_classi))%>%
  kable_styling() %>%
  column_spec(1, color = "blue")
(70,110] (110,150] (150,190] (190,230] (230,270] (270,310] (310,350] (350,390] (390,430]
Beaumont 5 11 24 13 6 1 0 0 0
Bryan-College Station 6 13 14 6 4 10 2 3 2
Tyler 0 1 5 10 13 15 9 6 1
Wichita Falls 24 33 3 0 0 0 0 0 0

I valori sono poi normalizzati.

length(df$city)
## [1] 240
length(df$sales_classi)
## [1] 240
kable(table(df$city, df$sales_classi)/n)%>%
  kable_styling() %>%
  column_spec(1, color = "blue")
(70,110] (110,150] (150,190] (190,230] (230,270] (270,310] (310,350] (350,390] (390,430]
Beaumont 0.0208333 0.0458333 0.1000000 0.0541667 0.0250000 0.0041667 0.0000000 0.0000 0.0000000
Bryan-College Station 0.0250000 0.0541667 0.0583333 0.0250000 0.0166667 0.0416667 0.0083333 0.0125 0.0083333
Tyler 0.0000000 0.0041667 0.0208333 0.0416667 0.0541667 0.0625000 0.0375000 0.0250 0.0041667
Wichita Falls 0.1000000 0.1375000 0.0125000 0.0000000 0.0000000 0.0000000 0.0000000 0.0000 0.0000000
barplot(distr_freq_classi_sales$ni,
         main = "distribuzione di frequenza delle classi di vendita",
         xlab = "classi di vendita",
         ylab= "frequenze assolute",
         ylim =  c(0, 60),
         col = "blue",
         names.arg = rownames(distr_freq_classi_sales),
         cex.names = 0.7)

Distribuendo le vendite in classi si nota come le classi con maggiori osservazioni sono quelle che rappresentano i valori da 110 a 150 e da 150 a 190.

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

gini.index(df$sales_classi)
## [1] 0.9499609
gini.index(df$city)
## [1] 1

La distribuzione di frequenza della variabile sales è molto eterogenea, l’indice di Gini normalizzato risulta vicino ad uno. Provando a calcolare l’indice di Gini per la variabile “city” otteniamo il valore massimo di eterogeneità 1.

Calcolo della probabilità

length(df$month)/12
## [1] 20
kable(table(df$month))%>%
  kable_styling() %>%
  column_spec(1, color = "blue")
Var1 Freq
1 20
2 20
3 20
4 20
5 20
6 20
7 20
8 20
9 20
10 20
11 20
12 20
prob.luglio<-20/240*100
prob.meseanno<-1/240*100
prob.Beaumont<-60/240*100
prob.luglio
## [1] 8.333333
prob.meseanno
## [1] 0.4166667
prob.Beaumont
## [1] 25

La probabilità che una riga/osservazione presa a caso riporti la città di “Beaumont” è del 25%. La probabilità viene calcolata come il rapporto fra casi favorevoli e il numero di casi possibili.

La probabilità che una riga/osservazione presa a caso riporti il mese di luglio è data dal rapporto fra il numero di osservazioni registrate nel mese di luglio e il numero totale delle osservazioni, risulta essere di 8,3%.

La probabilità che riporti il mese di dicembre 2012 è dello 0,4%.

Creazione di nuove variabili.

df$month_year <- paste(df$month, df$year, sep = "/")
df$price_medium<- (df$volume)/(df$sales)*1000000
df$ad_effectiveness<- (df$listings)/(df$sales)

Il rapporto fra i volumi di vendita mensili e le vendite restituisce il prezzo medio di vendita Il rapporto fra il numero totale di annunci e le vendite effettivamente conseguite indica quanto siano efficaci gli annunci.

summary_table <- df %>%
  group_by(city) %>%
  summarise(avg_effectivness = mean(ad_effectiveness, na.rm = TRUE))
kable(summary_table)%>%
  kable_styling() %>%
  column_spec(1, color = "blue")
city avg_effectivness
Beaumont 10.049329
Bryan-College Station 8.356607
Tyler 11.388303
Wichita Falls 8.092745

La variabile city che presenta la miglior efficacia degli annunci è Wichita Falls, in poco più di 8 mesi in media una abitazione viene venduta.

summary_table <- df %>%
  group_by(city) %>%
  summarise(avg_price_medium = mean(price_medium, na.rm = TRUE))
kable(summary_table)%>%
  kable_styling() %>%
  column_spec(1, color = "blue")
city avg_price_medium
Beaumont 146640.4
Bryan-College Station 183534.3
Tyler 167676.8
Wichita Falls 119430.0

La zona con la media dei prezzi più alta è Byran-College Station con più di 183 mila dollari per abitazione.

Analisi condizionata

kable(df %>%
    group_by(city) %>%
   summarise(across(c(sales, median_price), 
                     list(media = mean, dev.st = sd))))%>%
  kable_styling() %>%
  column_spec(1, color = "blue")
city sales_media sales_dev.st median_price_media median_price_dev.st
Beaumont 177.3833 41.48395 129988.3 10104.993
Bryan-College Station 205.9667 84.98374 157488.3 8852.235
Tyler 269.7500 61.96380 141441.7 9336.538
Wichita Falls 116.0667 22.15192 101743.3 11320.034
boxplot1 <- ggplot(data=df)+
  geom_boxplot(aes(x=df$city,
                   y=df$median_price),
                   col="black",
                   fill="blue")+
              labs(
                title = "Boxplot dei valori medi del prezzo per città",
                x = "Città",
                y = "Valori misurati")
print(boxplot1)
## Warning: Use of `df$city` is discouraged.
## ℹ Use `city` instead.
## Warning: Use of `df$median_price` is discouraged.
## ℹ Use `median_price` instead.

boxplot2 <- ggplot(data=df)+
   geom_boxplot(aes(x=df$city,
                   y=df$sales),
                   col="red",
                   fill="lightblue"
                  ) +
                labs(
                title = "Boxplot delle vendite per città",
                x = "Città",
                y = "Valori misurati")
print(boxplot2)
## Warning: Use of `df$city` is discouraged.
## ℹ Use `city` instead.
## Warning: Use of `df$sales` is discouraged.
## ℹ Use `sales` instead.

I grafici presentano media e varianza di “median_price” e “sales” rispetto alla variabile “city”, da questo si può dedurre che:

  1. le vendite medie più alte sono state registrate nella città di Tyler tuttavia Bryan-College Station presenta il prezzo medio più alto.

  2. il calcolo delle deviazioni standard della variabile SALES mostra come la varianza più alta si registri per la città Bryan-College Station mentre la minima varianza si riscontra per la città Wichita Falls.

  3. il calcolo delle deviazioni standard della variabile MEDIAN_PRICE mostra una varianza più alta per la città di Wichita Falls e più bassa per la città Bryan-College Station.

  4. Creazione di visualizzazioni con ggplot2

Sommare le vendite per anno

sales_year_city <- df %>%
  group_by(year,city) %>%
  summarise(year_sales = sum(sales, na.rm = TRUE))
## `summarise()` has grouped output by 'year'. You can override using the
## `.groups` argument.
ggplot(data=sales_year_city)+
   geom_bar(aes(x=year,y=year_sales,fill=city),
            stat ="identity")+
            labs(title = "Vendite city per anno",x = "Anno", y = "Vendite", fill = "Città")

Eccezion fatta per l’anno 2011 le vendite generali sono sempre cresciute nel corso dei 5 anni. La città con maggiori vendite è Tyler.

Sommare le vendite per mese

sales_month_city <- df %>%
  group_by(month,city) %>%
  summarise(monthly_sales = sum(sales, na.rm = TRUE))
## `summarise()` has grouped output by 'month'. You can override using the
## `.groups` argument.
ggplot(data=sales_month_city)+
   geom_bar(aes(x=month,y=monthly_sales,fill=city),
            stat ="identity")+
            labs(title = "Vendite city per anno",x = "Mese", y = "Vendite", fill = "Città")

Dall’osservazione del grafico emerge che le vendite osservano una certa stagionalità con vendite maggiori nei mesi di maggio, giugno, luglio ed agosto. Il mese con meno vendite risulta essere gennaio. Questo fenomeno è meno evidente per la città di Wichita Falls.

Generazione di due nuove colonne utili alle visualizzazioni successive: una con mese-anno ed la data del mese.

df$month_year <- paste(df$month, df$year, sep = "/")
df$dates <- as.Date(paste0("1/", df$month_year), format = "%d/%m/%Y")
ggplot(data=df)+
    geom_line(aes(x = dates , y = sales, group = city, color = city))+
    labs(title="Numero di unità abitative vendute per città negli anni", x="Periodo",y="Vendite", color = "Città")+
    scale_x_date(date_breaks = "12 month", date_labels = "%m/%Y", expand = c(0, 0))

Il grafico a linee evidenzia il livello di vendite/sales nel corso del tempo. Anche qui è evidente la stagionalità che caratterizza questa variabile. La città con il più basso livello di vendite negli anni è Wichita Falls mentre quella che registra il più alto volume di vendite è la città di Tyler. Si nota come la città di Wichita Falls non abbia registrato un significativo incremento di vendite nel tempo.

ggplot(df) +
  geom_line(aes(x = dates, y = median_price, group = city, color = city)) +
  # RETTE DI TREND:
  geom_smooth(
    aes(x = dates, y = median_price, group = city, color = city),
    method = "lm",
    se = FALSE,
    linetype = "dashed"
  ) +
  labs(
    title = "Prezzo medio di vendita negli anni per città",
    x = "Periodo",
    y = "Prezzo medio di vendita",
    color = "Città"
  ) +
  scale_x_date(
    date_breaks = "12 month",
    date_labels = "%m/%Y",
    expand = c(0, 0)
  ) +
  theme(
    panel.background = element_rect(fill = "white", color = NA)
  )
## `geom_smooth()` using formula = 'y ~ x'

Il grafico evidenzia una crescita dei prezzi per tutte le città. L’unica città con un trend di crescita meno marcato è Beaumont. La città con il prezzi medi più alti è Byron College Station mentre quella con i prezzi più bassi è Wichita Falls.

Conclusioni

Il dataframe presenta 240 osservazioni/righe e 8 colonne/variabili.

La variabile “median_price” riporta una asimmetria negativa con mediana superiore alla media dunque avremo una coda lunga a sinistra della distribuzione mentre le variabili “sales”, “volume”, “listings” e “months_inventory” presentano una asimmetria positiva con mediana inferiore alla media. L’asimmetria positiva massima si registra per la variabile volume.

La variabile che presenta maggiore variabilità risulta essere “volume” col coefficiente di variazione del 54% rispetto alla propria media.

Analizzando asimmetria e curtosi si può concludere che in linea generale tutte le variabili mostrano una distribuzione abbastanza simile ad una normale. Lo si deduce dal grafico e dal fatto che entrambi i valori (asimmetria e curtosi) per tutte le variabili sono infatti molto vicini a 0.

Distribuendo le vendite in classi si nota come le classi con maggiori osservazioni sono le classi da 110 a 150 e da 150 a 190.

La distribuzione di frequenza della variabile sales è molto eterogenea, l’indice di Gini normalizzato risulta vicino ad uno. Provando a calcolare l’indice di Gini per la variabile “city” otteniamo il valore massimo di eterogeneità 1.

La città con annunci più efficaci nel periodo osservato è Wichita Falls, in poco più di 8 mesi in media una abitazione viene venduta.

La zona con la media dei prezzi più alta è Byran-College Station con più di 183 mila dollari per abitazione.

Dall’osservazione di media e varianza di “median_price” e “sales” rispetto alle città si può dedurre che:

  1. le vendite medie più alte sono state registrate nella città di Tyler tuttavia Bryan-College Station presenta il prezzo medio più alto (vedi sopra).
  2. il calcolo delle deviazioni standard della variabile SALES mostra come la varianza più alta si registri per la città Bryan-College Station mentre la minima varianza si riscontra per la città Wichita Falls.
  3. il calcolo delle deviazioni standard della variabile MEDIAN_PRICE mostra una varianza più alta per la città di Wichita Falls e più bassa per la città Bryan-College Station.

Eccezion fatta per l’anno 2011 le vendite generali sono sempre cresciute nel corso dei 5 anni. La città con maggiori vendite è Tyler.

Le vendite sono soggette ad una certa stagionalità con valori maggiori nei mesi di maggio, giugno, luglio ed agosto contro un mese di gennaio molto ridotto. Questo fenomeno è meno evidente per la città di Wichita Falls.

Dall’analisi temporale con trend si evidenzia una crescita dei prezzi per tutte le città. L’unica città con un trend di crescita meno marcato (vedi coefficiente angolare della regressione) è Beaumont.