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: -\> Variabile categorica 
#year: -\> variabile temporale 
#month: -\> variabile temporale 
#sales: -\> variabile quantitativa discreta 
#volume: -\> variabile quantitativa discreta 
#median_price: -\> variabile quantitativa discreta 
#listings: variabile quantitativa discreta
#months_inventory: variabile quantitativa discreta

Step 2: Indici di posizione, variabilità e forma

#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
#Indici di variabilità
attach(dataset)

#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

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

#Calcoliamo gli indici di forma all'interno di un dataframe

install.packages('moments')
## Installazione pacchetto in 'C:/Users/mikia/AppData/Local/R/win-library/4.4'
## (perché 'lib' non è specificato)
## pacchetto 'moments' aperto con successo con controllo somme MD5
## 
## I pacchetti binari scaricati sono in
##  C:\Users\mikia\AppData\Local\Temp\Rtmpm8FdF3\downloaded_packages
library(moments)


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

#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
barplot(table(dataset$city))

barplot(table(dataset$year))

barplot(table(dataset$month))

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

#La grandezza con la maggiore variabilità relativa è "listings" 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, breaks = c(70000,90000,110000,130000,150000,170000,190000))

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(distr_freq_median_price$ni,
        main = "Distribuzione delle classi di Median Price",
        xlab = "Classi di Median Price",
        ylab = 'Frequenze assolute',
        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)
## 
##     (7e+04,9e+04]   (9e+04,1.1e+05] (1.1e+05,1.3e+05] (1.3e+05,1.5e+05] 
##                11                38                46                85 
## (1.5e+05,1.7e+05] (1.7e+05,1.9e+05] 
##                54                 6
gini.index(dataset$median_price_class)
## [1] 0.9112917

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

Step 6: Creazione di nuove variabili

dataset$mean_price = ((dataset$volume)*10^6)/dataset$sales

#Creiamo la colonna days_to_sell che rappresenta il numero di giorni medio necessario per vendere un annuncio per anno/mese/città

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

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  
##          median_price_class   mean_price      days_to_sell   
##  (7e+04,9e+04]    :11       Min.   : 97010   Min.   : 3.561  
##  (9e+04,1.1e+05]  :38       1st Qu.:132939   1st Qu.: 4.671  
##  (1.1e+05,1.3e+05]:46       Median :156588   Median : 5.868  
##  (1.3e+05,1.5e+05]:85       Mean   :154320   Mean   : 6.245  
##  (1.5e+05,1.7e+05]:54       3rd Qu.:173915   3rd Qu.: 7.865  
##  (1.7e+05,1.9e+05]: 6       Max.   :213234   Max.   :10.976
#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    (9e+04,1.1e+05]   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  (1.5e+05,1.7e+05]   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 = 4):
## 
##     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()

#Creiamo vari boxplot per i valori dei prezzi mediani nei vari anni separati per mese e città
ggplot(data = dataset) +
  geom_boxplot(aes(x = factor(month, levels = 1:12), y = median_price, fill = city)) +
  labs(
    x = "Mese",
    y = "Median Price",
    title = "Distribuzione del prezzo mediano per mese e città"
  ) +
  theme_minimal()

#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

dataset$month_year = paste(dataset$month, dataset$year, sep = "/")

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 = 45, hjust = 1))
## Warning in geom_point(aes(x = month_year, y = sales, color = city), alpha =
## 0.6, : Ignoring unknown parameters: `linewidth`

Step 9: Conclusioni

#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ù