STATISTICA DESCRITTIVA - PROGETTO FINALE

import delle librerie

library(ggplot2)
library(moments)
library(dplyr)
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union

set working dir

setwd("//wsl.localhost/Ubuntu/home/fchiricotto/ProfessionAI/AI-courses/02-statistica-descrittiva//progetto_finale")

lettura dati da csv

dati <- read.csv("./Real Estate Texas.csv", sep = ",")

1 Analisi delle variabili

Identifica e descrivi il tipo di variabili statistiche presenti nel dataset

head(dati) # visualizzo le prime righe del dataframe
##       city year month sales volume median_price listings months_inventory
## 1 Beaumont 2010     1    83 14.162       163800     1533              9.5
## 2 Beaumont 2010     2   108 17.690       138200     1586             10.0
## 3 Beaumont 2010     3   182 28.701       122400     1689             10.6
## 4 Beaumont 2010     4   200 26.819       123200     1708             10.6
## 5 Beaumont 2010     5   202 28.833       123100     1771             10.9
## 6 Beaumont 2010     6   189 27.219       122800     1803             11.1
attach(dati) # estrazione delle colonne del dataframe

Il dataset è composto dalle seguenti variabili:

  • city: variabile qualitativa su scala nominale

  • year: variabile quantitativa discreta su scala di intervalli da trattare come variabile qualitativa ordinale in questo caso.

  • month: variabile qualitativa nominale ciclica che in questo caso è codificata in numeri

  • sales: variabile quantitativa discreta su scala di rapporti

  • volume: variabile quantitativa continua su scala di rapporti

  • median_price: variabile quantitativa continua su scala di rapporti

  • listings: variabile quantitativa discreta su scala di rapporti

  • months_inventory: variabile quantitativa continua su scala di rapporti

Le variabili year e month di tipo tempo consentono osservare variazioni tra un anno e l’altro (trend annuale) e di identificare pattern stagionali.

2 Indici di posizione, variabilità e forma

Indici di posizione

qualitative_var = c("city", "year", "month")
quantitative_var = c("sales", "volume", "median_price", "listings", "months_inventory")

moda

Definisco la funzione per il calcolo della moda

compute_moda <- function(v) {
  freq_table <- table(v)
  moda <- names(freq_table)[freq_table == max(freq_table)]
  return(moda)
}

calcolo la moda:

for ( var in qualitative_var){
  moda <- compute_moda(dati[[var]])
  cat("la moda della variabile", var, ": ", moda, "\n")}
## la moda della variabile city :  Beaumont Bryan-College Station Tyler Wichita Falls 
## la moda della variabile year :  2010 2011 2012 2013 2014 
## la moda della variabile month :  1 2 3 4 5 6 7 8 9 10 11 12

mediana

Utilizzo la funzione built-in:

for ( var in quantitative_var){
  mediana <- median(dati[[var]])
  cat("la mediana della variabile", var, ": ", mediana, "\n")}
## la mediana della variabile sales :  175.5 
## la mediana della variabile volume :  27.0625 
## la mediana della variabile median_price :  134500 
## la mediana della variabile listings :  1618.5 
## la mediana della variabile months_inventory :  8.95

media

Utilizzo la funzione built-in

for ( var in quantitative_var){
  media <- mean(dati[[var]])
  cat("la media della variabile", var, ": ", media, "\n")}
## la media della variabile sales :  192.2917 
## la media della variabile volume :  31.00519 
## la media della variabile median_price :  132665.4 
## la media della variabile listings :  1738.021 
## la media della variabile months_inventory :  9.1925

Indici di variabilità

Calcolo gli indici di variabilità per le osservabili quantitative

range

for ( var in quantitative_var){
  cat("il range della variabile", var, ": ", range(dati[[var]]), "\n")
  cat("la differenza tra minimo e massimo: ", diff(range(dati[[var]])), "\n\n")}
## il range della variabile sales :  79 423 
## la differenza tra minimo e massimo:  344 
## 
## il range della variabile volume :  8.166 83.547 
## la differenza tra minimo e massimo:  75.381 
## 
## il range della variabile median_price :  73800 180000 
## la differenza tra minimo e massimo:  106200 
## 
## il range della variabile listings :  743 3296 
## la differenza tra minimo e massimo:  2553 
## 
## il range della variabile months_inventory :  3.4 14.9 
## la differenza tra minimo e massimo:  11.5

varianza e deviazione standard

var(volume); sd(volume)
## [1] 277.2707
## [1] 16.65145
var(sales); sd(sales)
## [1] 6344.3
## [1] 79.65111
var(listings); sd(listings)
## [1] 566569
## [1] 752.7078
var(median_price); sd(median_price)
## [1] 513572983
## [1] 22662.15
var(months_inventory); sd(months_inventory)
## [1] 5.306889
## [1] 2.303669

coefficiente di variazione

Definisco la funzione per il calcolo del Coefficiente di Variazione (CV)

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

Calcolo il coefficiente

for ( var in quantitative_var){
  cat("il CV della variabile", var, ": ", CV(dati[[var]]), "\n")}
## il CV della variabile sales :  41.42203 
## il CV della variabile volume :  53.70536 
## il CV della variabile median_price :  17.08218 
## il CV della variabile listings :  43.30833 
## il CV della variabile months_inventory :  25.06031

COMMENTO: Per confrontare correttamente la variabilità tra grandezze diverse, non basta analizzare il range o la Varianza/deviazione standard. Poiché queste misure si riferiscono a variabili con scale e unità differenti è più opportuno utilizzare il coefficiente di variazione, che permette di valutare la variabilità relativa rispetto al valore medio, consentendo un confronto più accurato.

Distribuzione di frequenza

city
N = length(city)
# assolute
ni <- table(city)
# relative
fi <- ni / N
# trasformo la tabella in un dataframe
# trasformo la tabella in un dataframe
distr_freq_city <- as.data.frame(cbind(ni, fi))
distr_freq_city
##                       ni   fi
## Beaumont              60 0.25
## Bryan-College Station 60 0.25
## Tyler                 60 0.25
## Wichita Falls         60 0.25
year
N = length(year)
# assolute
ni <- table(year)
# relative
fi <- ni / N
# assolute cumulate
Ni <- cumsum(ni)
# relative cumulate
Fi <- Ni / N
# trasformo la tabella in un dataframe
distr_freq_year <- as.data.frame(cbind(ni, fi, Ni, Fi))
distr_freq_year
##      ni  fi  Ni  Fi
## 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
month
N = length(month)
# assolute
ni <- table(month)
# relative
fi <- ni / N
# trasformo la tabella in un dataframe
distr_freq_month <- as.data.frame(cbind(ni, fi))
distr_freq_month
##    ni         fi
## 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

COMMENTO: osservando le frequenze vediamo che le 3 variabili categoriche city, year e month sono equidistribuite: city presenta 4 modaità tutte con frequenza relativa di 0.25 year presenta 5 modalità (anni dal 2010 al 2014) tutte con frequenza relativa di 0.2 month presenta 12 modalità (12 mesi dell’anno codificati con i numeri da 1 a 12) tutte con frequenza relativa 0.083

Indice di eterogeneità di Gini

Questo indice misura la propensione di una variabile qualitativa ad assumere le sue diverse modalità

Definisco la funzione per il calcolo

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)
}

Calcolo l’indice di Gini per le tre variabili categoriche

for ( var in qualitative_var){
  cat("Gini index della variabile", var, ": ", gini.index(dati[[var]]), "\n")}
## Gini index della variabile city :  1 
## Gini index della variabile year :  1 
## Gini index della variabile month :  1

COMMENTO: come ci si attendeva il valore dell’indice di Gini per le variabili in esame è pari ad 1, ad indicare una equidistribuzione delle variabili. In questo dataset infatti abbiamo, per ciascuna città, i dati delle vendite per anno e per mese dal Gennaio 2010 al Dicembre 2014.

Indici di forma

vediamo ora come sono distribuiti i dati e valutiamo la forma della loro distribuzione calcolando gli indici di asimmetria e curtosi. per il calcolo sfruttiamo la libreria moments importata all’inizio.

Asimmetria e curtosi

Volume
skewness(volume)
## [1] 0.884742
kurtosis(volume) - 3
## [1] 0.176987
plot(density(volume))

COMMENTO: la variabile volume presenta una distribuzione con asimmetria positiva (valori di skewness positivi) e leptocurtica (valori di curtosi positivi) ovvero più allungata rispetto alla distribuzione normale.

skewness(sales)
## [1] 0.718104
kurtosis(sales) - 3
## [1] -0.3131764
plot(density(sales))

COMMENTO: la variabile sales presenta una distribuzione con asimmetria positiva (valori di skewness positivi) e platicurtica (valori di curtosi negativi) ovvero più appiattita rispetto alla distribuzione normale

skewness(listings)
## [1] 0.6494982
kurtosis(listings) - 3
## [1] -0.79179
plot(density(listings))

COMMENTO: la variabile listings presenta una distribuzione con asimmetria positiva (valori di skewness positivi) e platicurtica (valori di curtosi negativi) ovvero più appiattita rispetto alla distribuzione normale

skewness(median_price)
## [1] -0.3645529
kurtosis(median_price) - 3
## [1] -0.6229618
plot(density(median_price))

COMMENTO: la variabile median_price presenta una distribuzione con asimmetria negativa (valori di skewness negativi) e platicurtica (valori di curtosi negativi) ovvero più appiattita rispetto alla distribuzione normale

skewness(months_inventory)
## [1] 0.04097527
kurtosis(months_inventory) - 3
## [1] -0.1744475
plot(density(months_inventory))

COMMENTO: la variabile months_inventory presenta una distribuzione con leggera asimmetria positiva (valori di skewness positivi) e platicurtica (valori di curtosi negativi) ovvero più appiattita rispetto alla distribuzione normale

3 Identificazione delle variabili con maggiore variabilità e asimmetria

Qual è la variabile con la più alta variabilità?

La variabile con la più alta variabilità è il volume poichè presenta un coefficiente di variabilità maggiore. Il coefficiente di variabilità mi permette di confrontare variabili diverse dello stesso campione che hanno unità di misura e ordini di grandezza differenti, come nel caso in esame.

Qual è la variabile con la distribuzione più asimmetrica

La variabile con la distribuzione più asimmetrica è il volume in quanto ha un valore di skewness più elevato. In questo casi si tratta di asimmetria positiva.

4 Creazione di classi per una variabile quantitativa

Seleziona una variabile quantitativa (es. sales o median_price) e suddividila in classi.

Suddivisione in classi della variabile sales. Valutiamo i valori massimo e minimo per decidere l’ampiezza delle classi

range(sales)
## [1]  79 423
diff(range(sales))
## [1] 344

Supponiamo ad esempio di suddividere sales in 8 classi, avranno ampiezza

diff(range(sales))/8
## [1] 43

Creo le classi

sales_cl <- cut(sales, 
                breaks = seq(79, 423, length.out = 9), # Genera 9 punti per 8 intervalli
                include.lowest = TRUE,                # Include il valore minimo nell'intervallo
                right = FALSE)  

Aggiungo le classi in una nuova colonna del dataframe

dati$sales_cl <- sales_cl
head(dati)
##       city year month sales volume median_price listings months_inventory
## 1 Beaumont 2010     1    83 14.162       163800     1533              9.5
## 2 Beaumont 2010     2   108 17.690       138200     1586             10.0
## 3 Beaumont 2010     3   182 28.701       122400     1689             10.6
## 4 Beaumont 2010     4   200 26.819       123200     1708             10.6
## 5 Beaumont 2010     5   202 28.833       123100     1771             10.9
## 6 Beaumont 2010     6   189 27.219       122800     1803             11.1
##    sales_cl
## 1  [79,122)
## 2  [79,122)
## 3 [165,208)
## 4 [165,208)
## 5 [165,208)
## 6 [165,208)

Crea una distribuzione di frequenze e rappresenta i dati con un grafico a barre.

Costruisco la distribuzione di frequenze usando le classi precedentemente definite.

# freq assolute
ni <- table(sales_cl)
# freq relative
fi <- ni / N
# freq assolute cumulate
Ni <- cumsum(ni)
# freq relative cumulate
Fi <- Ni / N
# Trasformo in un dataframe
distr_freq_sales_cl <- data.frame(
  classi = names(ni),
  ni = as.numeric(ni),
  fi = as.numeric(fi),
  Ni = as.numeric(Ni),
  Fi = as.numeric(Fi)
)

Definisco la funzione per estrarre il limite inferiore delle classi necessaria per il corretto ordinamento dei dati nel grafico finale.

estrai_limite_inferiore <- function(classi) {
  as.numeric(sub("\\[([0-9]+),.*", "\\1", classi))
}

ordino le classi in base al limite estrai_limite_inferiore

distr_freq_sales_cl$classi <- factor(
  distr_freq_sales_cl$classi,
  levels = distr_freq_sales_cl$classi[order(estrai_limite_inferiore(distr_freq_sales_cl$classi))]
)
distr_freq_sales_cl
##      classi ni         fi  Ni        Fi
## 1  [79,122) 49 0.20416667  49 0.2041667
## 2 [122,165) 60 0.25000000 109 0.4541667
## 3 [165,208) 45 0.18750000 154 0.6416667
## 4 [208,251) 27 0.11250000 181 0.7541667
## 5 [251,294) 28 0.11666667 209 0.8708333
## 6 [294,337) 17 0.07083333 226 0.9416667
## 7 [337,380) 10 0.04166667 236 0.9833333
## 8 [380,423]  4 0.01666667 240 1.0000000

Grafico a barre con frequenze assolute

ggplot(data = distr_freq_sales_cl) +
  geom_col(
    aes(x = classi, y = ni), 
    fill = "lightblue", 
    col = "black"
  ) +
  labs(
    x = "Sales in classi",
    y = "Frequenze assolute",
    title = "Grafico a barre delle frequenze assolute"
  ) +
  theme_classic() +
  scale_y_continuous(breaks = seq(0, max(distr_freq_sales_cl$ni) + 5, 5))

Grafico a barre con frequenze relative

ggplot(data = distr_freq_sales_cl) +
  geom_col(
    aes(x = classi, y = fi), 
    fill = "lightgreen", 
    col = "black"
  ) +
  labs(
    x = "Sales in classi",
    y = "Frequenze relative",
    title = "Grafico a barre delle frequenze relative"
  ) +
  theme_classic() +
  scale_y_continuous(breaks = seq(0, 1, 0.1))

Calcola indice di eterogeneità Gini e discuti i risultati.

gini.index(sales_cl)
## [1] 0.9455556

COMMENTO: l’indice di eterogenerità di Gini pari a 0.95 indica una forte eterogeneità della variabile sales. Questo è confermato anche dal grafico a barre che non mostra una grande variabilità tra le frequenze relative delle diverse classi.

5 Calcolo della probabilità

Qual è la probabilità che, presa una riga a caso di questo dataset, essa riporti la città “Beaumont”?

Grafico a barre

ggplot()+
  geom_histogram(aes(x=city,
                     y=after_stat(count/sum(count))),
                 stat = "count", #conteggio
                 col="black",
                 fill="lightblue")+
  scale_y_continuous(limits = c(0, 0.4))+
  theme_classic()
## Warning in geom_histogram(aes(x = city, y = after_stat(count/sum(count))), :
## Ignoring unknown parameters: `binwidth`, `bins`, and `pad`

Attraverso l’uso dell’istogramma posso dedurre che la probabilità di avere come città Beaumont è del 25%. In alternativa posso calcolare tale probabilità, secondo l’approccio classico come:

# P = numero_casi_favorevoli / numero_casi_possibili = 
P <- sum(city == "Beaumont") / nrow(dati)
P
## [1] 0.25

la probabilità è del 25%.

E la probabilità che riporti il mese di Luglio?

Grafico a barre

ggplot()+
  geom_histogram(aes(x=month,
                     y=stat(count/sum(count))),
                 stat = "count", #conteggio
                 col="black",
                 fill="lightblue")+
  scale_y_continuous(limits = c(0, 0.1))+
    theme_classic()
## Warning in geom_histogram(aes(x = month, y = stat(count/sum(count))), stat =
## "count", : Ignoring unknown parameters: `binwidth`, `bins`, and `pad`
## Warning: `stat(count / sum(count))` was deprecated in ggplot2 3.4.0.
## ℹ Please use `after_stat(count / sum(count))` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

calcolo la probabilità con approccio classico

P <- sum(month == 7) / nrow(dati)
P
## [1] 0.08333333

la probabilità è dell’ 8.3%.

E la probabilità che riporti il mese di dicembre 2012?

Per calcolare questa probabilità devo utilizzare sia la colonna year che la colonna month

P <- sum(month == 7 & year == 2012) / nrow(dati)
P
## [1] 0.01666667

la probabilità è dell’ 1.7%.

6 Creazione di nuove variabili

Crea una nuova colonna che calcoli il prezzo medio degli immobili utilizzando le variabili disponibili.

Creo una nuova colonna mean_price che riporta il prezzo medio (in milioni di dollari) degli immobili, calcolato come il rapporto tra il totale delle vendite (in milioni di dollari) ed il numero di immobili venduti

dati$mean_price <- dati$volume / dati$sales
head(dati)
##       city year month sales volume median_price listings months_inventory
## 1 Beaumont 2010     1    83 14.162       163800     1533              9.5
## 2 Beaumont 2010     2   108 17.690       138200     1586             10.0
## 3 Beaumont 2010     3   182 28.701       122400     1689             10.6
## 4 Beaumont 2010     4   200 26.819       123200     1708             10.6
## 5 Beaumont 2010     5   202 28.833       123100     1771             10.9
## 6 Beaumont 2010     6   189 27.219       122800     1803             11.1
##    sales_cl mean_price
## 1  [79,122)  0.1706265
## 2  [79,122)  0.1637963
## 3 [165,208)  0.1576978
## 4 [165,208)  0.1340950
## 5 [165,208)  0.1427376
## 6 [165,208)  0.1440159

Il prezzo medio fornisce un’indicazione del costo medio degli immobili in ciascuna città per un determinato anno e mese. Prezzi molto alti possono indicare mercati immobiliari di lusso, mentre prezzi bassi potrebbero riflettere aree con proprietà più economiche.

Boxplot del prezzo medio per città

ggplot(data = dati, aes(x = city, y = mean_price)) +
  geom_boxplot(fill = "lightblue", color = "black") +
  labs(title = "Distribuzione del Prezzo Medio per Citta",
       x = "Citta",
       y = "Prezzo Medio (10^6 $)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

La distribuzione del prezzo medio di vendita per città mostra che Bryan è la città con un prezzo medio più alto mentre Wichita Falls è quella con prezzo medio più basso.

Prova a creare una colonna che misuri l’efficacia degli annunci di vendita.

Per valutare l’efficacia degli annunci possiamo ad esempio utilizzare le variabili listings (numero di annunci attivi) e sales (numero totale di vendite)

dati$efficacia_annunci <- ifelse(dati$listings != 0, dati$sales / dati$listings, NA)
head(dati)
##       city year month sales volume median_price listings months_inventory
## 1 Beaumont 2010     1    83 14.162       163800     1533              9.5
## 2 Beaumont 2010     2   108 17.690       138200     1586             10.0
## 3 Beaumont 2010     3   182 28.701       122400     1689             10.6
## 4 Beaumont 2010     4   200 26.819       123200     1708             10.6
## 5 Beaumont 2010     5   202 28.833       123100     1771             10.9
## 6 Beaumont 2010     6   189 27.219       122800     1803             11.1
##    sales_cl mean_price efficacia_annunci
## 1  [79,122)  0.1706265        0.05414220
## 2  [79,122)  0.1637963        0.06809584
## 3 [165,208)  0.1576978        0.10775607
## 4 [165,208)  0.1340950        0.11709602
## 5 [165,208)  0.1427376        0.11405985
## 6 [165,208)  0.1440159        0.10482529

L’efficacia degli annunci cosi definita misura quanto gli annunci portano effettivamente ad una vendita. Ci aspettiamo che un valore vicino a 1 indica un mercato attivo, in cui gli annunci generano vendite. Un valore basso invece può indicare maggiore difficoltà di vendita.

Grafico dell’efficacia degli annunci per città

ggplot(data = dati, aes(x = city, y = efficacia_annunci)) +
  geom_boxplot(fill = "lightblue", color = "black") +
  labs(title = "Efficacia degli annunci per citta",
       x = "Citta",
       y = "Efficacia degli annunci") +
  theme_minimal()

La distribuzione dell’efficacia degli annunci per città è maggiore in Bryan e Wichita Falls rispetto alle altre due città. Mentre in Wichita Falls la distribuzione dell’efficacia è molto concentrata intorno alla media, nel caso Bryan-College Station sembra esserci una maggiore dispersione, con diversi casi di valori di efficacia molto maggiori della media.

Confrontando questo risultato con il prezzo medio di vendita per città potremmo affermare che la città in cui si ha una maggiore efficacia degli annunci considerando anche i profitti che ne potrebbero derivare (dato il prezzo di vendita medio maggiore) è Bryan-College Station.

7 Analisi condizionata

Usa il pacchetto dplyr o il linguaggio base di R per effettuare analisi statistiche condizionate per città, anno e mese. Genera dei summary (media, deviazione standard) e rappresenta graficamente i risultati.

Calcolo delle statistiche (media e deviazione standard) condizionate per città

statistiche_citta <- dati %>%
  group_by(city) %>%
  summarise(
    media_sales = mean(sales, na.rm = TRUE),
    sd_sales = sd(sales, na.rm = TRUE),
    media_volume = mean(volume, na.rm = TRUE),
    sd_volume = sd(volume, na.rm = TRUE)
  )
statistiche_citta
## # A tibble: 4 × 5
##   city                  media_sales sd_sales media_volume sd_volume
##   <chr>                       <dbl>    <dbl>        <dbl>     <dbl>
## 1 Beaumont                     177.     41.5         26.1      6.97
## 2 Bryan-College Station        206.     85.0         38.2     17.2 
## 3 Tyler                        270.     62.0         45.8     13.1 
## 4 Wichita Falls                116.     22.2         13.9      3.24

Calcolo delle statistiche (media e deviazione standard) condizionate per anno

statistiche_year <- dati %>%
  group_by(year) %>%
  summarise(
    media_sales = mean(sales, na.rm = TRUE),
    sd_sales = sd(sales, na.rm = TRUE),
    media_volume = mean(volume, na.rm = TRUE),
    sd_volume = sd(volume, na.rm = TRUE)
  )
statistiche_year
## # A tibble: 5 × 5
##    year media_sales sd_sales media_volume sd_volume
##   <int>       <dbl>    <dbl>        <dbl>     <dbl>
## 1  2010        169.     60.5         25.7      10.8
## 2  2011        164.     63.9         25.2      12.2
## 3  2012        186.     70.9         29.3      14.5
## 4  2013        212.     84.0         35.2      17.9
## 5  2014        231.     95.5         39.8      21.2

Calcolo delle statistiche (media e deviazione standard) condizionate per mese

statistiche_month <- dati %>%
  group_by(month) %>%
  summarise(
    media_sales = mean(sales, na.rm = TRUE),
    sd_sales = sd(sales, na.rm = TRUE),
    media_volume = mean(volume, na.rm = TRUE),
    sd_volume = sd(volume, na.rm = TRUE)
  )
statistiche_month
## # A tibble: 12 × 5
##    month media_sales sd_sales media_volume sd_volume
##    <int>       <dbl>    <dbl>        <dbl>     <dbl>
##  1     1        127.     43.4         19.0      8.37
##  2     2        141.     51.1         21.7     10.1 
##  3     3        189.     59.2         29.4     12.0 
##  4     4        212.     65.4         33.3     14.5 
##  5     5        239.     83.1         39.7     19.0 
##  6     6        244.     95.0         41.3     21.1 
##  7     7        236.     96.3         39.1     21.4 
##  8     8        231.     79.2         38.0     18.0 
##  9     9        182.     72.5         29.6     15.2 
## 10    10        180.     75.0         29.1     15.1 
## 11    11        157.     55.5         24.8     11.2 
## 12    12        169.     60.7         27.1     12.6

Rappresento graficamente le statistiche appena calcolate:

city
ggplot(data = statistiche_citta, aes(x = city, y = media_sales, fill = city)) +
  geom_bar(stat = "identity", color = "black", position = "dodge") + 
  geom_text(aes(label = round(media_sales, 1)),  
            vjust = -0.5,                        
            size = 4) +                          
  labs(
    title = "Media delle vendite per citta",
    x = "Citta",
    y = "Media delle vendite"
  ) +
  theme_minimal() +
  theme(legend.position = "none") 

COMMENTO: dal grafico emerge che nella città di Tyler si ha la media delle vendite più alta, mentre a Wichita Falls si ha la media minore.

year
ggplot(data = statistiche_year, aes(x = year, y = media_sales)) +
  geom_line(size = 1) +         
  geom_point(size = 3) +        
  geom_text(aes(label = round(media_sales, 1)),   
            vjust = -1, size = 4, color = "black") +
  labs(
    title = "Media delle vendite per anno",
    x = "Anno",
    y = "Media delle vendite"
  )+
  theme_minimal() +
  theme(legend.position = "bottom")+
  scale_y_continuous(limits = c(0, 300))
## 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.

COMMENTO: in media le vendite hanno avuto un trend positivo negli anni.

month
ggplot(data = statistiche_month, aes(x = month, y = media_sales, group = month, color = month)) +
  geom_point() +
  geom_errorbar(aes(ymin = media_sales - sd_sales,   
                    ymax = media_sales + sd_sales), 
                width = 0.2,                        
                size = 0.8) +  labs(
    title = "Media delle vendite per mese",
    x = "Mese",
    y = "Media delle vendite"
  ) +
  theme_minimal() +
  scale_x_discrete(limits = month.abb) +  
  theme(legend.position = "bottom")

COMMENTO: osservando la media delle vendite mensili si osserva una forte stagionalità; il maggior numero di vendite si ha nei mesi estivi da Maggio ad Agosto

Calcolo delle statistiche (media e deviazione standard) condizionate per città e mese

statistiche_city_month <- dati %>%
  group_by(city, month) %>%
  summarise(
    media_sales = mean(sales, na.rm = TRUE),
    sd_sales = sd(sales, na.rm = TRUE),
    media_volume = mean(volume, na.rm = TRUE),
    sd_volume = sd(volume, na.rm = TRUE)
  )
## `summarise()` has grouped output by 'city'. You can override using the
## `.groups` argument.
statistiche_month
## # A tibble: 12 × 5
##    month media_sales sd_sales media_volume sd_volume
##    <int>       <dbl>    <dbl>        <dbl>     <dbl>
##  1     1        127.     43.4         19.0      8.37
##  2     2        141.     51.1         21.7     10.1 
##  3     3        189.     59.2         29.4     12.0 
##  4     4        212.     65.4         33.3     14.5 
##  5     5        239.     83.1         39.7     19.0 
##  6     6        244.     95.0         41.3     21.1 
##  7     7        236.     96.3         39.1     21.4 
##  8     8        231.     79.2         38.0     18.0 
##  9     9        182.     72.5         29.6     15.2 
## 10    10        180.     75.0         29.1     15.1 
## 11    11        157.     55.5         24.8     11.2 
## 12    12        169.     60.7         27.1     12.6
ggplot(data = statistiche_city_month, aes(x = month, y = media_sales, group = city, color = city)) +
  geom_line(lwd=1)+
  geom_point() +
  labs(
    title = "Media delle vendite per mese",
    x = "Mese",
    y = "Media delle vendite"
  ) +
  theme_minimal() +
  scale_x_discrete(limits = month.abb) +  
  theme(legend.position = "bottom")

COMMENTO: osservando l’andamento delle vendite medie per mese e per città emerge ancora la presenza di una forte stagionalità, in particolare nelle città di Bryan-College Station e Tyler.

Calcolo delle statistiche (media e deviazione standard) condizionate per città e anno

statistiche_city_year <- dati %>%
  group_by(city, year) %>%
  summarise(
    media_sales = mean(sales, na.rm = TRUE),
    sd_sales = sd(sales, na.rm = TRUE),
    media_volume = mean(volume, na.rm = TRUE),
    sd_volume = sd(volume, na.rm = TRUE)
  )
## `summarise()` has grouped output by 'city'. You can override using the
## `.groups` argument.
statistiche_city_year
## # A tibble: 20 × 6
## # Groups:   city [4]
##    city                   year media_sales sd_sales media_volume sd_volume
##    <chr>                 <int>       <dbl>    <dbl>        <dbl>     <dbl>
##  1 Beaumont               2010        156.     36.9         22.7      4.95
##  2 Beaumont               2011        144      22.7         21.1      4.30
##  3 Beaumont               2012        172.     28.4         24.5      4.92
##  4 Beaumont               2013        201.     37.7         30.3      6.44
##  5 Beaumont               2014        214.     36.5         32.1      7.05
##  6 Bryan-College Station  2010        168.     70.8         28.7     10.8 
##  7 Bryan-College Station  2011        167.     62.2         28.9     10.3 
##  8 Bryan-College Station  2012        197.     74.3         35.4     13.5 
##  9 Bryan-College Station  2013        238.     95.8         45.1     19.5 
## 10 Bryan-College Station  2014        260.     86.7         52.8     18.0 
## 11 Tyler                  2010        228.     49.0         36.3      8.39
## 12 Tyler                  2011        239.     49.6         38.6      9.41
## 13 Tyler                  2012        264.     46.4         44.0     10.2 
## 14 Tyler                  2013        287.     53.0         50.3     10.3 
## 15 Tyler                  2014        332.     56.9         59.6     12.8 
## 16 Wichita Falls          2010        123.     26.6         15.0      4.07
## 17 Wichita Falls          2011        106.     19.8         12.1      2.52
## 18 Wichita Falls          2012        112.     14.2         13.2      2.66
## 19 Wichita Falls          2013        121.     26.0         14.9      3.11
## 20 Wichita Falls          2014        117      21.1         14.5      3.13
ggplot(data = statistiche_city_year, aes(x = year, y = media_sales, group = city, color = city)) +
  geom_line(lwd=1)+
  geom_point() +
  labs(
    title = "Media delle vendite per Anno per Citta",
    x = "Anno",
    y = "Media delle vendite"
  ) +
  theme_minimal() +
  theme(legend.position = "bottom")

COMMENTO: l’andamento delle vendite medie per anno e per città mostra un trend positivo; le vendite sono aumentate nel corso degli anni in particolar modo nelle città di Bryan-College Station, Tyler e Beaumont.

Calcolo dell’efficacia media delle vendite per anno e per città

Calcolo delle statistiche (media e deviazione standard) condizionate per città e anno

statistiche_city_year_eff <- dati %>%
  group_by(city, year) %>%
  summarise(
    media_efficacia = mean(efficacia_annunci, na.rm = TRUE),
    sd_efficacia = sd(efficacia_annunci, na.rm = TRUE)
  )
## `summarise()` has grouped output by 'city'. You can override using the
## `.groups` argument.
statistiche_city_year_eff
## # A tibble: 20 × 4
## # Groups:   city [4]
##    city                   year media_efficacia sd_efficacia
##    <chr>                 <int>           <dbl>        <dbl>
##  1 Beaumont               2010          0.0898       0.0195
##  2 Beaumont               2011          0.0823       0.0117
##  3 Beaumont               2012          0.102        0.0158
##  4 Beaumont               2013          0.123        0.0215
##  5 Beaumont               2014          0.135        0.0218
##  6 Bryan-College Station  2010          0.106        0.0396
##  7 Bryan-College Station  2011          0.103        0.0315
##  8 Bryan-College Station  2012          0.122        0.0423
##  9 Bryan-College Station  2013          0.171        0.0649
## 10 Bryan-College Station  2014          0.236        0.0768
## 11 Tyler                  2010          0.0745       0.0151
## 12 Tyler                  2011          0.0773       0.0126
## 13 Tyler                  2012          0.0902       0.0134
## 14 Tyler                  2013          0.101        0.0143
## 15 Tyler                  2014          0.124        0.0199
## 16 Wichita Falls          2010          0.129        0.0302
## 17 Wichita Falls          2011          0.108        0.0159
## 18 Wichita Falls          2012          0.126        0.0154
## 19 Wichita Falls          2013          0.144        0.0283
## 20 Wichita Falls          2014          0.133        0.0187
ggplot(data = statistiche_city_year_eff, aes(x = year, y = media_efficacia, group = city, color = city)) +
  geom_line(lwd=1)+
  geom_point() +
  labs(
    title = "Efficacia media per Anno per Citta",
    x = "Anno",
    y = "Efficacia media delle vendite"
  ) +
  theme_minimal() +
  theme(legend.position = "bottom")

COMMENTO: l’efficacia media delle vendite sembra essere in aumento negli anni per le città di Bryan-College Station Tyler e Beaumont. Nell’ultimo anno l’efficacia nella città di Wichita-Falls ha avuto una flessione.

8 Creazione di visualizzazioni con ggplot2

Utilizza ggplot2 per creare grafici personalizzati. Assicurati di esplorare:

- Boxplot per confrontare la distribuzione del prezzo mediano tra le città.

ggplot(data = dati, aes(x = city, y = median_price)) +
  geom_boxplot(fill = "lightblue", color = "black") +
  labs(title = "Distribuzione del Prezzo Mediano per Citta",
       x = "Citta",
       y = "Prezzo Mediano ($)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

COMMENTO: il grafico mostra la distribuzione del prezzo medio per città; Bryan-College Station e Tyler sono le città con il prezzo mediano più alto.

- Grafici a barre per confrontare il totale delle vendite per mese e città.

total_sales_city_month <- dati %>%
  group_by(city, month) %>%
  summarise(
    total_sales = sum(sales, na.rm = TRUE)
  )
## `summarise()` has grouped output by 'city'. You can override using the
## `.groups` argument.

Grafico a barre (dodge):

ggplot(data = total_sales_city_month, aes(x = month, y = total_sales, fill = city)) +
  geom_col(position = "dodge", color = "black") + # Bar plot con le barre affiancate
  labs(
    title = "Totale delle vendite per mese per citta",
    x = "Mese",
    y = "Totale delle vendite"
  ) +
  theme_minimal() +
  scale_x_discrete(limits = month.abb) +  # Mostra i mesi abbreviati
  theme(legend.position = "bottom")

Grafico a barre (dodge):

ggplot(data = total_sales_city_month, aes(x = month, y = total_sales, fill = city)) +
  geom_col(position = "stack", color = "black") + # Bar plot con le barre sovrapposte
  labs(
    title = "Totale delle vendite per mese per citta",
    x = "Mese",
    y = "Totale delle vendite"
  ) +
  theme_minimal() +
  scale_x_discrete(limits = month.abb) +  # Mostra i mesi abbreviati
  theme(legend.position = "bottom")

- Line charts per confrontare l’andamento delle vendite in periodi storici differenti.

Creo una colonna anno-mese utile ai fini della creazione del grafico:

dati$yearmonth <- paste(year, month, sep = "-")

Converto la colonna AnnoMese in formato Date per avere un ordinamento corretto

dati$yearmonth <- as.Date(paste0(dati$yearmonth, "-01"))  

Grafico line-plot dei Volume

ggplot(data=dati)+
  geom_line(aes(x=yearmonth,y=volume, color= city, group = city),lwd=1)+
  geom_point(aes(x=yearmonth,y=volume, color=city, group = city))+
  labs(x="year-month",
       y="volume (10^6$)",
       color="city",
       title="Serie storica Volume")+
  theme_minimal()+
  theme(axis.text.x = element_text(angle = 90))+
  scale_x_date(date_labels = "%Y-%m", date_breaks = "3 month")+
  theme(legend.position = "bottom")

Grafico line-plot dei sales

ggplot(data=dati)+
  geom_line(aes(x=yearmonth,y=sales, color= city, group = city),lwd=1)+
  geom_point(aes(x=yearmonth,y=sales, color=city, group = city))+
  labs(x="year-month",
       y="Sales",
       color="city",
       title="Serie storica Vendite")+
  theme_minimal()+
  theme(axis.text.x = element_text(angle = 90))+
  scale_x_date(date_labels = "%Y-%m", date_breaks = "3 month")+
  theme(legend.position = "bottom")

9 Conclusioni

Fornisci una sintesi dei risultati ottenuti, facendo riferimento alle principali tendenze emerse e fornendo raccomandazioni basate sull’analisi.

Dalle analisi svolte sono emerse le seguenti osservazioni: - dalle serie storiche appare evidente che ci sia una stagionalità marcata: si hanno forti incrementi delle vendite nei mesi estivi.

Intensificare la campagna di annunci nella zona di Bryan-College Station potrebbe portare a maggiori vendite ad un prezzo medio più elevato. La città di Tyler sembra anche essa essere promettente in quanto ha un mercato in forte espansione ed i prezzi medi delle abitazioni sono ancora elevati.

In generare i mesi estivi sembrano essere il periodo migliore per mettere in vendita le abitazioni. Si potrebbero quindi intensificare le campagne di vendita nei mesi da Maggio ad Agosto.