“Real Estate Texas.csv”

Il dataset contiene le seguenti variabili:

city: città di riferimento

year: anno di riferimento

month: mese di riferimento

sales: numero totale di vendite

volume: valore totale delle vendite (in milioni di dollari)

median_price: prezzo mediano di vendita (in dollari)

listings: numero totale di annunci attivi

months_inventory: quantità di tempo necessaria per vendere tutte le inserzioni correnti, espresso in mesi

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
library(ggplot2)
library(gghalves)
library(moments)
library(lubridate)
## 
## Attaching package: 'lubridate'
## The following objects are masked from 'package:base':
## 
##     date, intersect, setdiff, union
library(scales)

0. Caricamento File

FILE_CSV <- ".//realestate_texas.csv"

dati_re <- read.csv( FILE_CSV, sep=",", head=TRUE)

attach(dati_re)

1. Analisi delle variabili

Identifica e descrivi il tipo di variabili statistiche presenti nel dataset.

Valuta come gestire le variabili che sottintendono una dimensione tempo

e commenta sul tipo di analisi che può essere condotta su ciascuna variabile.

dim(dati_re)
## [1] 240   8

Abbiamo 8 variabili e 240 osservazioni.

1.1. CITY: variabile categorica

Analizzo la dimensione di questa variabile qualitativa per capire come usarla poi.

city_items <- dati_re%>%select(city)%>%distinct(city)

length(city_items$city)
## [1] 4

L’insieme delle osservazioni è riferito a 4 città diverse. Questo è un valore tale da poter usare poi la variabile city come variabile di raggruppamento.

Vediamo i valori di City

city_items$city
## [1] "Beaumont"              "Bryan-College Station" "Tyler"                
## [4] "Wichita Falls"

1.2. YEAR e MONTH: variabili temporali.

Ne verifico l’arco temporale coperto.

range(year)
## [1] 2010 2014

Abbiamo osservazioni che ricoprono gli anni dal 2010 al 2014.

range(month)
## [1]  1 12

Abbiamo dati per tutto l’arco dell’anno.

Poi costruisco una variabile date

dati_re$date <- make_date(year = year, month = month, day = 1)

1.3. SALES, VOLUME, LISTING, MEDIAN_PRICE, MONTHS_INVENTORY: variabili quantitative

variabili continue in funzione del tempo: sono già espressione di raggruppamenti temporali sul mese.

1.3.1. Isolo le variabili quantitative

Isolo le variabili quantitative per poter successivamente calcolare i vari indici.

dati_y <- dati_re%>%
  select(sales, volume, median_price, listings, months_inventory)

1.3.2. Andamenti delle variabili continue come serie temporali

Distribuzione numero totale di Vendite per città

(#fig:plot_01)Distribuzione numero totale di Vendite per città

La vaiabile sales (vedi in @ref(fig:plot_01)) ha un andamento periodico nell’arco dell’anno, con tendenza in crescita nell’avanzare degli anni

Figura_02: Distribuzione Volume di Vendite per città

(#fig:plot_02)Figura_02: Distribuzione Volume di Vendite per città

La vaiabile volume ha un andamento periodico nell’arco dell’anno, con tendenza in crescita nell’avanzare degli anni

La vaiabile listings ha un andamento periodico nell’arco dell’anno, con tendenza negativa nell’avanzare degli anni

La vaiabile months_inventory ha un andamento periodico nell’arco dell’anno, con tendenza negativa nell’avanzare degli anni

2. Indici di posizione, variabilità e forma

Calcola Indici di posizione, variabilità e forma per tutte le variabili per

le quali ha senso farlo, per le altre crea una distribuzione di frequenza.

Infine, commenta tutto brevemente.

n_obs <- length(volume)

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

summarize_indexes <- function(x) {
  return (
    cbind( mean = mean(x), var = var(x), sd = sd(x), sigma = coeff_var(x), skeness = skewness(x), k = kurtosis(x) - 3)
    
          )
}
summary(dati_y)
##      sales           volume        median_price       listings   
##  Min.   : 79.0   Min.   : 8.166   Min.   : 73800   Min.   : 743  
##  1st Qu.:127.0   1st Qu.:17.660   1st Qu.:117300   1st Qu.:1026  
##  Median :175.5   Median :27.062   Median :134500   Median :1618  
##  Mean   :192.3   Mean   :31.005   Mean   :132665   Mean   :1738  
##  3rd Qu.:247.0   3rd Qu.:40.893   3rd Qu.:150050   3rd Qu.:2056  
##  Max.   :423.0   Max.   :83.547   Max.   :180000   Max.   :3296  
##  months_inventory
##  Min.   : 3.400  
##  1st Qu.: 7.800  
##  Median : 8.950  
##  Mean   : 9.193  
##  3rd Qu.:10.950  
##  Max.   :14.900
indexes <- data.frame(
  media = sapply(dati_y, mean),
  varianza = sapply(dati_y, var),
  Deviazione_Std = sapply(dati_y, sd),
  Coeff_varianza = sapply(dati_y, coeff_var),
  Asimmetria = sapply(dati_y, skewness),
  Curtosi = sapply(dati_y, kurtosis) -3
)
indexes
##                         media     varianza Deviazione_Std Coeff_varianza
## sales               192.29167 6.344300e+03      79.651111       41.42203
## volume               31.00519 2.772707e+02      16.651447       53.70536
## median_price     132665.41667 5.135730e+08   22662.148687       17.08218
## listings           1738.02083 5.665690e+05     752.707756       43.30833
## months_inventory      9.19250 5.306889e+00       2.303669       25.06031
##                   Asimmetria    Curtosi
## sales             0.71810402 -0.3131764
## volume            0.88474203  0.1769870
## median_price     -0.36455288 -0.6229618
## listings          0.64949823 -0.7917900
## months_inventory  0.04097527 -0.1744475

2.1. Commenti

Per la variabile sales si noti che fra il terzo quartile e il valore massimo che una differenza alta (423.0 - 247.0 = 176) in rapporto alla differenza fra il terzo quartile e il valore minimo (247.0 - 79.0 = 168). Questo anticipa che potremmo trovare molti outliers. E anticipa il valore alto di deviazione standard(79) e di coefficiente di varianza(41.4).

La variabile Volume con un coefficiente di varianza 53.7 ha il valore più alto. Inoltre con un’assimetria di 0.884742 quindi positiva, prevede di comprendere più valori alti. Con una curtosi di 0.176987 dovremmo avere una distribuzione leptocurtica cioè più allungata

Per la varibile listing si possono fare considerazioni simili alla variabile sales vista l’equidistanza del terzo quartile dal minimo e dal massimo.

3. Identificazione delle variabili con maggiore variabilità e asimmetria

Determina: - Qual è la variabile con la più alta variabilità - Qual è la variabile con la distribuzione più asimmetrica Spiega come sei giunto a queste conclusioni e fornisci considerazioni statistiche.

3.1. Analisi per variabile volume

Sulla base delle considerazioni nella sezione precedente, ho individuato le variabile volume, di cui abbiamo isolato gli indici.

summary(volume)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   8.166  17.660  27.062  31.005  40.893  83.547
summarize_indexes(volume)
##          mean      var       sd    sigma  skeness        k
## [1,] 31.00519 277.2707 16.65145 53.70536 0.884742 0.176987

Proviamo a ricalcolare gli indici di posizione, variabilità e assimmetria per città

dati_re %>%
  group_by(city) %>%
  summarise( 
    mediana = median(volume),
    media = mean(volume) ,
    dev.st = sd(volume) ,
    index.var = coeff_var(volume),
    skewness = skewness(volume),
    kurtosis = kurtosis(volume) - 3
  )
## # A tibble: 4 × 7
##   city                  mediana media dev.st index.var skewness kurtosis
##   <chr>                   <dbl> <dbl>  <dbl>     <dbl>    <dbl>    <dbl>
## 1 Beaumont                 25.6  26.1   6.97      26.7    0.363  -0.358 
## 2 Bryan-College Station    33.6  38.2  17.2       45.2    0.856  -0.0797
## 3 Tyler                    45.1  45.8  13.1       28.6    0.353  -0.389 
## 4 Wichita Falls            13.7  13.9   3.24      23.3    0.193  -0.902

E’ evidente che i dati della città di Bryan-College Station condizionano l’insieme avendo valori di indice di variabilità che si discostano dagli altri.

4. Creazione di classi per una variabile quantitativa

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

in classi. Crea una distribuzione di frequenze e rappresenta i dati con un

grafico a barre. Calcola. l’indice di eterogeneità Gini e discuti i risultati.

4.1. Analisi per classi della variabile volume

dati_re$volume_CL <- cut(dati_re$volume,
                      breaks = c(5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85) )
ni = table(dati_re$volume_CL)
fi = table(dati_re$volume_CL) / n_obs
NI = cumsum(ni)
FI = NI / n_obs

distr_freq_volume <- as.data.frame( cbind( ni, fi, NI, FI ) )
etichette <- paste(rownames(distr_freq_volume),
                   round(distr_freq_volume$fi*100,
                         digits = 2),
                   "%")

Interessante il contributo delle varie città che evidenzia caratterestiche diverse. il numero non elevatissimo di osservazioni scoraggia però di continuare a studiare i singoli contributi separatamente.

gini.indexes <- function(x) {
  ni = table(x)
  fi = ni / length(x)
  f2 = fi^2
  J = length(ni)
  gini = 1 - sum(f2)
  gini.normalizzato = gini / ((J-1)/J)
  return ( gini.normalizzato)
}

gini.indexes(dati_re$volume_CL)
## [1] 0.9621111

4.2. Analisi per classi della variabile sales

dati_re$sales_CL <- cut(dati_re$sales,
                      breaks = c(75, 100, 125, 150, 175, 200, 225, 250, 275, 300, 325, 350, 375, 400, 425) )
ni = table(dati_re$sales_CL)
fi = table(dati_re$sales_CL) / n_obs
NI = cumsum(ni)
FI = NI / n_obs

distr_freq_sales <- as.data.frame( cbind( ni, fi, NI, FI ) )

gini.indexes(dati_re$sales_CL)
## [1] 0.9673985

5. Calcolo della probabilità

Qual è la probabilità che, presa una riga a caso di questo dataset, essa riporti la città “Beaumont”? E la probabilità che riporti il mese di Luglio? E la probabilità che riporti il mese di dicembre 2012?

5.1. Probabilità che una riga a caso riporti la città Beaumont

n_beaumont_obs <- dati_re%>%
                    filter( city == 'Beaumont')%>%
                    count()

n_tot <- length(city)

P_Beaumont <- n_beaumont_obs$n / n_tot
percent( P_Beaumont, accuracy = 1)
## [1] "25%"
paste( round(P_Beaumont*100, digits = 2), "%")
## [1] "25 %"

I due valori formattati diversamente non differiscono

5.2. Probabilità che una riga a caso riporti il mese di luglio

n_july_obs <- dati_re%>%
                    filter( month == 7)%>%
                    count()

n_tot <- length(month)

P_july <- n_july_obs$n / n_tot
percent( P_july, accuracy = 1)
## [1] "8%"
paste( round(P_july*100, digits = 2), "%")
## [1] "8.33 %"

I due valori formattati diversamente differiscono

5.3. Probabilità che una riga a caso riporti il mese di dicembre 2012

n_dic_2012_obs <- dati_re%>%
  filter( month == 12 & year == 2012)%>%
  count()

P_dic_2012 <- n_dic_2012_obs$n / n_tot
percent( P_dic_2012, accuracy = 1)
## [1] "2%"
paste( round(P_dic_2012*100, digits = 2), "%")
## [1] "1.67 %"

I due valori formattati diversamente differiscono

6. Creazione di nuove variabili

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

Prova a creare una colonna che misuri l’efficacia degli annunci di vendita. Commenta e discuti i risultati.

6.1. Prezzo medio degli immobili

dati_re$mean_price <- volume / sales

6.2. Efficienza degli annunci di vendita

dati_re$listings_eff <- months_inventory / listings

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.

7.1. Per CIttà

dati_re %>%
  group_by(city) %>%
  summarise( 
    min = min(sales),
    max = max(sales),
    media = mean(sales) ,
    dev.st = sd(sales) ,
    index.var = coeff_var(sales),
    skewness = skewness(sales),
    kurtosis = kurtosis(sales) - 3
  )
## # A tibble: 4 × 8
##   city                    min   max media dev.st index.var skewness kurtosis
##   <chr>                 <int> <int> <dbl>  <dbl>     <dbl>    <dbl>    <dbl>
## 1 Beaumont                 83   273  177.   41.5      23.4    0.188   -0.162
## 2 Bryan-College Station    89   403  206.   85.0      41.3    0.652   -0.604
## 3 Tyler                   143   423  270.   62.0      23.0    0.139   -0.396
## 4 Wichita Falls            79   167  116.   22.2      19.1    0.316   -0.592

7.2. Per Anno

dati_re %>%
  group_by(year) %>%
  summarise( 
    min = min(sales),
    max = max(sales),
    media = mean(sales) ,
    dev.st = sd(sales) ,
    index.var = coeff_var(sales),
    skewness = skewness(sales),
    kurtosis = kurtosis(sales) - 3
  )
## # A tibble: 5 × 8
##    year   min   max media dev.st index.var skewness kurtosis
##   <int> <int> <int> <dbl>  <dbl>     <dbl>    <dbl>    <dbl>
## 1  2010    83   316  169.   60.5      35.9    0.588   -0.507
## 2  2011    79   313  164.   63.9      38.9    0.730   -0.572
## 3  2012    90   322  186.   70.9      38.1    0.521   -1.06 
## 4  2013    79   402  212.   84.0      39.6    0.482   -0.753
## 5  2014    89   423  231.   95.5      41.4    0.304   -1.03

7.3. Per Mese

dati_re %>%
  group_by(month) %>%
  summarise( 
    min = min(sales),
    max = max(sales),
    media = mean(sales) ,
    dev.st = sd(sales) ,
    index.var = coeff_var(sales),
    skewness = skewness(sales),
    kurtosis = kurtosis(sales) - 3
  )
## # A tibble: 12 × 8
##    month   min   max media dev.st index.var skewness kurtosis
##    <int> <int> <int> <dbl>  <dbl>     <dbl>    <dbl>    <dbl>
##  1     1    79   238  127.   43.4      34.1   0.872    0.152 
##  2     2    79   244  141.   51.1      36.3   0.703   -0.799 
##  3     3   102   298  189.   59.2      31.2   0.494   -0.950 
##  4     4   111   323  212.   65.4      30.9   0.217   -1.05  
##  5     5   102   388  239.   83.1      34.8  -0.0122  -1.08  
##  6     6   111   423  244.   95.0      39.0   0.0937  -1.11  
##  7     7   104   403  236.   96.3      40.8   0.485   -1.07  
##  8     8   123   357  231.   79.2      34.2   0.0763  -1.42  
##  9     9    95   361  182.   72.5      39.8   0.846   -0.118 
## 10    10    97   369  180.   75.0      41.7   0.855    0.0789
## 11    11    93   300  157.   55.5      35.4   0.912    0.474 
## 12    12    81   332  169.   60.7      35.9   0.794    0.583

Non ha molto senso il calcolo degli indici per mese con osservazioni che coprono solo 5 anni.

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à.<>

    • Grafici a barre per confrontare il totale delle vendite per mese e città.<>

      • Line charts per confrontare l’andamento delle vendite in periodi storici differenti.<>

9. Conclusioni

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

Questo non è un progetto di programmazione, ma di statistica, e ci si aspetta di leggere commenti e considerazioni statistiche per i vari passaggi e risultati.

Analisi per città

#BEAMONT

dati_bea <- dati_re%>%
  filter(city == city_items$city[1])%>%
  reframe(
    year = year,
    month = month,
    sales = sales,
    volume= volume,
    listings = listings,
    median_price = median_price,
    months_inventory = months_inventory
  )
ggplot(data = dati_bea)+
  geom_col( aes(x = month, y = volume), col="black")+
  scale_x_continuous(breaks = seq(1, 12, 1))+ 
  labs(
    title = "Distribuzione Volume di Vendite per BEAMONT",
    x = "Data",
    y = "Volume tot. (100000 $)"
  )

#BRYAN COLLEGE STATION

dati_bcs <- dati_re%>%
  filter(city == city_items$city[2])%>%
  reframe(
    year = year,
    month = month,
    sales = sales,
    volume= volume,
    listings = listings,
    median_price = median_price,
    months_inventory = months_inventory
  )
ggplot(data = dati_bcs)+
  geom_col( aes(x = month, y = volume), col="black")+
  scale_x_continuous(breaks = seq(1, 12, 1))+ 
  labs(
    title = "Distribuzione Volume di Vendite per BRYAN COLLEGE STATION",
    x = "Data",
    y = "Volume tot. (100000 $)"
  )

# TYLER

dati_tyl <- dati_re%>%
  filter(city == city_items$city[3])%>%
  reframe(
    year = year,
    month = month,
    sales = sales,
    volume= volume,
    listings = listings,
    median_price = median_price,
    months_inventory = months_inventory
  )
ggplot(data = dati_tyl)+
  geom_col( 
    aes(
      x = month,
      y = volume,
      fill = year
    ),
    col = "red", lwd=1
  )+
  scale_x_continuous(breaks = seq(1, 12, 1))

#WICHITA FALLS

dati_wif <- dati_re%>%
  filter(city == city_items$city[4])%>%
  reframe(
    year = year,
    month = month,
    sales = sales,
    volume= volume,
    listings = listings,
    median_price = median_price,
    months_inventory = months_inventory
  )