Introduzione

Il presente lavoro analizza un dataset relativo al mercato immobiliare del Texas.

L’obiettivo è effettuare un’analisi descrittiva delle principali variabili, studiare posizione, variabilità e forma delle distribuzioni, analizzare le variabili nel tempo e per città e rappresentare graficamente i principali risultati.


1. Analisi delle variabili

1.1 Caricamento dei dati

library(tidyverse)
library(readxl)
library(e1071)
library(scales)

# Impostazione della cartella di lavoro
setwd("C:/Users/Rosse/Desktop/master/primo progetto/Analisi di Mercato_Texas")

# Importazione del dataset
realestate_texas <- read_csv("realestate_texas.csv")

1.2 Controllo del dataset

Verifichiamo le dimensioni del dataset, i nomi delle variabili, la struttura e le principali statistiche descrittive.

dim(realestate_texas)
## [1] 240   8
names(realestate_texas)
## [1] "city"             "year"             "month"            "sales"           
## [5] "volume"           "median_price"     "listings"         "months_inventory"
head(realestate_texas)
## # A tibble: 6 × 8
##   city      year month sales volume median_price listings months_inventory
##   <chr>    <dbl> <dbl> <dbl>  <dbl>        <dbl>    <dbl>            <dbl>
## 1 Beaumont  2010     1    83   14.2       163800     1533              9.5
## 2 Beaumont  2010     2   108   17.7       138200     1586             10  
## 3 Beaumont  2010     3   182   28.7       122400     1689             10.6
## 4 Beaumont  2010     4   200   26.8       123200     1708             10.6
## 5 Beaumont  2010     5   202   28.8       123100     1771             10.9
## 6 Beaumont  2010     6   189   27.2       122800     1803             11.1
str(realestate_texas)
## spc_tbl_ [240 × 8] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
##  $ city            : chr [1:240] "Beaumont" "Beaumont" "Beaumont" "Beaumont" ...
##  $ year            : num [1:240] 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 ...
##  $ month           : num [1:240] 1 2 3 4 5 6 7 8 9 10 ...
##  $ sales           : num [1:240] 83 108 182 200 202 189 164 174 124 150 ...
##  $ volume          : num [1:240] 14.2 17.7 28.7 26.8 28.8 ...
##  $ median_price    : num [1:240] 163800 138200 122400 123200 123100 ...
##  $ listings        : num [1:240] 1533 1586 1689 1708 1771 ...
##  $ months_inventory: num [1:240] 9.5 10 10.6 10.6 10.9 11.1 11.7 11.6 11.7 11.5 ...
##  - attr(*, "spec")=
##   .. cols(
##   ..   city = col_character(),
##   ..   year = col_double(),
##   ..   month = col_double(),
##   ..   sales = col_double(),
##   ..   volume = col_double(),
##   ..   median_price = col_double(),
##   ..   listings = col_double(),
##   ..   months_inventory = col_double()
##   .. )
##  - attr(*, "problems")=<externalptr>
summary(realestate_texas)
##      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

1.3 Controllo dei valori mancanti

missing_values <- colSums(is.na(realestate_texas))
missing_values
##             city             year            month            sales 
##                0                0                0                0 
##           volume     median_price         listings months_inventory 
##                0                0                0                0

Nel dataset non risultano valori mancanti.

1.4 Conversione delle variabili

La variabile city viene trattata come variabile qualitativa nominale.

Le variabili year e month vengono mantenute numeriche per consentire i calcoli, mentre viene creata una variabile qualitativa ordinata per rappresentare i mesi nei grafici.

realestate_texas$city <- as.factor(realestate_texas$city)

realestate_texas$month_factor <- factor(
  realestate_texas$month,
  levels = 1:12,
  labels = c(
    "January", "February", "March", "April",
    "May", "June", "July", "August",
    "September", "October", "November", "December"
  ),
  ordered = TRUE
)

1.5 Creazione della variabile temporale

Per poter analizzare l’andamento delle variabili nel tempo, viene costruita una variabile date.

realestate_texas$date <- as.Date(
  paste(
    realestate_texas$year,
    realestate_texas$month,
    "01",
    sep = "-"
  )
)

head(realestate_texas$date)
## [1] "2010-01-01" "2010-02-01" "2010-03-01" "2010-04-01" "2010-05-01"
## [6] "2010-06-01"

1.6 Classificazione delle variabili

Le variabili presenti nel dataset possono essere suddivise in:

  • city: variabile qualitativa nominale;
  • year: variabile temporale relativa all’anno;
  • month: variabile temporale relativa al mese;
  • sales: numero di vendite;
  • volume: volume delle vendite;
  • median_price: prezzo mediano;
  • listings: numero di annunci;
  • months_inventory: mesi di inventario.

Per la variabile qualitativa city è opportuno utilizzare una distribuzione di frequenza.

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

Frequenze relative

round(
  prop.table(table(realestate_texas$city)),
  4
)
## 
##              Beaumont Bryan-College Station                 Tyler 
##                  0.25                  0.25                  0.25 
##         Wichita Falls 
##                  0.25

Distribuzione per anno

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

Distribuzione per mese

table(realestate_texas$month_factor)
## 
##   January  February     March     April       May      June      July    August 
##        20        20        20        20        20        20        20        20 
## September   October  November  December 
##        20        20        20        20

2. Indici di posizione, variabilità e forma

Per le variabili quantitative vengono calcolati:

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

2.1 Funzione per il calcolo degli indici

calcola_statistiche <- function(x) {
  
  x <- x[!is.na(x)]
  
  c(
    Media = mean(x),
    Mediana = median(x),
    Minimo = min(x),
    Q1 = quantile(x, 0.25),
    Q3 = quantile(x, 0.75),
    Massimo = max(x),
    Range = max(x) - min(x),
    Varianza = var(x),
    Deviazione_Standard = sd(x),
    CV_percentuale = sd(x) / mean(x) * 100,
    Asimmetria = skewness(x),
    Curtosi = kurtosis(x)
  )
}

2.2 Calcolo degli indici

statistiche <- sapply(
  realestate_texas[variabili_quantitative],
  calcola_statistiche
)

statistiche <- round(statistiche, 3)

statistiche
##                        sales  volume  median_price   listings months_inventory
## Media                192.292  31.005    132665.417   1738.021            9.193
## Mediana              175.500  27.062    134500.000   1618.500            8.950
## Minimo                79.000   8.166     73800.000    743.000            3.400
## Q1.25%               127.000  17.660    117300.000   1026.500            7.800
## Q3.75%               247.000  40.893    150050.000   2056.000           10.950
## Massimo              423.000  83.547    180000.000   3296.000           14.900
## Range                344.000  75.381    106200.000   2553.000           11.500
## Varianza            6344.300 277.271 513572983.089 566568.966            5.307
## Deviazione_Standard   79.651  16.651     22662.149    752.708            2.304
## CV_percentuale        41.422  53.705        17.082     43.308           25.060
## Asimmetria             0.714   0.879        -0.362      0.645            0.041
## Curtosi               -0.336   0.151        -0.643     -0.810           -0.198

2.3 Confronto tra media e mediana

for (v in variabili_quantitative) {
  
  media <- mean(realestate_texas[[v]], na.rm = TRUE)
  mediana <- median(realestate_texas[[v]], na.rm = TRUE)
  
  cat("\nVariabile:", v, "\n")
  cat("Media:", round(media, 2), "\n")
  cat("Mediana:", round(mediana, 2), "\n")
  
  if (media > mediana) {
    cat(
      "Interpretazione: la media è superiore alla mediana, ",
      "possibile indicazione di asimmetria positiva.\n"
    )
    
  } else if (media < mediana) {
    cat(
      "Interpretazione: la media è inferiore alla mediana, ",
      "possibile indicazione di asimmetria negativa.\n"
    )
    
  } else {
    cat(
      "Interpretazione: media e mediana sono molto simili, ",
      "indicando una distribuzione relativamente simmetrica.\n"
    )
  }
}
## 
## Variabile: sales 
## Media: 192.29 
## Mediana: 175.5 
## Interpretazione: la media è superiore alla mediana,  possibile indicazione di asimmetria positiva.
## 
## Variabile: volume 
## Media: 31.01 
## Mediana: 27.06 
## Interpretazione: la media è superiore alla mediana,  possibile indicazione di asimmetria positiva.
## 
## Variabile: median_price 
## Media: 132665.4 
## Mediana: 134500 
## Interpretazione: la media è inferiore alla mediana,  possibile indicazione di asimmetria negativa.
## 
## Variabile: listings 
## Media: 1738.02 
## Mediana: 1618.5 
## Interpretazione: la media è superiore alla mediana,  possibile indicazione di asimmetria positiva.
## 
## Variabile: months_inventory 
## Media: 9.19 
## Mediana: 8.95 
## Interpretazione: la media è superiore alla mediana,  possibile indicazione di asimmetria positiva.

3. Variabilità e asimmetria

3.1 Coefficiente di variazione

Il coefficiente di variazione permette di confrontare la dispersione relativa di variabili espresse su scale differenti.

CV <- sapply(
  realestate_texas[variabili_quantitative],
  function(x) {
    sd(x, na.rm = TRUE) /
      mean(x, na.rm = TRUE) *
      100
  }
)

CV <- sort(CV, decreasing = TRUE)

round(CV, 3)
##           volume         listings            sales months_inventory 
##           53.705           43.308           41.422           25.060 
##     median_price 
##           17.082
variabile_max_CV <- names(CV)[1]

cat(
  "La variabile con la maggiore variabilità relativa è:",
  variabile_max_CV,
  "\n"
)
## La variabile con la maggiore variabilità relativa è: volume
cat(
  "Il suo coefficiente di variazione è:",
  round(CV[1], 2),
  "%\n"
)
## Il suo coefficiente di variazione è: 53.71 %

3.2 Deviazione standard

SD <- sapply(
  realestate_texas[variabili_quantitative],
  sd,
  na.rm = TRUE
)

round(SD, 3)
##            sales           volume     median_price         listings 
##           79.651           16.651        22662.149          752.708 
## months_inventory 
##            2.304

3.3 Asimmetria

asimmetria <- sapply(
  realestate_texas[variabili_quantitative],
  function(x) {
    skewness(x, na.rm = TRUE)
  }
)

round(asimmetria, 3)
##            sales           volume     median_price         listings 
##            0.714            0.879           -0.362            0.645 
## months_inventory 
##            0.041

La variabile con la maggiore asimmetria in valore assoluto viene individuata considerando il valore assoluto dell’indice di skewness.

variabile_max_asimmetria <-
  names(which.max(abs(asimmetria)))

valore_asimmetria <-
  asimmetria[variabile_max_asimmetria]

cat(
  "La variabile con la maggiore asimmetria in valore assoluto è:",
  variabile_max_asimmetria,
  "\n"
)
## La variabile con la maggiore asimmetria in valore assoluto è: volume
cat(
  "Indice di asimmetria:",
  round(valore_asimmetria, 3),
  "\n"
)
## Indice di asimmetria: 0.879

4. Classificazione del prezzo

La variabile median_price viene suddivisa in cinque classi utilizzando i quintili.

quantili_prezzo <- quantile(
  realestate_texas$median_price,
  probs = seq(0, 1, 0.2),
  na.rm = TRUE
)

quantili_prezzo
##     0%    20%    40%    60%    80%   100% 
##  73800 110000 130700 141220 152360 180000
breaks_prezzo <- unique(quantili_prezzo)

if (length(breaks_prezzo) < 2) {
  stop(
    "Non è possibile creare classi di prezzo."
  )
}

realestate_texas$price_class <- cut(
  realestate_texas$median_price,
  breaks = breaks_prezzo,
  include.lowest = TRUE,
  labels = c(
    "Molto Basso",
    "Basso",
    "Medio",
    "Alto",
    "Molto Alto"
  )
)

4.1 Distribuzione di frequenza

freq_price <- table(realestate_texas$price_class)

freq_price_rel <- prop.table(freq_price)

freq_price_percent <- freq_price_rel * 100

freq_price
## 
## Molto Basso       Basso       Medio        Alto  Molto Alto 
##          49          48          47          48          48
tabella_prezzo <- data.frame(
  Classe = names(freq_price),
  Frequenza = as.vector(freq_price),
  Frequenza_relativa =
    round(as.vector(freq_price_rel), 3),
  Percentuale =
    round(as.vector(freq_price_percent), 3)
)

tabella_prezzo
##        Classe Frequenza Frequenza_relativa Percentuale
## 1 Molto Basso        49              0.204      20.417
## 2       Basso        48              0.200      20.000
## 3       Medio        47              0.196      19.583
## 4        Alto        48              0.200      20.000
## 5  Molto Alto        48              0.200      20.000

4.2 Grafico a barre

grafico_classi_prezzo <- ggplot(
  realestate_texas,
  aes(x = price_class)
) +
  geom_bar(fill = "steelblue") +
  labs(
    title = "Distribuzione degli immobili per classe di prezzo",
    subtitle = "Classificazione basata sui quintili",
    x = "Classe di prezzo",
    y = "Frequenza"
  ) +
  theme_minimal() +
  theme(
    axis.text.x =
      element_text(angle = 45, hjust = 1)
  )

grafico_classi_prezzo

4.3 Indice di eterogeneità di Gini

p <- prop.table(freq_price)

Gini <- 1 - sum(p^2)

cat(
  "Indice di eterogeneità di Gini:",
  round(Gini, 3)
)
## Indice di eterogeneità di Gini: 0.8
k <- length(freq_price)

gini_norm <-
  Gini / ((k - 1) / k)

cat(
  "\nIndice di Gini normalizzato:",
  round(gini_norm, 3)
)
## 
## Indice di Gini normalizzato: 1

Un valore vicino a 0 indica una maggiore concentrazione delle osservazioni in poche classi, mentre valori più elevati indicano una maggiore eterogeneità nella distribuzione delle osservazioni tra le classi.


5. Calcolo delle probabilità

5.1 Probabilità di Beaumont

P_Beaumont <-
  mean(
    realestate_texas$city == "Beaumont",
    na.rm = TRUE
  )

cat(
  "P(city = Beaumont) =",
  round(P_Beaumont, 3),
  "\n"
)
## P(city = Beaumont) = 0.25
cat(
  "Percentuale =",
  round(P_Beaumont * 100, 2),
  "%"
)
## Percentuale = 25 %

5.2 Probabilità del mese di luglio

P_Luglio <-
  mean(
    realestate_texas$month == 7,
    na.rm = TRUE
  )

cat(
  "P(month = Luglio) =",
  round(P_Luglio, 3),
  "\n"
)
## P(month = Luglio) = 0.083
cat(
  "Percentuale =",
  round(P_Luglio * 100, 2),
  "%"
)
## Percentuale = 8.33 %

5.3 Probabilità di dicembre 2012

P_Dicembre_2012 <-
  mean(
    realestate_texas$month == 12 &
      realestate_texas$year == 2012,
    na.rm = TRUE
  )

cat(
  "P(month = Dicembre AND year = 2012) =",
  round(P_Dicembre_2012, 3),
  "\n"
)
## P(month = Dicembre AND year = 2012) = 0.017
cat(
  "Percentuale =",
  round(P_Dicembre_2012 * 100, 2),
  "%"
)
## Percentuale = 1.67 %

6. Creazione di nuove variabili

6.1 Valore totale stimato delle vendite

Il prodotto tra sales e median_price non rappresenta il valore reale delle singole transazioni, ma costituisce una stima del valore complessivo delle vendite.

realestate_texas$total_sales_value <-
  realestate_texas$sales *
  realestate_texas$median_price

6.2 Efficacia degli annunci

Viene costruito un indicatore descrittivo dato dal rapporto tra vendite e numero di annunci.

realestate_texas$listing_effectiveness <-
  realestate_texas$sales /
  realestate_texas$listings

realestate_texas$listing_effectiveness_pct <-
  realestate_texas$sales /
  realestate_texas$listings *
  100

Statistiche

summary(realestate_texas$total_sales_value)
##     Min.  1st Qu.   Median     Mean  3rd Qu.     Max. 
##  7173200 15270250 23501800 26570396 35216950 69557800
summary(
  realestate_texas$listing_effectiveness_pct
)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   5.014   8.980  10.963  11.874  13.492  38.713
media_eff <-
  mean(
    realestate_texas$listing_effectiveness_pct,
    na.rm = TRUE
  )

mediana_eff <-
  median(
    realestate_texas$listing_effectiveness_pct,
    na.rm = TRUE
  )

cat(
  "Media dell'efficacia degli annunci:",
  round(media_eff, 2),
  "%\n"
)
## Media dell'efficacia degli annunci: 11.87 %
cat(
  "Mediana dell'efficacia degli annunci:",
  round(mediana_eff, 2),
  "%"
)
## Mediana dell'efficacia degli annunci: 10.96 %

L’indicatore sales/listings deve essere interpretato come indicatore descrittivo e non come vera probabilità di vendita di un singolo immobile, poiché gli annunci possono rimanere presenti per più periodi.


7. Analisi condizionata

7.1 Analisi per città

summary_city <- realestate_texas %>%
  group_by(city) %>%
  summarise(
    n = n(),
    media_sales = mean(sales, na.rm = TRUE),
    sd_sales = sd(sales, na.rm = TRUE),
    media_price = mean(median_price, na.rm = TRUE),
    sd_price = sd(median_price, na.rm = TRUE),
    media_volume = mean(volume, na.rm = TRUE),
    sd_volume = sd(volume, na.rm = TRUE),
    media_listings = mean(listings, na.rm = TRUE),
    sd_listings = sd(listings, na.rm = TRUE),
    media_inventory =
      mean(months_inventory, na.rm = TRUE),
    sd_inventory =
      sd(months_inventory, na.rm = TRUE),
    media_total_value =
      mean(total_sales_value, na.rm = TRUE),
    .groups = "drop"
  )

summary_city
## # A tibble: 4 × 13
##   city        n media_sales sd_sales media_price sd_price media_volume sd_volume
##   <fct>   <int>       <dbl>    <dbl>       <dbl>    <dbl>        <dbl>     <dbl>
## 1 Beaumo…    60        177.     41.5     129988.   10105.         26.1      6.97
## 2 Bryan-…    60        206.     85.0     157488.    8852.         38.2     17.2 
## 3 Tyler      60        270.     62.0     141442.    9337.         45.8     13.1 
## 4 Wichit…    60        116.     22.2     101743.   11320.         13.9      3.24
## # ℹ 5 more variables: media_listings <dbl>, sd_listings <dbl>,
## #   media_inventory <dbl>, sd_inventory <dbl>, media_total_value <dbl>

7.2 Analisi per anno

summary_year <- realestate_texas %>%
  group_by(year) %>%
  summarise(
    n = n(),
    media_sales = mean(sales, na.rm = TRUE),
    sd_sales = sd(sales, na.rm = TRUE),
    media_price = mean(median_price, na.rm = TRUE),
    sd_price = sd(median_price, na.rm = TRUE),
    media_volume = mean(volume, na.rm = TRUE),
    sd_volume = sd(volume, na.rm = TRUE),
    media_listings = mean(listings, na.rm = TRUE),
    sd_listings = sd(listings, na.rm = TRUE),
    media_inventory =
      mean(months_inventory, na.rm = TRUE),
    sd_inventory =
      sd(months_inventory, na.rm = TRUE),
    media_total_value =
      mean(total_sales_value, na.rm = TRUE),
    .groups = "drop"
  )

summary_year
## # A tibble: 5 × 13
##    year     n media_sales sd_sales media_price sd_price media_volume sd_volume
##   <dbl> <int>       <dbl>    <dbl>       <dbl>    <dbl>        <dbl>     <dbl>
## 1  2010    48        169.     60.5     130192.   21822.         25.7      10.8
## 2  2011    48        164.     63.9     127854.   21318.         25.2      12.2
## 3  2012    48        186.     70.9     130077.   21432.         29.3      14.5
## 4  2013    48        212.     84.0     135723.   21708.         35.2      17.9
## 5  2014    48        231.     95.5     139481.   25625.         39.8      21.2
## # ℹ 5 more variables: media_listings <dbl>, sd_listings <dbl>,
## #   media_inventory <dbl>, sd_inventory <dbl>, media_total_value <dbl>

7.3 Analisi per mese

summary_month <- realestate_texas %>%
  group_by(month) %>%
  summarise(
    n = n(),
    media_sales = mean(sales, na.rm = TRUE),
    sd_sales = sd(sales, na.rm = TRUE),
    media_price = mean(median_price, na.rm = TRUE),
    sd_price = sd(median_price, na.rm = TRUE),
    media_volume = mean(volume, na.rm = TRUE),
    sd_volume = sd(volume, na.rm = TRUE),
    media_listings = mean(listings, na.rm = TRUE),
    sd_listings = sd(listings, na.rm = TRUE),
    media_inventory =
      mean(months_inventory, na.rm = TRUE),
    sd_inventory =
      sd(months_inventory, na.rm = TRUE),
    media_total_value =
      mean(total_sales_value, na.rm = TRUE),
    .groups = "drop"
  )

summary_month
## # A tibble: 12 × 13
##    month     n media_sales sd_sales media_price sd_price media_volume sd_volume
##    <dbl> <int>       <dbl>    <dbl>       <dbl>    <dbl>        <dbl>     <dbl>
##  1     1    20        127.     43.4      124250   25151.         19.0      8.37
##  2     2    20        141.     51.1      130075   22823.         21.7     10.1 
##  3     3    20        189.     59.2      127415   23442.         29.4     12.0 
##  4     4    20        212.     65.4      131490   21458.         33.3     14.5 
##  5     5    20        239.     83.1      134485   18796.         39.7     19.0 
##  6     6    20        244.     95.0      137620   19231.         41.3     21.1 
##  7     7    20        236.     96.3      134750   21945.         39.1     21.4 
##  8     8    20        231.     79.2      136675   22488.         38.0     18.0 
##  9     9    20        182.     72.5      134040   24344.         29.6     15.2 
## 10    10    20        180.     75.0      133480   26358.         29.1     15.1 
## 11    11    20        157.     55.5      134305   24691.         24.8     11.2 
## 12    12    20        169.     60.7      133400   22810.         27.1     12.6 
## # ℹ 5 more variables: media_listings <dbl>, sd_listings <dbl>,
## #   media_inventory <dbl>, sd_inventory <dbl>, media_total_value <dbl>

7.4 Analisi per città e anno

summary_city_year <- realestate_texas %>%
  group_by(city, year) %>%
  summarise(
    n = n(),
    media_sales = mean(sales, na.rm = TRUE),
    sd_sales = sd(sales, na.rm = TRUE),
    media_price = mean(median_price, na.rm = TRUE),
    sd_price = sd(median_price, na.rm = TRUE),
    media_total_value =
      mean(total_sales_value, na.rm = TRUE),
    .groups = "drop"
  )

summary_city_year
## # A tibble: 20 × 8
##    city   year     n media_sales sd_sales media_price sd_price media_total_value
##    <fct> <dbl> <int>       <dbl>    <dbl>       <dbl>    <dbl>             <dbl>
##  1 Beau…  2010    12        156.     36.9     133117.   13354.         20475667.
##  2 Beau…  2011    12        144      22.7     125642.    9603.         18189383.
##  3 Beau…  2012    12        172.     28.4     126533.    7973.         21881350 
##  4 Beau…  2013    12        201.     37.7     132400     7785.         26740500 
##  5 Beau…  2014    12        214.     36.5     132250     9835.         28504700 
##  6 Brya…  2010    12        168.     70.8     153533.    5474.         25539775 
##  7 Brya…  2011    12        167.     62.2     151417.    3709.         25259617.
##  8 Brya…  2012    12        197.     74.3     153567.    7096.         30297950 
##  9 Brya…  2013    12        238.     95.8     159392.    5429.         38162042.
## 10 Brya…  2014    12        260.     86.7     169533.    7776.         44115525 
## 11 Tyler  2010    12        228.     49.0     135175     4782.         30812450 
## 12 Tyler  2011    12        239.     49.6     136217.    8505.         32775808.
## 13 Tyler  2012    12        264.     46.4     139250     7983.         36918483.
## 14 Tyler  2013    12        287.     53.0     146100     6726.         42223217.
## 15 Tyler  2014    12        332.     56.9     150467.    8543.         50099317.
## 16 Wich…  2010    12        123.     26.6      98942.   10361.         12328017.
## 17 Wich…  2011    12        106.     19.8      98142.   10632.         10531908.
## 18 Wich…  2012    12        112.     14.2     100958.   12347.         11409800 
## 19 Wich…  2013    12        121.     26.0     105000    10383.         12722517.
## 20 Wich…  2014    12        117      21.1     105675    12444.         12419900

7.5 Analisi per città, anno e mese

summary_city_year_month <- realestate_texas %>%
  group_by(city, year, month) %>%
  summarise(
    n = n(),
    media_sales = mean(sales, na.rm = TRUE),
    sd_sales = sd(sales, na.rm = TRUE),
    media_price = mean(median_price, na.rm = TRUE),
    sd_price = sd(median_price, na.rm = TRUE),
    media_total_value =
      mean(total_sales_value, na.rm = TRUE),
    .groups = "drop"
  )

summary_city_year_month
## # A tibble: 240 × 9
##    city      year month     n media_sales sd_sales media_price sd_price
##    <fct>    <dbl> <dbl> <int>       <dbl>    <dbl>       <dbl>    <dbl>
##  1 Beaumont  2010     1     1          83       NA      163800       NA
##  2 Beaumont  2010     2     1         108       NA      138200       NA
##  3 Beaumont  2010     3     1         182       NA      122400       NA
##  4 Beaumont  2010     4     1         200       NA      123200       NA
##  5 Beaumont  2010     5     1         202       NA      123100       NA
##  6 Beaumont  2010     6     1         189       NA      122800       NA
##  7 Beaumont  2010     7     1         164       NA      124300       NA
##  8 Beaumont  2010     8     1         174       NA      136800       NA
##  9 Beaumont  2010     9     1         124       NA      121100       NA
## 10 Beaumont  2010    10     1         150       NA      138500       NA
## # ℹ 230 more rows
## # ℹ 1 more variable: media_total_value <dbl>

8. Analisi grafica

8.1 Boxplot del prezzo mediano per città

grafico_box_price <- ggplot(
  realestate_texas,
  aes(
    x = city,
    y = median_price
  )
) +
  geom_boxplot(
    fill = "steelblue",
    alpha = 0.7
  ) +
  labs(
    title = "Distribuzione del prezzo mediano per città",
    x = "Città",
    y = "Prezzo mediano"
  ) +
  theme_minimal() +
  theme(
    axis.text.x =
      element_text(angle = 45, hjust = 1)
  )

grafico_box_price

Il boxplot permette di confrontare mediana, quartili, dispersione e possibili valori anomali del prezzo tra le diverse città.

8.2 Valore totale delle vendite per città

grafico_box_value_city <- ggplot(
  realestate_texas,
  aes(
    x = city,
    y = total_sales_value
  )
) +
  geom_boxplot(
    fill = "darkorange",
    alpha = 0.7
  ) +
  scale_y_continuous(
    labels = label_number(
      big.mark = ".",
      decimal.mark = ","
    )
  ) +
  labs(
    title = "Distribuzione del valore totale stimato delle vendite",
    x = "Città",
    y = "Valore totale stimato"
  ) +
  theme_minimal() +
  theme(
    axis.text.x =
      element_text(angle = 45, hjust = 1)
  )

grafico_box_value_city

8.3 Valore totale delle vendite per anno

grafico_box_value_year <- ggplot(
  realestate_texas,
  aes(
    x = factor(year),
    y = total_sales_value
  )
) +
  geom_boxplot(
    fill = "seagreen",
    alpha = 0.7
  ) +
  labs(
    title = "Distribuzione del valore totale stimato per anno",
    x = "Anno",
    y = "Valore totale stimato"
  ) +
  theme_minimal()

grafico_box_value_year

8.4 Valore totale per città e anno

grafico_box_city_year <- ggplot(
  realestate_texas,
  aes(
    x = city,
    y = total_sales_value,
    fill = factor(year)
  )
) +
  geom_boxplot() +
  labs(
    title = "Valore totale delle vendite per città e anno",
    x = "Città",
    y = "Valore totale stimato",
    fill = "Anno"
  ) +
  theme_minimal() +
  theme(
    axis.text.x =
      element_text(angle = 45, hjust = 1)
  )

grafico_box_city_year

8.5 Facet per anno

grafico_box_facet_year <- ggplot(
  realestate_texas,
  aes(
    x = city,
    y = total_sales_value
  )
) +
  geom_boxplot(
    fill = "mediumpurple",
    alpha = 0.7
  ) +
  facet_wrap(~year) +
  labs(
    title =
      "Valore totale delle vendite per città nei diversi anni",
    x = "Città",
    y = "Valore totale stimato"
  ) +
  theme_minimal() +
  theme(
    axis.text.x =
      element_text(angle = 45, hjust = 1)
  )

grafico_box_facet_year


9. Vendite per mese e città

Creiamo una tabella contenente il totale delle vendite per mese e città.

sales_month_city <- realestate_texas %>%
  group_by(
    month,
    month_factor,
    city
  ) %>%
  summarise(
    total_sales =
      sum(sales, na.rm = TRUE),
    .groups = "drop"
  )

sales_month_city
## # A tibble: 48 × 4
##    month month_factor city                  total_sales
##    <dbl> <ord>        <fct>                       <dbl>
##  1     1 January      Beaumont                      608
##  2     1 January      Bryan-College Station         591
##  3     1 January      Tyler                         907
##  4     1 January      Wichita Falls                 442
##  5     2 February     Beaumont                      677
##  6     2 February     Bryan-College Station         628
##  7     2 February     Tyler                        1058
##  8     2 February     Wichita Falls                 454
##  9     3 March        Beaumont                      855
## 10     3 March        Bryan-College Station         949
## # ℹ 38 more rows

9.1 Grafico a barre

grafico_bar_month_city <- ggplot(
  sales_month_city,
  aes(
    x = month_factor,
    y = total_sales,
    fill = city
  )
) +
  geom_col(
    position = "stack"
  ) +
  labs(
    title = "Totale delle vendite per mese e città",
    x = "Mese",
    y = "Totale vendite",
    fill = "Città"
  ) +
  theme_minimal() +
  theme(
    axis.text.x =
      element_text(angle = 45, hjust = 1)
  )

grafico_bar_month_city

9.2 Barre normalizzate

grafico_bar_normalized <- ggplot(
  sales_month_city,
  aes(
    x = month_factor,
    y = total_sales,
    fill = city
  )
) +
  geom_col(
    position = "fill"
  ) +
  scale_y_continuous(
    labels = percent
  ) +
  labs(
    title = "Composizione percentuale delle vendite per mese",
    x = "Mese",
    y = "Percentuale",
    fill = "Città"
  ) +
  theme_minimal() +
  theme(
    axis.text.x =
      element_text(angle = 45, hjust = 1)
  )

grafico_bar_normalized


10. Analisi temporale

10.1 Vendite per mese, città e anno

sales_month_city_year <- realestate_texas %>%
  group_by(
    year,
    month,
    month_factor,
    city
  ) %>%
  summarise(
    total_sales =
      sum(sales, na.rm = TRUE),
    .groups = "drop"
  )

10.2 Grafico con facet per anno

grafico_bar_year <- ggplot(
  sales_month_city_year,
  aes(
    x = month_factor,
    y = total_sales,
    fill = city
  )
) +
  geom_col() +
  facet_wrap(~year) +
  labs(
    title = "Vendite mensili per città e anno",
    x = "Mese",
    y = "Totale vendite",
    fill = "Città"
  ) +
  theme_minimal() +
  theme(
    axis.text.x =
      element_text(angle = 45, hjust = 1)
  )

grafico_bar_year

10.3 Barre normalizzate per anno

grafico_bar_year_normalized <- ggplot(
  sales_month_city_year,
  aes(
    x = month_factor,
    y = total_sales,
    fill = city
  )
) +
  geom_col(position = "fill") +
  facet_wrap(~year) +
  scale_y_continuous(
    labels = percent
  ) +
  labs(
    title =
      "Composizione percentuale delle vendite per mese e anno",
    x = "Mese",
    y = "Percentuale",
    fill = "Città"
  ) +
  theme_minimal() +
  theme(
    axis.text.x =
      element_text(angle = 45, hjust = 1)
  )

grafico_bar_year_normalized


11. Andamento delle vendite nel tempo

sales_time_city <- realestate_texas %>%
  group_by(date, city) %>%
  summarise(
    total_sales =
      sum(sales, na.rm = TRUE),
    .groups = "drop"
  )
grafico_line_sales <- ggplot(
  sales_time_city,
  aes(
    x = date,
    y = total_sales,
    color = city,
    group = city
  )
) +
  geom_line(linewidth = 1) +
  labs(
    title = "Andamento delle vendite nel tempo",
    x = "Periodo",
    y = "Vendite",
    color = "Città"
  ) +
  theme_minimal()

grafico_line_sales

Il line chart permette di analizzare l’evoluzione temporale delle vendite e di individuare eventuali variazioni o fenomeni stagionali.


12. Evoluzione del prezzo mediano

price_time_city <- realestate_texas %>%
  group_by(date, city) %>%
  summarise(
    avg_median_price =
      mean(median_price, na.rm = TRUE),
    .groups = "drop"
  )
grafico_line_price <- ggplot(
  price_time_city,
  aes(
    x = date,
    y = avg_median_price,
    color = city,
    group = city
  )
) +
  geom_line(linewidth = 1) +
  geom_point(size = 1.5) +
  labs(
    title = "Evoluzione del prezzo mediano nel tempo",
    x = "Periodo",
    y = "Prezzo mediano",
    color = "Città"
  ) +
  theme_minimal()

grafico_line_price


13. Prezzo mediano medio per anno

price_year_city <- realestate_texas %>%
  group_by(year, city) %>%
  summarise(
    avg_price =
      mean(median_price, na.rm = TRUE),
    .groups = "drop"
  )
grafico_line_price_year <- ggplot(
  price_year_city,
  aes(
    x = year,
    y = avg_price,
    color = city,
    group = city
  )
) +
  geom_line(linewidth = 1) +
  geom_point(size = 2) +
  labs(
    title = "Prezzo mediano medio per città e anno",
    x = "Anno",
    y = "Prezzo mediano medio",
    color = "Città"
  ) +
  theme_minimal()

grafico_line_price_year


14. Evoluzione dell’efficacia degli annunci

effectiveness_time_city <- realestate_texas %>%
  group_by(date, city) %>%
  summarise(
    effectiveness =
      mean(
        listing_effectiveness_pct,
        na.rm = TRUE
      ),
    .groups = "drop"
  )
grafico_line_effectiveness <- ggplot(
  effectiveness_time_city,
  aes(
    x = date,
    y = effectiveness,
    color = city,
    group = city
  )
) +
  geom_line(linewidth = 1) +
  labs(
    title = "Evoluzione dell'efficacia degli annunci",
    x = "Periodo",
    y = "Vendite / annunci (%)",
    color = "Città"
  ) +
  theme_minimal()

grafico_line_effectiveness


15. Confronto delle vendite medie per città

grafico_media_sales_city <- ggplot(
  summary_city,
  aes(
    x = reorder(city, media_sales),
    y = media_sales
  )
) +
  geom_col(fill = "steelblue") +
  coord_flip() +
  labs(
    title = "Vendite medie per città",
    x = "Città",
    y = "Vendite medie"
  ) +
  theme_minimal()

grafico_media_sales_city


16. Confronto dei prezzi medi per città

grafico_media_price_city <- ggplot(
  summary_city,
  aes(
    x = reorder(city, media_price),
    y = media_price
  )
) +
  geom_col(fill = "darkorange") +
  coord_flip() +
  labs(
    title = "Prezzo mediano medio per città",
    x = "Città",
    y = "Prezzo mediano medio"
  ) +
  theme_minimal()

grafico_media_price_city


17. Confronto delle vendite medie per anno

grafico_sales_year <- ggplot(
  summary_year,
  aes(
    x = factor(year),
    y = media_sales
  )
) +
  geom_col(fill = "seagreen") +
  labs(
    title = "Vendite medie per anno",
    x = "Anno",
    y = "Vendite medie"
  ) +
  theme_minimal()

grafico_sales_year


18. Conclusioni

L’analisi descrittiva mostra differenze tra le città per quanto riguarda prezzi, vendite, volume degli scambi, numero di annunci e disponibilità di inventario.

Il confronto dei coefficienti di variazione consente di identificare la variabile caratterizzata dalla maggiore dispersione relativa rispetto alla propria media.

L’indice di asimmetria permette di individuare eventuali distribuzioni non simmetriche. Una skewness positiva indica una coda verso i valori elevati, mentre una skewness negativa indica una coda verso i valori più bassi.

I boxplot consentono di confrontare mediana, dispersione, quartili e possibili valori anomali del prezzo tra le diverse città.

Il confronto del valore totale stimato delle vendite per città e anno permette di analizzare differenze sia territoriali sia temporali.

Le barre sovrapposte mostrano il volume complessivo delle vendite per mese e consentono di confrontare il contributo delle diverse città. Le barre normalizzate mostrano invece la composizione percentuale del totale.

I line chart permettono di analizzare l’evoluzione temporale delle vendite e dei prezzi, distinguendo eventuali fenomeni stagionali da variazioni più persistenti.

L’indicatore sales/listings è stato utilizzato come proxy dell’efficacia degli annunci. Deve tuttavia essere interpretato con cautela, poiché gli annunci possono rimanere disponibili per più periodi.

Infine, il valore totale delle vendite è una stima ottenuta come prodotto tra numero di vendite e prezzo mediano e non rappresenta necessariamente il valore effettivo delle singole transazioni.

Riepilogo dei principali risultati

cat(
  "Numero totale di osservazioni:",
  nrow(realestate_texas),
  "\n"
)
## Numero totale di osservazioni: 240
cat(
  "Numero di città:",
  nlevels(realestate_texas$city),
  "\n"
)
## Numero di città: 4
cat(
  "Numero di anni:",
  length(unique(realestate_texas$year)),
  "\n\n"
)
## Numero di anni: 5
cat(
  "Variabile con maggiore variabilità relativa:\n"
)
## Variabile con maggiore variabilità relativa:
cat(
  variabile_max_CV,
  " - CV = ",
  round(CV[1], 2),
  "%\n\n",
  sep = ""
)
## volume - CV = 53.71%
cat(
  "Variabile con maggiore asimmetria:\n"
)
## Variabile con maggiore asimmetria:
cat(
  variabile_max_asimmetria,
  " - skewness = ",
  round(valore_asimmetria, 3),
  "\n\n",
  sep = ""
)
## volume - skewness = 0.879
cat(
  "Indice di eterogeneità di Gini:\n",
  round(Gini, 4),
  "\n\n"
)
## Indice di eterogeneità di Gini:
##  0.8
cat(
  "Probabilità di Beaumont:\n",
  round(P_Beaumont * 100, 2),
  "%\n\n"
)
## Probabilità di Beaumont:
##  25 %
cat(
  "Probabilità di Luglio:\n",
  round(P_Luglio * 100, 2),
  "%\n\n"
)
## Probabilità di Luglio:
##  8.33 %
cat(
  "Probabilità di Dicembre 2012:\n",
  round(P_Dicembre_2012 * 100, 2),
  "%"
)
## Probabilità di Dicembre 2012:
##  1.67 %