L’azienda Texas Realty Insights desidera analizzare le tendenze del mercato immobiliare nello stato del Texas, sfruttando i dati storici relativi alle vendite di immobili. L’obiettivo è fornire insight statistici e visivi che supportino le decisioni strategiche di vendita e l’ottimizzazione delle inserzioni immobiliari.
# Caricamento pacchetti necessari
library(dplyr)
library(ggplot2)
library(e1071) # Per il calcolo della skewness (asimmetria)
# Importazione dataset (assicurati che il percorso sia corretto sul tuo PC)
dati <- read.csv("C:\\Users\\rodomda\\Downloads\\Real-Estate-Texas.csv", stringsAsFactors = FALSE)
Il dataset contiene le seguenti variabili: - city: Qualitativa nominale. Serve come dimensione di raggruppamento per confrontare i mercati. - year / month: Quantitative discrete, ma di fatto rappresentano dimensioni temporali. - sales / listings: Quantitative discrete. Rappresentano i volumi fisici del mercato (transazioni e inventario). - volume / median_price / months_inventory: Quantitative continue.
str(dati)
## 'data.frame': 240 obs. of 8 variables:
## $ city : chr "Beaumont" "Beaumont" "Beaumont" "Beaumont" ...
## $ year : int 2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 ...
## $ month : int 1 2 3 4 5 6 7 8 9 10 ...
## $ sales : int 83 108 182 200 202 189 164 174 124 150 ...
## $ volume : num 14.2 17.7 28.7 26.8 28.8 ...
## $ median_price : num 163800 138200 122400 123200 123100 ...
## $ listings : int 1533 1586 1689 1708 1771 1803 1857 1830 1829 1779 ...
## $ months_inventory: num 9.5 10 10.6 10.6 10.9 11.1 11.7 11.6 11.7 11.5 ...
Calcoliamo le principali metriche statistiche per le variabili
quantitative continue e costruiamo una distribuzione di frequenza per la
variabile qualitativa city.
dati_num <- dati %>% select(where(is.numeric))
statistiche_fun <- function(x) {
c(
n = length(x),
media = mean(x, na.rm = TRUE),
mediana = median(x, na.rm = TRUE),
min = min(x, na.rm = TRUE),
q1 = quantile(x, 0.25, na.rm = TRUE),
q3 = quantile(x, 0.75, na.rm = TRUE),
max = max(x, na.rm = TRUE),
dev_std = sd(x, na.rm = TRUE),
cv = sd(x, na.rm = TRUE) / mean(x, na.rm = TRUE),
asimmetria = skewness(x, na.rm = TRUE, type = 2)
)
}
tabella_statistiche <- as.data.frame(t(sapply(dati_num, statistiche_fun)))
round(tabella_statistiche, 2)
## n media mediana min q1.25% q3.75% max
## year 240 2012.00 2012.00 2010.00 2011.00 2013.00 2014.00
## month 240 6.50 6.50 1.00 3.75 9.25 12.00
## sales 240 192.29 175.50 79.00 127.00 247.00 423.00
## volume 240 31.01 27.06 8.17 17.66 40.89 83.55
## median_price 240 132665.42 134500.00 73800.00 117300.00 150050.00 180000.00
## listings 240 1738.02 1618.50 743.00 1026.50 2056.00 3296.00
## months_inventory 240 9.19 8.95 3.40 7.80 10.95 14.90
## dev_std cv asimmetria
## year 1.42 0.00 0.00
## month 3.46 0.53 0.00
## sales 79.65 0.41 0.72
## volume 16.65 0.54 0.89
## median_price 22662.15 0.17 -0.37
## listings 752.71 0.43 0.65
## months_inventory 2.30 0.25 0.04
# Frequenze per 'city'
table(dati$city)
##
## Beaumont Bryan-College Station Tyler
## 60 60 60
## Wichita Falls
## 60
Commento: Le 4 città sono perfettamente bilanciate (60 osservazioni ciascuna). Il prezzo mediano ha una media di 132.665$ e risulta leggermente asimmetrico a sinistra (-0.36), indicando una concentrazione di immobili nelle fasce di prezzo medio-alte per il periodo osservato.
Uso il Coefficiente di Variazione (CV) per misurare la variabilità relativa e la Skewness per l’asimmetria.
# Variabile più variabile (CV più alto)
tabella_statistiche[which.max(tabella_statistiche$cv), c("cv", "dev_std", "media")]
## cv dev_std media
## volume 0.5370536 16.65145 31.00519
# Variabile più asimmetrica (Valore assoluto di skewness più alto)
tabella_statistiche[which.max(abs(tabella_statistiche$asimmetria)), c("asimmetria")]
## [1] 0.8903162
Considerazioni: Il volume ($ mln) è sia la variabile con maggior variabilità (CV del 53.7%) sia quella più asimmetrica (coda lunga a destra con asimmetria 0.88). Questo avviene perché il volume finanziario subisce l’effetto combinato delle variazioni del prezzo degli immobili e del numero totale di vendite, presentando picchi molto alti in mesi eccezionali.
Suddivido il median_price in fasce per calcolare
l’indice di Gini (eterogeneità).
# Creazione classi
dati$classe_prezzo <- cut(
dati$median_price,
breaks = c(0, 100000, 125000, 150000, 175000, 200000, 250000, Inf),
include.lowest = TRUE, right = TRUE
)
freq_classi <- table(dati$classe_prezzo)
# Grafico a barre
barplot(freq_classi, col = "steelblue", main = "Distribuzione Prezzo Mediano in Classi", las = 2, cex.names = 0.8)
# Calcolo Indice di Gini
gini_fun <- function(freq) {
freq <- as.numeric(freq)
n <- length(freq)
freq <- sort(freq)
(2 * sum((1:n) * freq) / (n * sum(freq))) - (n + 1) / n
}
gini_prezzo <- gini_fun(freq_classi)
paste("Indice di Gini (classi di prezzo):", round(gini_prezzo, 4))
## [1] "Indice di Gini (classi di prezzo): 0.5512"
Commento: La classe modale (più frequente) è quella tra i 125.000$ e i 150.000$. L’indice di Gini pari a 0.55 mostra una discreta ma non estrema eterogeneità, indicando che i prezzi non sono tutti concentrati in un’unica fascia.
Calcoliamo le probabilità basandoci sulle frequenze relative degli eventi nel dataset.
prob_beaumont <- mean(dati$city == "Beaumont")
prob_luglio <- mean(dati$month == 7)
prob_dic_2012 <- mean(dati$month == 12 & dati$year == 2012)
cat("Probabilità Beaumont: ", prob_beaumont, "\n")
## Probabilità Beaumont: 0.25
cat("Probabilità Luglio: ", prob_luglio, "\n")
## Probabilità Luglio: 0.08333333
cat("Probabilità Dicembre 2012: ", prob_dic_2012, "\n")
## Probabilità Dicembre 2012: 0.01666667
Calcoliamo il mean_price stimato dal volume e una nuova
metrica: l’efficacia_annunci.
# Prezzo medio stimato
dati$mean_price <- (dati$volume * 1000000) / dati$sales
# Efficacia annunci (tasso di assorbimento)
dati$efficacia_annunci <- dati$sales / dati$listings
summary(dati[, c("mean_price", "efficacia_annunci")])
## mean_price efficacia_annunci
## Min. : 97010 Min. :0.05014
## 1st Qu.:132939 1st Qu.:0.08980
## Median :156588 Median :0.10963
## Mean :154320 Mean :0.11874
## 3rd Qu.:173915 3rd Qu.:0.13492
## Max. :213234 Max. :0.38713
Effettuiamo analisi di aggregazione per rispondere alle domande operative sui sottogruppi.
# Per città
dati %>% group_by(city) %>%
summarise(
prezzo_mediano_avg = mean(median_price),
efficacia_avg = mean(efficacia_annunci),
vendite_totali = sum(sales)
)
## # A tibble: 4 × 4
## city prezzo_mediano_avg efficacia_avg vendite_totali
## <chr> <dbl> <dbl> <int>
## 1 Beaumont 129988. 0.106 10643
## 2 Bryan-College Station 157488. 0.147 12358
## 3 Tyler 141442. 0.0935 16185
## 4 Wichita Falls 101743. 0.128 6964
# Per anno
dati %>% group_by(year) %>%
summarise(
prezzo_mediano_avg = mean(median_price),
mesi_inventario_avg = mean(months_inventory)
)
## # A tibble: 5 × 3
## year prezzo_mediano_avg mesi_inventario_avg
## <int> <dbl> <dbl>
## 1 2010 130192. 9.97
## 2 2011 127854. 10.9
## 3 2012 130077. 9.88
## 4 2013 135723. 8.15
## 5 2014 139481. 7.06
Commento: Bryan-College Station è il mercato più ricco e reattivo (prezzi più alti, maggiore efficacia degli annunci). A livello annuale, si nota un netto trend di crescita dal 2010 al 2014, con prezzi in salita e mesi d’inventario in crollo (da quasi 10 mesi a 7 mesi), segnale di un mercato sempre più reattivo e “veloce”.
ggplot(dati, aes(x = city, y = median_price, fill = city)) +
geom_boxplot() +
labs(title = "Distribuzione del Prezzo Mediano per Città", x = "Città", y = "Prezzo Mediano ($)") +
theme_minimal() + theme(legend.position = "none")
Commento: Wichita Falls è il mercato più economico, con
pochissima dispersione. Bryan-College è dove ci sono i prezzi alti.
# Inseriamo year e city nello stesso blocco per confrontare
ggplot(dati, aes(x = factor(year), y = volume, fill = city)) +
geom_boxplot() +
labs(title = "Volume Vendite per Anno e Città", x = "Anno", y = "Volume (Mln $)") +
theme_minimal()
Commento: I volumi crescono di molto a partire dal
2013-2014 per tutte le città. L’anno 2014 evidenzia spread notevoli in
estate, generando estremi superiori vistosi.
# Stacked Bar
ggplot(dati, aes(x = factor(month), y = sales, fill = city)) +
geom_col(position = "stack") +
labs(title = "Vendite Totali Mensili (Stagionalità)", x = "Mese", y = "Vendite") +
theme_minimal()
# Normalized Bar (100%)
ggplot(dati, aes(x = factor(month), y = sales, fill = city)) +
geom_col(position = "fill") +
labs(title = "Composizione % Vendite Mensili", x = "Mese", y = "Quota") +
theme_minimal()
Commento: La stagionalità è fortissima: i picchi si
raggiungono sistematicamente tra Maggio e Agosto. Il grafico
normalizzato dimostra che le proporzioni tra i vari mercati cittadini
rimangono quasi costanti durante tutti i 12 mesi.
# Creazione variabile data fittizia per serie storica continua
dati$data_storica <- as.Date(paste(dati$year, dati$month, "01", sep="-"))
ggplot(dati, aes(x = data_storica, y = median_price, color = city)) +
geom_line(linewidth = 1) +
labs(title = "Trend Storico del Prezzo Mediano", x = "Tempo", y = "Prezzo Mediano ($)") +
theme_minimal()
Commento: La serie storica conferma visivamente la
netta divaricazione dei prezzi di Bryan-College rispetto alle altre,
evidenziando le fluttuazioni cicliche infra-annuali attorno al trend di
crescita strutturale di lungo periodo.
Dalla nostra analisi del mercato del Texas emergono chiari indirizzi strategici per Texas Realty Insights: