Step 1: Analisi delle variabili

options(repos = c(CRAN = "https://cran.r-project.org"))

#Caricamento del dataset
dataset = read.csv("C:/Users/mikia/Desktop/corso_statistica/realestate_texas.csv")

#Analisi statistica delle variabili

#city: -\> Qualitativa nominale
#year: -\> Quantitativa continua da trattare come qualitativa ordinale
#month: -\> Qualitativa nominale (ciclica) ma codificata in numeri
#sales: -\> Quantitativa discreta
#volume: -\> Quantitativa continua
#median_price: -\> Quantitativa continua 
#listings: -\> Quantitativa discreta
#months_inventory: Quantitativa continua

Step 2: Indici di posizione, variabilità e forma

#Carico le librerie 
#knitr per visualizzare gli output tabellari 

library(knitr)
## Warning: il pacchetto 'knitr' è stato creato con R versione 4.4.2
library(moments)

#Grazie alla funzione summary riusciamo a vedere i principali indici di posizione per le variabili del dataset

summary(dataset)
##      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
#Definiamo una funzione per calcolare il coefficiente di variazione
cv = function(x){
  return(sd(x)/mean(x))
}

#Calcoliamo gli indici di variabilità all'interno di un dataframe
attach(dataset)


variable_index = data.frame(
  sales = c(round(var(sales), 2), round(sd(sales), 2), round(IQR(sales), 2), round(cv(sales), 2)),
  volume = c(round(var(volume), 2), round(sd(volume), 2), round(IQR(volume), 2), round(cv(volume), 2)),
  median_price = c(round(var(median_price), 2), round(sd(median_price), 2), round(IQR(median_price), 2), round(cv(median_price), 2)),
  listings = c(round(var(listings), 2), round(sd(listings), 2), round(IQR(listings), 2), round(cv(listings), 2)),
  month_inventory = c(round(var(months_inventory), 2), round(sd(months_inventory), 2), round(IQR(months_inventory), 2), round(cv(months_inventory), 2))
)

# Aggiunta dei nomi delle righe
rownames(variable_index) = c("Variance", "Standard Deviation", "IQR", "Coefficient of Variation")

kable(variable_index)
sales volume median_price listings month_inventory
Variance 6344.30 277.27 513572983.09 566568.97 5.31
Standard Deviation 79.65 16.65 22662.15 752.71 2.30
IQR 120.00 23.23 32750.00 1029.50 3.15
Coefficient of Variation 0.41 0.54 0.17 0.43 0.25
#Calcoliamo gli indici di forma all'interno di un dataframe


form_index <- data.frame(
  sales = c(round(skewness(sales), 2), round(kurtosis(sales), 2)),
  volume = c(round(skewness(volume), 2), round(kurtosis(volume), 2)),
  median_price = c(round(skewness(median_price), 2), round(kurtosis(median_price), 2)),
  listings = c(round(skewness(listings), 2), round(kurtosis(listings), 2)),
  month_inventory = c(round(skewness(months_inventory), 2), round(kurtosis(months_inventory), 2))
)

# Aggiunta dei nomi delle righe
rownames(form_index) = c("Skewness", "Kurtosis")

kable(form_index)
sales volume median_price listings month_inventory
Skewness 0.72 0.88 -0.36 0.65 0.04
Kurtosis 2.69 3.18 2.38 2.21 2.83
#Creiamo le distribuzioni per le variabili city, year, month.
#Per queste variabili infatti gli indici di cui sopra hanno poco significato.
#Osserviamo dai grafici che tutte queste variabili sono presenti con lo stesso numero di dati
#Ossia ciascuna variabile compare n/x volte con n il numero di righe del dataset ed x le modalità della variabile


barplot(
  table(dataset$city),
  main = "Frequenza delle città",  
  xlab = "Città",                 
  ylab = "Frequenza",           
)

barplot(
  table(dataset$year),
  main = "Frequenza degli anni",  
  xlab = "Year",                 
  ylab = "Frequenza",             
)

barplot(
  table(dataset$month),
  main = "Frequenza dei mesi",  
  xlab = "Month",                 
  ylab = "Frequenza",            
)

Step 3: Identificazione delle variabili con maggiore variabilità e asimmetria

#La grandezza con la maggiore variabilità relativa è "volume" avendo il più alto coefficiente di variabilità
#La grandezza con l'asimetria maggiore è "volume" essendo quella con la skewness più alta in valore assoluto

Step 4: Creazione di classi per una variabile quantitativa

dataset$median_price_class = cut(dataset$median_price/1000, breaks = c(70,90,110,130,150,170,190))

N = dim(dataset)[1]


#Calcolo le frequenze assolute e relative
ni = table(dataset$median_price_class) 
fi = table(dataset$median_price_class)/N

#Calcolo le frequenze assolute e relative cumulate
Ni = cumsum(ni)
Fi = cumsum(fi)

#Unisco i valori in unico vettore
distr_freq_median_price = as.data.frame(cbind(ni,fi,Ni,Fi))


#Realizzo un grafico a barre
barplot(round(distr_freq_median_price$ni,2),
        main = "Frequenze assolute delle classi di Median Price",
        xlab = "Classi di Median Price in k€",
        ylab = 'Numero di campioni',
        names.arg = rownames(distr_freq_median_price))

#Possiamo osservare come la distribuzione risulti skewed verso destra

#Calcolo indice di Gini
gini.index = function(x){
  ni = table(x)
  fi = ni/length(x)
  fi2 = fi^2
  J = length(table(x))
  gini = 1-sum(fi2)
  gini_norm = gini/((J-1)/J)
  return(gini_norm)
}

table(dataset$median_price_class)
## 
##   (70,90]  (90,110] (110,130] (130,150] (150,170] (170,190] 
##        11        38        46        85        54         6
print('Indice di Gini:')
## [1] "Indice di Gini:"
gini.index(dataset$median_price_class)
## [1] 0.9112917
#Abbiamo un indice di Gini pari a 0,9 quindi molto tendente ad 1
#Questa significa che la nostra distribuzione in classi è molto eterogenea
#Se tutte le classi fossero state con lo stesso numero di campioni avremmo infatti avuto un gini di 1

Step 5: Calcolo delle probabilità

sum(dataset$city == 'Beaumont')/N
## [1] 0.25
sum(dataset$month == 7)/N
## [1] 0.08333333
sum(dataset$month == 12 & dataset$year == 2012)/N
## [1] 0.01666667
#Per eseguire il calcolo delle probabilità occorre andare a dividere il numero di successi per il numero totale di casi
#Il numero totale di casi è dato dal numero di righe del dataset mentre il numero di successi è dato nel primo caso dalla città 'Beaumont', nel secondo caso dal mese 7 e così via...

Step 6: Creazione di nuove variabili

#Creo una colonna che contenga il prezzo medio degli immobili venduti per anno/mese/città
#Per fare questo vado a dividere il valore totale delle vendite per il numero di vendite che sono state fatte
dataset$mean_price = ((dataset$volume)*10^6)/dataset$sales

#Cerchiamo una metrica che misuri l'efficacia degli annunci di vendita
#Per esempio possiamo andare a verificare il numero di giorni medio necessario per vendere una casa per anno/mese/città
#Le righe col il valore più basso saranno quelle con le performance migliori

#Creiamo quindi la colonna days_to_sell

dataset$days_to_sell = dataset$listings/(dataset$months_inventory*30)

#Vediamo quale riga rappresenta la performance migliore
dataset[dataset$days_to_sell == min(dataset$days_to_sell), ]
##              city year month sales volume median_price listings
## 204 Wichita Falls 2011    12    81    9.4       102300      844
##     months_inventory median_price_class mean_price days_to_sell
## 204              7.9           (90,110]   116049.4     3.561181
#E quale la peggiore
dataset[dataset$days_to_sell == max(dataset$days_to_sell), ]
##      city year month sales volume median_price listings months_inventory
## 180 Tyler 2014    12   332 61.032       161600     2272              6.9
##     median_price_class mean_price days_to_sell
## 180          (150,170]   183831.3     10.97585

Step 7+8: Analisi condizionata applicata sulla colonna median_price e creazione di grafici con ggplot2

attach(dataset)
## I seguenti oggetti sono mascherati da dataset (pos = 3):
## 
##     city, listings, median_price, month, months_inventory, sales,
##     volume, year
library(ggplot2)
## Warning: il pacchetto 'ggplot2' è stato creato con R versione 4.4.2
#Creiamo i boxplot per vedere i valori dei prezzi mediani nei vari mesi/anni divisi per città
ggplot(data = dataset) +
  geom_boxplot(aes(x = city, y = median_price)) +
  labs(
    x = "Città",
    y = "Prezzo Mediano",
    title = "Distribuzione del prezzo mediano per città"
  ) +
  theme_minimal()

#Creiamo i boxplot per vedere i valori dei prezzi mediani nei vari mesi divisi per anno
ggplot(data = dataset) +
  geom_boxplot(aes(x = factor(year), y = median_price)) +
  labs(
    x = "Anni",
    y = "Median Price",
    title = "Distribuzione del prezzo mediano per anno"
  ) +
  theme_minimal()

# Carica il pacchetto dplyr
library(dplyr)
## Warning: il pacchetto 'dplyr' è stato creato con R versione 4.4.2
## 
## 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
# Creiamo il grafico a barre del prezzo mediano per ogni mese e città
ggplot(data = dataset) +
  stat_summary(
    aes(x = factor(month, levels = 1:12), y = median_price, fill = city),
    geom = "bar",  
    position = "dodge",  
    width = 0.7
  ) +
  labs(
    x = "Mese",
    y = "Median Price",
    title = "Prezzo Mediano per Mese e Città",
    fill = "Città"
  ) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))
## No summary function supplied, defaulting to `mean_se()`

#Creiamo un line chart per vedere l'andamento delle vendite medie per città e mese
#Per fare questo occorre prima creare una colonna che sia concatenazione di anno e mese e che sarà il nostro asse x

# Creiamo la colonna month_year come un oggetto di tipo Date
dataset$month_year <- as.Date(paste(dataset$year, dataset$month, "01", sep = "-"), format = "%Y-%m-%d")


ggplot(data = dataset) +
  geom_point(aes(x = month_year, y = sales, color = city), alpha = 0.6, linewidth = 2) +
  geom_line(aes(x = month_year, y = sales, color = city, group = city), linewidth = 1) +
  labs(
    x = "Mese/Anno",
    y = "Sales",
    color = "Città",
    title = "Andamento delle vendite nel tempo per città"
  ) +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 90, hjust = 1),
        legend.position = "bottom")
## Warning in geom_point(aes(x = month_year, y = sales, color = city), alpha =
## 0.6, : Ignoring unknown parameters: `linewidth`

Step 9: Conclusioni

#Per quanto riguarda la distribuzione del prezzo mediano possiamo dire come questo sia tendenzialmente in crescita dal 2010 al 2014 come si poteva aspettare.
#L'unica eccezione è stata nel 2011 ma per il resto il prezzo è sempre andato a salire

#Per quanto riguarda le città possiamo vedere come Bryan-College station sia quella con il prezzo mediano maggiore.
#Al contrario Wichita Falls presenta il prezzo mediano minore

#Andando ad osservare il prezzo mediano per mese e città possiamo vedere che i mesi con i prezzi mediano più alti sono quelli estivi per Wichita Falls e per Tyler.
#Meno marcata sembra essere la differenza per le altre due città

#Dal grafico delle vendite nel tempo possiamo osservare delle stagionalità
#Per esempio nel periodo da maggio fino a settembre è per tutte le città il periodo dove in genre si vende di più