Questo documento contiene il progetto finale di Luigi Carlucci del corso “Statistica Descrittiva” per il Master in Data Science di ProfessionAI.
Viene caricata la libreria dplyr e il dataset
realestate_texas.csv.
library(dplyr)
##
## Caricamento pacchetto: 'dplyr'
## I seguenti oggetti sono mascherati da 'package:stats':
##
## filter, lag
## I seguenti oggetti sono mascherati da 'package:base':
##
## intersect, setdiff, setequal, union
texas_data = read.csv("realestate_texas.csv")
attach(texas_data)
head(texas_data)
## 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
Nel dataset sono presenti le seguenti variabili:
city: variabile qualitativa su scala nominale;
contiene il nome della città di riferimento; può essere usata per
effettuare analisi di confronto tra le diverse città
year: variabile quantitativa discreta; rappresenta
una dimensione temporale, nello specifico l’anno di riferimento; può
essere usata per effettuare analisi di andamento nel tempo
month: variabile quantitativa discreta; rappresenta
una dimensione temporale, nello specifico il mese di riferimento per
ogni anno; può essere usata per effettuare analisi di confronto tra i
diversi mesi
sales: variabile quantitativa discreta; riporta il
numero totale di vendite di immobili per ogni città, anno e mese; è
possibile effettuare analisi con indici di posizione, variabilità e
forma, suddividere la variabile in classi e creare una distribuzione di
frequenze, effettuare analisi condizionate per altre variabili
volume: variabile quantitativa continua; riporta il
valore totale delle vendite di immobili (in milioni di dollari) per ogni
città, anno e mese; è possibile effettuare analisi con indici di
posizione, variabilità e forma, suddividere la variabile in classi e
creare una distribuzione di frequenze, effettuare analisi condizionate
per altre variabili
median_price: variabile quantitativa continua;
riporta il prezzo mediano di vendita di immobili (in dollari) per ogni
città, anno e mese; è possibile effettuare analisi con indici di
posizione, variabilità e forma, suddividere la variabile in classi e
creare una distribuzione di frequenze, effettuare analisi condizionate
per altre variabili
listings: variabile quantitativa discreta; riporta
il numero totale di annunci attivi per ogni città, anno e mese; è
possibile effettuare analisi con indici di posizione, variabilità e
forma, suddividere la variabile in classi e creare una distribuzione di
frequenze, effettuare analisi condizionate per altre variabili
months_inventory: variabile quantitativa continua;
riporta il tempo necessario (in mesi) per vendere tutte le inserzioni
correnti per ogni città, anno e mese; è possibile effettuare analisi con
indici di posizione, variabilità e forma, suddividere la variabile in
classi e creare una distribuzione di frequenze, effettuare analisi
condizionate per altre variabili
Per le variabili quantitative (escludendo quelle che rappresentano una dimensione temporale) si possono calcolare:
Indici di posizione: minimo, massimo, mediana, primo e terzo quartile, media
Indici di variabilità: range, range interquartile, varianza, deviazione standard, coefficiente di variazione
Indici di forma: asimmetria e curtosi
# Caricamento della libreria per skewness e kurtosis
library(moments)
# Creazione di una funzione per il calcolo degli indici
calcola_indici = function(x) {
c(
Min = min(x),
Max = max(x),
Mediana = median(x),
Primo_Quartile = unname(quantile(texas_data$sales, 0.25)),
Terzo_Quartile = unname(quantile(texas_data$sales, 0.75)),
Media = mean(x),
Range = max(x) - min(x),
Range_Interquartile = IQR(x),
Varianza = var(x),
Deviazione_Standard = sd(x),
Coeff_Variazione = sd(x)/mean(x) * 100,
Asimmetria = skewness(x),
Curtosi = kurtosis(x)
)
}
Come esempio, vengono prima calcolati gli indici per la variabile
sales:
# Applicazione della funzione e approssimazione dei risultati a due cifre decimali
indici_sales = round(calcola_indici(sales),2)
# Trasformazione in data frame per una migliore visualizzazione
indici_sales_df = as.data.frame(indici_sales)
indici_sales_df
## indici_sales
## Min 79.00
## Max 423.00
## Mediana 175.50
## Primo_Quartile 127.00
## Terzo_Quartile 247.00
## Media 192.29
## Range 344.00
## Range_Interquartile 120.00
## Varianza 6344.30
## Deviazione_Standard 79.65
## Coeff_Variazione 41.42
## Asimmetria 0.72
## Curtosi 2.69
In seguito, vengono calcolati gli indici per tutte le variabili opportune:
# Selezione delle variabili dal dataset intero
variables_subs = texas_data %>% select(sales, volume, median_price, listings, months_inventory)
# Applicazione della funzione a tutte le variabili selezionate e approssimazione
indici_vars = round(sapply(variables_subs, calcola_indici),2)
# Trasformazione in data frame e visualizzazione
indici_vars_df = as.data.frame(indici_vars)
indici_vars_df
## sales volume median_price listings months_inventory
## Min 79.00 8.17 73800.00 743.00 3.40
## Max 423.00 83.55 180000.00 3296.00 14.90
## Mediana 175.50 27.06 134500.00 1618.50 8.95
## Primo_Quartile 127.00 127.00 127.00 127.00 127.00
## Terzo_Quartile 247.00 247.00 247.00 247.00 247.00
## Media 192.29 31.01 132665.42 1738.02 9.19
## Range 344.00 75.38 106200.00 2553.00 11.50
## Range_Interquartile 120.00 23.23 32750.00 1029.50 3.15
## Varianza 6344.30 277.27 513572983.09 566568.97 5.31
## Deviazione_Standard 79.65 16.65 22662.15 752.71 2.30
## Coeff_Variazione 41.42 53.71 17.08 43.31 25.06
## Asimmetria 0.72 0.88 -0.36 0.65 0.04
## Curtosi 2.69 3.18 2.38 2.21 2.83
write.csv(indici_vars_df, file='indici_stats.csv')
Da una prima osservazione si notano molte differenze tra le diverse variabili in termini di distribuzione, che verranno analizzate e discusse più nel dettaglio nelle sezioni seguenti.
Per le variabili city, year e
month viene creata una distribuzione di frequenza:
N=dim(texas_data)[1]
# Distribuzione di frequenza della variabile "city"
city_freq_ass = table(city)
city_freq_rel = table(city)/N
city_freq = as.data.frame(cbind(city = rownames(city_freq_ass), city_freq_ass, city_freq_rel), row.names = FALSE)
print(city_freq)
## city city_freq_ass city_freq_rel
## 1 Beaumont 60 0.25
## 2 Bryan-College Station 60 0.25
## 3 Tyler 60 0.25
## 4 Wichita Falls 60 0.25
# Distribuzione di frequenza della variabile "year"
year_freq_ass = table(year)
year_freq_rel = table(year)/N
year_freq = as.data.frame(cbind(year = rownames(year_freq_ass), year_freq_ass, year_freq_rel), row.names = FALSE)
print(year_freq)
## year year_freq_ass year_freq_rel
## 1 2010 48 0.2
## 2 2011 48 0.2
## 3 2012 48 0.2
## 4 2013 48 0.2
## 5 2014 48 0.2
# Distribuzione di frequenza della variabile "month"
month_freq_ass = table(month)
month_freq_rel = table(month)/N
month_freq = as.data.frame(cbind(month = rownames(month_freq_ass), month_freq_ass, month_freq_rel), row.names = FALSE)
print(month_freq)
## month month_freq_ass month_freq_rel
## 1 1 20 0.0833333333333333
## 2 2 20 0.0833333333333333
## 3 3 20 0.0833333333333333
## 4 4 20 0.0833333333333333
## 5 5 20 0.0833333333333333
## 6 6 20 0.0833333333333333
## 7 7 20 0.0833333333333333
## 8 8 20 0.0833333333333333
## 9 9 20 0.0833333333333333
## 10 10 20 0.0833333333333333
## 11 11 20 0.0833333333333333
## 12 12 20 0.0833333333333333
Si nota chiramente come tutte le tre variabili hanno le stesse frequenze per ogni valore. Nello specifico ogni città ha lo stesso numero (n=60) di dati, distribuiti ugualamente per ogni anno e mese.
Viene ora determinato:
qual è la variabile con la maggiore variabilità, valutando il coefficiente di variazione (CV)
qual è variabile con la distribuzione più asimmetrica, valutando il valore dell’asimmetria
# Identificazione della variabile con la maggiore variabilità (CV più alto)
var_max_cv = colnames(indici_vars_df)[which.max(indici_vars_df["Coeff_Variazione",])]
cv_max_value = max(indici_vars_df["Coeff_Variazione",])
var_max_cv
## [1] "volume"
cv_max_value
## [1] 53.71
In questo caso, la variabile volume presenta il valore
più alto (53.71) di coefficiente di variazione (CV),
che misura la dispersione relativa rispetto alla media, ed è quindi la
variabile con la maggiore variabiltà tra tutte quelle presenti nel
dataset.
# Identificazione della variabile più asimmerica (asimmetria più alta in valore assoluto)
var_max_skewness = colnames(indici_vars_df)[which.max(abs(indici_vars_df["Asimmetria",]))]
skew_max_value = max(abs(indici_vars_df["Asimmetria",]))
var_max_skewness
## [1] "volume"
skew_max_value
## [1] 0.88
In questo caso, la variabile volume presenta il valore
più alto (0.88) di asimmetria in valore assoluto ed è quindi la
variabile con la distribuzione più asimmetrica tra tutte quelle presenti
nel dataset.
# Identificazione del valore orginale di asimmetria per la variabile "volume"
indici_vars_df["Asimmetria",]$volume
## [1] 0.88
In particolare, poichè il valore dell’indice di asimmetria è
positivo, la variabile volume ha una distribuzione
asimmetrica positiva, cioè con una coda verso destra, come si può
osservara anche da un grafico della densità.
library(ggplot2)
ggplot(texas_data)+
geom_density(aes(x=volume), col="black", fill="steelblue") +
labs(title = "Densità del volume delle vendite",
x = "Volume delle vendite (milioni di $)", y = "Densità")
La variabile quantitativa median_price viene suddivisa
in 10 classi.
# Suddivisione della variabile median_price in classi
median_price_cl = cut(texas_data$median_price, breaks = 10, dig.lab=10)
Vengono create delle distribuzione di frequenze, che includono la frequenza assoluta, la frequenza relativa, la frequenza assoluta cumulata e la frequenza relativa cumulata.
# Creazione delle distribuzioni di frequenze
N=dim(texas_data)[1]
ni = table(median_price_cl)
fi = ni/N
Ni = cumsum(ni)
Fi = Ni/N
distr_freq_median_price_cl = as.data.frame(cbind(ni,fi,Ni,Fi))
distr_freq_median_price_cl
## ni fi Ni Fi
## (73693.8,84420] 2 0.008333333 2 0.008333333
## (84420,95040] 16 0.066666667 18 0.075000000
## (95040,105660] 23 0.095833333 41 0.170833333
## (105660,116280] 17 0.070833333 58 0.241666667
## (116280,126900] 25 0.104166667 83 0.345833333
## (126900,137520] 48 0.200000000 131 0.545833333
## (137520,148140] 38 0.158333333 169 0.704166667
## (148140,158760] 46 0.191666667 215 0.895833333
## (158760,169380] 16 0.066666667 231 0.962500000
## (169380,180106.2] 9 0.037500000 240 1.000000000
Viene utilizzata la funzione barplot per rappresentare i
dati della frequenza assoluta della variabile median_price
suddivisa in classi.
barplot(distr_freq_median_price_cl$ni,
xlab = "Classi di prezzo ($)",
ylab = "Frequenza assolute",
names.arg = rownames(distr_freq_median_price_cl),
col="steelblue")
Viene utilizzata la libreria ggplot2 per creare i gafici
a barre relativi ai quattro tipi di distribuzione di frequenze
(assoluta, relativa, assoluta cumulata e relativa cumulata).
ggplot(distr_freq_median_price_cl) +
geom_bar(aes(x=row.names(distr_freq_median_price_cl), y=ni), stat = "identity", fill = "steelblue") +
scale_x_discrete(limits=row.names(distr_freq_median_price_cl)) +
labs(title = "Distribuzione del prezzo mediano",
x = "Classi di prezzo ($)",
y = "Frequenza assoluta") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
ggplot(distr_freq_median_price_cl) +
geom_bar(aes(x=row.names(distr_freq_median_price_cl), y=fi), stat = "identity", fill = "steelblue") +
scale_x_discrete(limits=row.names(distr_freq_median_price_cl)) +
labs(title = "Distribuzione del prezzo mediano",
x = "Classi di prezzo ($)",
y = "Frequenza relativa") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
ggplot(distr_freq_median_price_cl) +
geom_bar(aes(x=row.names(distr_freq_median_price_cl), y=Ni), stat = "identity", fill = "steelblue") +
scale_x_discrete(limits=row.names(distr_freq_median_price_cl)) +
labs(title = "Distribuzione del prezzo mediano",
x = "Classi di prezzo ($)",
y = "Frequenza assoluta cumulata") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
ggplot(distr_freq_median_price_cl) +
geom_bar(aes(x=row.names(distr_freq_median_price_cl), y=Fi), stat = "identity", fill = "steelblue") +
scale_x_discrete(limits=row.names(distr_freq_median_price_cl)) +
labs(title = "Distribuzione del prezzo mediano",
x = "Classi di prezzo ($)",
y = "Frequenza relativa cumulata") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Infine, viene calcolato l’indice di eterogeneità Gini:
# Creazione di una funzione per calcolare l'indice di eterogeneità 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)
}
#Applicazione della funzione alla variabile "median_price", precedentemente suddivisa in classi
gini.index(median_price_cl)
## [1] 0.958642
L’indice di eterogeneità Gini rappresenta una misura della diseguaglianza (o eterogeneità) di una distribuzione e assume un valore compreso tra 0 e 1. Valori bassi (vicini allo 0) indicano che la distribuzione è abbastanza omogenea, mentre valori alti (vicino ad 1) indicano una distribuione più eterogenea. Nel caso preso in esempio del prezzo medio di vendita degli immobili, l’indice calcolato di 0.95 indica una elevata eterogeneità nei prezzi.
In questa sezione, viene utilizzata la probabilità classica, cioè il rapporto tra il numero di casi favorevoli e il numero totale di osservazioni, per calcolare la probabilità che, presa una riga a caso del dataset originario, si verfichino le seguenti condizioni:
la riga riporti la città “Beaumont”
la riga riporti il mese di Luglio
la riga riporti il mese di dicembre 2012
# Numero totale di righe nel dataset
total_row = nrow(texas_data)
# Probabilità che la città sia "Beaumont"
p_beaumont = sum(texas_data$city == "Beaumont") / total_row
cat("P(Beaumont) =", round(p_beaumont,2), "\n")
## P(Beaumont) = 0.25
# Probabilità che il mese sia Luglio
p_luglio = sum(texas_data$month == 7) / total_row
cat("P(Luglio) =", round(p_luglio,2), "\n")
## P(Luglio) = 0.08
# Probabilità che sia Dicembre 2012
p_dicembre_2012 = sum(texas_data$year == 2012 & texas_data$month == 12) / total_row
cat("P(Dicembre 2012) =", round(p_dicembre_2012,2), "\n")
## P(Dicembre 2012) = 0.02
Dal calcolo delle probabilità è risultato che la probabilità che una riga presa a caso:
riporti la città “Beaumont” è di 0.25 (25%)
riporti il mese di Luglio è di 0.08 (8%)
porti il mese di dicembre 2012 è di 0.02 (2%)
Vengono aggiunte due nuove colonne al dataset, create partendo da altre variabili già presenti, che indicano:
il prezzo medio degli immobili
l’efficacia degli annunci di vendita
Il prezzo medio degli immobili venduti viene calcolato come il valore
totale delle vendite (variabile volume) diviso per il
numero totale di vendite (variabile sales). La variabile
volume viene moltiplicata per \(10^6\) per ottenere il valore in
dollari.
# Creazione della colonna "mean_price"
texas_data$mean_price = round(((texas_data$volume * 10^6) / texas_data$sales),0)
head(texas_data)
## 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
## mean_price
## 1 170627
## 2 163796
## 3 157698
## 4 134095
## 5 142738
## 6 144016
I valori della variabile calcolata mean_price
differiscono dalla variabile median_price poichè la media è
influenzata dai valori estremi. Una maggiore differenza tra
mean_price e median_price indica una maggiore
asimmetria nei prezzi.
Una possibile misura dell’efficacia degli annunci di vendita è data
dal rapporto tra le vendite effettive per ogni mese (variabile
sales) e le vendite attese determinato dalle variabili
listings (numero di annunci attivi) e
months_inventory (numero di mesi necessari per vendere
tutte le inserzioni correnti). In particolare, il rapporto tra le
variabili listings e months_inventory
determina il numero atteso di vendite in un singolo mese.
# Creazione della colonna "listing_effectiveness"
texas_data$listing_effectiveness = texas_data$sales / (texas_data$listings / texas_data$months_inventory)
head(texas_data)
## 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
## mean_price listing_effectiveness
## 1 170627 0.5143509
## 2 163796 0.6809584
## 3 157698 1.1422143
## 4 134095 1.2412178
## 5 142738 1.2432524
## 6 144016 1.1635607
In questo caso, se la variabile listing_effectiveness è
> 1 le vendite nel mese corrente sono andate più velocemente di
quanto atteso, se è < 1 le vendite sono andate più lentamente, mentre
se sono vicine ad 1 le vendite sono andate esattamente al ritmo
atteso.
In questa sezione vengono eseguite delle analisi statistiche condizionate, attraverso la creazione di summary statistici in base a tre variabili:
città (city)
anno (year)
mese (month)
Nello specifico, vengono calcolate la media e la deviazione standard per le principali variabili quantitative e mostrate delle rappresentazioni grafiche dei risultati.
# Summary statistico per città
summary_city = texas_data %>%
group_by(city) %>%
summarise(
sales_mean = mean(sales),
sales_sd = sd(sales),
volume_mean = mean(volume),
volume_sd = sd(volume),
median_price_mean = mean(median_price),
median_price_sd = sd(median_price),
listings_mean = mean(listings),
listings_sd = sd(listings)
) %>%
mutate(across(2:9, round, 2))
## Warning: There was 1 warning in `mutate()`.
## ℹ In argument: `across(2:9, round, 2)`.
## Caused by warning:
## ! The `...` argument of `across()` is deprecated as of dplyr 1.1.0.
## Supply arguments directly to `.fns` through an anonymous function instead.
##
## # Previously
## across(a:b, mean, na.rm = TRUE)
##
## # Now
## across(a:b, \(x) mean(x, na.rm = TRUE))
summary_city
## # A tibble: 4 × 9
## city sales_mean sales_sd volume_mean volume_sd median_price_mean
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Beaumont 177. 41.5 26.1 6.97 129988.
## 2 Bryan-College Sta… 206. 85.0 38.2 17.2 157488.
## 3 Tyler 270. 62.0 45.8 13.1 141442.
## 4 Wichita Falls 116. 22.2 13.9 3.24 101743.
## # ℹ 3 more variables: median_price_sd <dbl>, listings_mean <dbl>,
## # listings_sd <dbl>
Nei seguenti garfici a barre vengono mostrati i valori medi delle vendite e dei prezzi mediani nelle diverse città.
ggplot(summary_city, aes(x = city, y = sales_mean)) +
geom_bar(stat = "identity", fill = "steelblue") +
labs(title = "Media delle vendite per città", x = "Città", y = "Vendite")
ggplot(summary_city, aes(x = city, y = median_price_mean)) +
geom_bar(stat = "identity", fill = "steelblue") +
labs(title = "Media del prezzo mediano per città", x = "Città", y = "Prezzo ($)") +
scale_y_continuous(labels = scales::comma)
# Summary statistico per anno
summary_year = texas_data %>%
group_by(year) %>%
summarise(
sales_mean = mean(sales),
sales_sd = sd(sales),
volume_mean = mean(volume),
volume_sd = sd(volume),
median_price_mean = mean(median_price),
median_price_sd = sd(median_price),
listings_mean = mean(listings),
listings_sd = sd(listings)
) %>%
mutate(across(2:9, round, 2))
summary_year
## # A tibble: 5 × 9
## year sales_mean sales_sd volume_mean volume_sd median_price_mean
## <int> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2010 169. 60.5 25.7 10.8 130192.
## 2 2011 164. 63.9 25.2 12.2 127854.
## 3 2012 186. 70.9 29.3 14.5 130077.
## 4 2013 212. 84 35.2 17.9 135723.
## 5 2014 231. 95.5 39.8 21.2 139481.
## # ℹ 3 more variables: median_price_sd <dbl>, listings_mean <dbl>,
## # listings_sd <dbl>
Nei seguenti garfici a linee vengono mostrati gli andamenti dei valori medi delle vendite e dei prezzi mediani nel corso degli anni.
ggplot(summary_year, aes(x = year, y = sales_mean)) +
geom_line(color = "red") +
geom_point(color = "red") +
labs(title = "Evoluzione della media delle vendite", x = "Anno", y = "Vendite")
ggplot(summary_year, aes(x = year, y = median_price_mean)) +
geom_line(color = "red") +
geom_point(color = "red") +
labs(title = "Evoluzione della media del prezzo mediano", x = "Anno", y = "Prezzo ($)") +
scale_y_continuous(labels = scales::comma)
# Summary statistico per mese
summary_month = texas_data %>%
group_by(month) %>%
summarise(
sales_mean = mean(sales),
sales_sd = sd(sales),
volume_mean = mean(volume),
volume_sd = sd(volume),
median_price_mean = mean(median_price),
median_price_sd = sd(median_price),
listings_mean = mean(listings),
listings_sd = sd(listings)
) %>%
mutate(across(2:9, round, 2))
summary_month
## # A tibble: 12 × 9
## month sales_mean sales_sd volume_mean volume_sd median_price_mean
## <int> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 127. 43.4 19 8.37 124250
## 2 2 141. 51.1 21.6 10.1 130075
## 3 3 189. 59.2 29.4 12.0 127415
## 4 4 212. 65.4 33.3 14.5 131490
## 5 5 239. 83.1 39.7 19.0 134485
## 6 6 244. 95 41.3 21.1 137620
## 7 7 236. 96.3 39.1 21.4 134750
## 8 8 231. 79.2 38.0 18.0 136675
## 9 9 182. 72.5 29.6 15.2 134040
## 10 10 180. 75.0 29.1 15.1 133480
## 11 11 157. 55.5 24.8 11.2 134305
## 12 12 169. 60.8 27.1 12.6 133400
## # ℹ 3 more variables: median_price_sd <dbl>, listings_mean <dbl>,
## # listings_sd <dbl>
Nei seguenti garfici a barre vengono mostrati i valori medi delle vendite e dei prezzi mediani in ogni mese.
ggplot(summary_month, aes(x = factor(month), y = sales_mean)) +
geom_bar(stat = "identity", fill = "forestgreen") +
labs(title = "Media delle vendite per mese", x = "Mese", y = "Vendite")
ggplot(summary_month, aes(x = factor(month), y = median_price_mean)) +
geom_bar(stat = "identity", fill = "forestgreen") +
labs(title = "Media del prezzo mediano per mese", x = "Mese", y = "Prezzo ($)") +
scale_y_continuous(labels = scales::comma)
In questa sezione viene usata la libreria ggplot2 per
realizzare dei grafici personalizzati ed evidenziare alcuni aspetti che
emergono dai dati.
Vengono creati dei boxplot per confrontare la distrubuzione del
prezzo mediano tra le città. Questo tipo di grafico permette di
visualizzare il valore mediano. il range interquartile, i valori massimi
e minimi e gli outliers per la variabile median_price nelle
diverse città. Sono stati aggiunti anche dei violin plot per mostrare
anche la distribuzione della densità dei valori. Si può chiaramente
osservare come i prezzi mediani a “Wichita Falls” sono tendenzialmente
più bassi rispetto alle altre tre città, ma hanno una maggiore
variabilità. Si nota anche come a “Bryan-College Station” vi sono i
prezzi più alti, indicati sia dalla mediana che dai massimi.
ggplot(texas_data, aes(x = city, y = median_price, fill = city)) +
geom_violin(show.legend = FALSE) +
geom_boxplot(width=0.5 , show.legend = FALSE) +
labs(title = "Distribuzione del prezzo mediano tra le città",
x = "Città", y = "Prezzo mediano ($)") +
scale_y_continuous(labels = scales::comma)
Vengono poi creati dei grafici a barre per confrontare il totale
delle vendite per mese e città. In questo caso il dataset viene
raggruppato considerando le variabili city e
month e viene eseguito un summary calcolando le vendite
totali per tutti gli anni. Nel primo grafico vengono mostrati i mesi
sull’asse x e le barre colorate diversamente indicano le città. Nel
secondo grafico vengono mostrate le città sull’asse x e le diverse barre
sono colorate in base al mese. In entrabi i casi si nota come vi sia un
maggior numero di vendite nei mesi primaverili e estivi nelle città di
“Bryan-College Station” e “Tyler”, mentre nelle città di “Beaumont” e
soprattutto “Wichita Falls” le vendite sono più costanti nel corso
dell’anno.
texas_data %>%
group_by(city, month) %>%
summarise(total_sales = sum(sales)) %>%
ggplot(aes(x = factor(month), y = total_sales, fill = city)) +
geom_bar(stat = "identity", position = "dodge") +
labs(title = "Totale vendite per mese e città",
x = "Mese", y = "Totale vendite", fill = "Città")
## `summarise()` has grouped output by 'city'. You can override using the
## `.groups` argument.
texas_data %>%
group_by(city, month) %>%
summarise(total_sales = sum(sales)) %>%
ggplot(aes(x = factor(city), y = total_sales, fill = as.factor(month))) +
geom_bar(stat = "identity", position = "dodge") +
labs(title = "Totale vendite per mese e città",
x = "Città", y = "Totale vendite", fill = "Mese")
## `summarise()` has grouped output by 'city'. You can override using the
## `.groups` argument.
Costruendo un grafico a barre sovrapposte si osservano più chiaramente le differenza nel totale delle vendite. “Wichita Falls”, oltre ad avere la minore variabilità annuale, ha anche un numero di vendite totali minore rispetto alle altre città. “Tyler”, invece, è la città con il maggior numero di vendite.
texas_data %>%
group_by(city, month) %>%
summarise(total_sales = sum(sales)) %>%
ggplot(aes(x = factor(city), y = total_sales, fill = as.factor(month))) +
geom_bar(stat = "identity", position = "stack") +
labs(title = "Totale vendite per mese e città (sovrapposte)",
x = "Città", y = "Totale vendite", fill = "Mese")
## `summarise()` has grouped output by 'city'. You can override using the
## `.groups` argument.
Costruendo lo stesso grafico a barre normalizzato, che rappresenta le percentuali sul totale delle vendite per ogni mese, si osserva meglio la differenza nelle vendite nei vari mesi ma si perde l’informazione sul totale delle vendite nelle diverse città.
texas_data %>%
group_by(city, month) %>%
summarise(total_sales = sum(sales)) %>%
group_by(month) %>%
mutate(perc_sales = total_sales / sum(total_sales)) %>%
ggplot(aes(x = factor(city), y = perc_sales, fill = as.factor(month))) +
geom_bar(stat = "identity", position = "fill") +
scale_y_continuous(labels = scales::percent) +
labs(title = "Totale vendite per mese e città (normalizzato)",
x = "Città", y = "Percentuale sul totale", fill = "Mese")
## `summarise()` has grouped output by 'city'. You can override using the
## `.groups` argument.
Utilizzano la funzione facet_wrap di
ggplot2 è possibile suddivire i grafici anche per la
variabile year. In questo modo si può per esempio
visualizzare il totale delle vendite per mese e città nei diversi anni
attraverso grafici a barre affiancate o sovrapposte.
texas_data %>%
group_by(year, city, month) %>%
summarise(total_sales = sum(sales)) %>%
ggplot(aes(x = factor(month), y = total_sales, fill = city)) +
geom_bar(stat = "identity", position = "dodge") +
facet_wrap(~ year) + # Suddivisione dei grafici per anno
labs(title = "Totale vendite per mese, città e anno",
x = "Mese", y = "Totale vendite", fill = "Città") +
theme(legend.position = c(0.85, 0.2))
## `summarise()` has grouped output by 'year', 'city'. You can override using the
## `.groups` argument.
## Warning: A numeric `legend.position` argument in `theme()` was deprecated in ggplot2
## 3.5.0.
## ℹ Please use the `legend.position.inside` argument of `theme()` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
texas_data %>%
group_by(year, city, month) %>%
summarise(total_sales = sum(sales)) %>%
ggplot(aes(x = factor(city), y = total_sales, fill = as.factor(month))) +
geom_bar(stat = "identity", position = "stack") +
facet_wrap(~ year) + # Suddivisione dei grafici per anno
labs(title = "Totale vendite per mese, città e anno",
x = "Città", y = "Totale vendite", fill = "Mese") +
theme(legend.position = c(0.85, 0),
axis.text.x = element_text(size=7, angle = 45, hjust = 1)) +
guides(fill=guide_legend(ncol=3))
## `summarise()` has grouped output by 'year', 'city'. You can override using the
## `.groups` argument.
In seguito vengono creati dei boxplot che permettono di confrontare la distribuzione del valore totale delle vendite tra le varie città e nei diversi anni. Dal grafico si può osservare come il valore delle vendite a “Wichita Falls” rimane basso nel corso degli anni, mentre cresce molto a “Bryan-College Station” e “Tyler”.
ggplot(texas_data, aes(x = city, y = volume, fill = as.factor(year))) +
geom_boxplot() +
labs(title = "Distribuzione del valore totale delle vendite tra le città",
x = "Città", y = "Volume delle vendite (milioni di $)", fill = "Anno")
Infine, vengono creati dei grafici a linee per visualizzare
l’andamento delle vendite nel corso del tempo. Per questa operazione
viene creata una nuova variabile date che combina le
variabili year e month e indica la data di
riferimento.
# Creazione di una varianile "date" che include mese e anno
texas_data = texas_data %>%
mutate(date = as.Date(paste(year, month, "01", sep = "-")))
I due garfici seguenti mostrano l’andamento delle vendite totali e del loro valore totale per tutte le città.
texas_data %>%
group_by(date) %>%
summarise(total_sales = sum(sales)) %>%
ggplot(aes(x = date, y = total_sales)) +
geom_line(color = "red") +
geom_point(color = "red") +
labs(title = "Andamento delle vendite totali",
x = "Data", y = "Totale vendite") +
scale_x_date(date_breaks = "years", date_labels = "%Y")
texas_data %>%
group_by(date) %>%
summarise(total_volume = sum(volume)) %>%
ggplot(aes(x = date, y = total_volume)) +
geom_line(color = "limegreen") +
geom_point(color = "limegreen") +
labs(title = "Andamento del valore totale delle vendite",
x = "Data", y = "Volume delle vendite (milioni di $)") +
scale_x_date(date_breaks = "years", date_labels = "%Y")
Il grafico seguente permette di confrontare l’andamento delle vendite nelle varie città.
ggplot(texas_data, aes(x = date, y = sales, color = city, group = city)) +
geom_line() +
geom_point() +
labs(title = "Andamento delle vendite nelle varie città",
x = "Data", y = "Vendite", color = "Città") +
scale_x_date(date_breaks = "years", date_labels = "%Y") +
guides(color = guide_legend(position = "inside")) +
theme(legend.position.inside = c(0.2, 0.8),
legend.background = element_rect(fill = "#FFFFFF85", colour = NA))
Mentre con il grafico precedente è possibile osservare le
oscillazioni delle vendite nel corso dei mesi e degli anni, è difficile
distinguere delle tendenze tra le varie città. Questo è facilitato
utilizzando la funzione geom_smooth di
ggplot2, che applica una funzione di smoothing alle serie
di dati relative alle diverse città, producendo una linea di tendenza e
un intervallo di confidenza.
ggplot(texas_data, aes(x = date, y = sales, color = city, group = city)) +
geom_point() +
geom_smooth(aes(color = city, fill = city)) +
labs(title = "Andamento delle vendite nelle varie città",
x = "Data", y = "Vendite", color = "Città", fill = "Città") +
scale_x_date(date_breaks = "years", date_labels = "%Y") +
guides(color = guide_legend(position = "inside"),
fill = guide_legend(position = "inside")) +
theme(legend.position.inside = c(0.2, 0.8),
legend.background = element_rect(fill = "#FFFFFF85", colour = NA))
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Dal grafico è possibile osservare come le vendite nella città di “Tyler” abbiano valori più alti e una tendenza marcatamente crescente nel corso del tempo. Al contrario, nella città di “Wichita Falls” le vendite hanno valori più bassi e una tendenza costante. Le città di “Beaumont” e “Bryan-College Station” hanno dei valori intermedi e in buona parte sovrapposti, con delle tendeze leggermente in crescita.
Creando lo stesso grafico per i prezzi mediani si osserva un andamento leggermente crescente in tutte le città, con l’esclusione di “Beaumont”. Come notato anche in precedenza, i prezzi nella città di “Bryan-College Station” risultano essere i più alti.
ggplot(texas_data, aes(x = date, y = median_price, color = city, group = city)) +
geom_point() +
geom_smooth(aes(color = city, fill = city)) +
labs(title = "Andamento dei prezzi mediani nelle varie città",
x = "Data", y = "Prezzi mediani ($)", color = "Città", fill = "Città") +
scale_x_date(date_breaks = "years", date_labels = "%Y") +
scale_y_continuous(labels = scales::comma) +
guides(color = guide_legend(position = "inside"),
fill = guide_legend(position = "inside")) +
theme(legend.position.inside = c(0.2, 0.8),
legend.background = element_rect(fill = "#FFFFFF85", colour = NA))
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'
Questa analisi esplorativa del mercato immobiliare del Texas ha permesso di rivelare alcune caratteristiche e tendenze relative alla vendita di immobili in 4 diverse città.
Come indicato dall’indice di eterogeneità di Gini, calcolato per il prezzo mediano di vendita degli immobili, pari a 0.95, è presente un’elevata eterogeneità nei prezzi. In particolare, osservando le analisi condizionate per le diverse città, questo sembra dovuto al fatto che i prezzi della città di “Wichita Falls” sono tendenzialmente più bassi rispetto alle altre tre città. Appare interessante notare che i prezzi nella città di “Bryan-College Station” sono i più alti, mentre le vendite nella stessa città sono inferiori rispetto alla città di “Tyler”. Questo potrebbe suggerire uno squilibrio nei prezzi nella città di “Bryan-College Station”, le cui cause andrebbero approfondite analizzando altre varibili.
Un’altra caratteristica emersa da questa analisi è la stagionalità nelle vendite. Questa è evidente principalmente nelle città di “Bryan-College Station” e “Tyler”, che presentano un maggior numero di vendite nei mesi primaverili e estivi, mentre le città di “Beaumont” e soprattutto “Wichita Falls” presentano vendite più costanti nel corso dell’anno. Le cause di questa stagionalità potrebbero essere legate a una maggiore attrattività turistica di “Bryan-College Station” e “Tyler”, ma servirebbero ulteriori dati per confermare questa ipotesi. Da questo punto di vista, inoltre, è interessante notare, confrontando le città di “Beaumont” e “Bryan-College Station” attraverso i grafici a barre che mostrano le vendite suddivise per mese e il grafico a linee dell’andamento temporale, che le vendite nelle due città nei mesi autunnali e invernali sono sempre a livelli simili, mentre nei mesi primaverili ed estivi le vendite a “Bryan-College Station” sono molto maggiori.
Infine, occorre notare una generale tendenza crescente delle vedite nel corso degli anni, emersa in tutte le città analizzate, ad esclusione di “Wichita Falls”, dove le vendite sono rimaste sostanzialmente costanti. Questo suggerisce che “Wichita Falls” potrebbe presentare una scarsa attrattività generale, non legata esclusivamente al settore turistico.