#Pacchetti utili
library(moments)
library(dplyr)
library(tidyr)
library(ggplot2)
library(knitr)
#Caricamento e descrizione dei dati
dati <- read.csv("realestate_texas.csv", sep = ",")
N <- dim(dati)[1]
#Distribuzioni di frequenza per le variabili city, year e month
distr_freq <- function(x) {
t <- table(x)
data.frame(
Modalità = names(t),
Frequenza = as.vector(t),
Frequenza_relativa = as.vector(t / sum(t)),
Frequenza_cumulata = cumsum(as.vector(t)),
Frequenza_relativa_cumulata = cumsum(as.vector(t / sum(t)))
)
}
distr_freq_city <- distr_freq(dati$city)
distr_freq_year <- distr_freq(dati$year)
distr_freq_month <- distr_freq(dati$month)
kable(distr_freq_city, digits = 3,
caption = "Distribuzione di frequenza della variabile City")
| Modalità | Frequenza | Frequenza_relativa | Frequenza_cumulata | Frequenza_relativa_cumulata |
|---|---|---|---|---|
| Beaumont | 60 | 0.25 | 60 | 0.25 |
| Bryan-College Station | 60 | 0.25 | 120 | 0.50 |
| Tyler | 60 | 0.25 | 180 | 0.75 |
| Wichita Falls | 60 | 0.25 | 240 | 1.00 |
kable(distr_freq_year, digits = 3,
caption = "Distribuzione di frequenza della variabile Year")
| Modalità | Frequenza | Frequenza_relativa | Frequenza_cumulata | Frequenza_relativa_cumulata |
|---|---|---|---|---|
| 2010 | 48 | 0.2 | 48 | 0.2 |
| 2011 | 48 | 0.2 | 96 | 0.4 |
| 2012 | 48 | 0.2 | 144 | 0.6 |
| 2013 | 48 | 0.2 | 192 | 0.8 |
| 2014 | 48 | 0.2 | 240 | 1.0 |
kable(distr_freq_month, digits = 3,
caption = "Distribuzione di frequenza della variabile Month")
| Modalità | Frequenza | Frequenza_relativa | Frequenza_cumulata | Frequenza_relativa_cumulata |
|---|---|---|---|---|
| 1 | 20 | 0.083 | 20 | 0.083 |
| 2 | 20 | 0.083 | 40 | 0.167 |
| 3 | 20 | 0.083 | 60 | 0.250 |
| 4 | 20 | 0.083 | 80 | 0.333 |
| 5 | 20 | 0.083 | 100 | 0.417 |
| 6 | 20 | 0.083 | 120 | 0.500 |
| 7 | 20 | 0.083 | 140 | 0.583 |
| 8 | 20 | 0.083 | 160 | 0.667 |
| 9 | 20 | 0.083 | 180 | 0.750 |
| 10 | 20 | 0.083 | 200 | 0.833 |
| 11 | 20 | 0.083 | 220 | 0.917 |
| 12 | 20 | 0.083 | 240 | 1.000 |
dati_num <- dati %>%
select(year, month, sales, volume, median_price, listings, months_inventory)
#Calcolo degli indici di posizione
posizione <- dati_num %>%
summarise(across(
everything(),
list(
Media = ~mean(., na.rm = TRUE),
Mediana = ~median(., na.rm = TRUE),
Min = ~min(., na.rm = TRUE),
Max = ~max(., na.rm = TRUE)
)
)) %>%
pivot_longer(
cols = everything(),
names_to = c("Variabile", ".value"),
names_pattern = "(.*)_(.*)"
)
kable(posizione, digits = 2,
caption = "Indici di posizione")
| Variabile | Media | Mediana | Min | Max |
|---|---|---|---|---|
| year | 2012.00 | 2012.00 | 2010.00 | 2014.00 |
| month | 6.50 | 6.50 | 1.00 | 12.00 |
| sales | 192.29 | 175.50 | 79.00 | 423.00 |
| volume | 31.01 | 27.06 | 8.17 | 83.55 |
| median_price | 132665.42 | 134500.00 | 73800.00 | 180000.00 |
| listings | 1738.02 | 1618.50 | 743.00 | 3296.00 |
| months_inventory | 9.19 | 8.95 | 3.40 | 14.90 |
#Calcolo degli indici di variabilità
CV <- function(x) sd(x, na.rm = TRUE) / mean(x, na.rm = TRUE) * 100
variabilita <- dati_num %>%
summarise(across(
everything(),
list(
Range = ~max(., na.rm = TRUE) - min(., na.rm = TRUE),
IQR = ~IQR(., na.rm = TRUE),
Var = ~var(., na.rm = TRUE),
SD = ~sd(., na.rm = TRUE),
CV = ~sd(., na.rm = TRUE) / mean(., na.rm = TRUE) * 100
)
)) %>%
pivot_longer(
cols = everything(),
names_to = c("Variabile", ".value"),
names_pattern = "(.*)_(.*)"
)
kable(variabilita, digits = 2,
caption = "Indici di variabilità")
| Variabile | Range | IQR | Var | SD | CV |
|---|---|---|---|---|---|
| year | 4.00 | 2.00 | 2.01000e+00 | 1.42 | 0.07 |
| month | 11.00 | 5.50 | 1.19700e+01 | 3.46 | 53.22 |
| sales | 344.00 | 120.00 | 6.34430e+03 | 79.65 | 41.42 |
| volume | 75.38 | 23.23 | 2.77270e+02 | 16.65 | 53.71 |
| median_price | 106200.00 | 32750.00 | 5.13573e+08 | 22662.15 | 17.08 |
| listings | 2553.00 | 1029.50 | 5.66569e+05 | 752.71 | 43.31 |
| months_inventory | 11.50 | 3.15 | 5.31000e+00 | 2.30 | 25.06 |
#Calcolo degli indici di forma
forma <- dati_num %>%
summarise(across(
everything(),
list(
Asimmetria = ~skewness(., na.rm = TRUE),
Curtosi = ~kurtosis(., na.rm = TRUE) - 3
)
)) %>%
pivot_longer(
cols = everything(),
names_to = c("Variabile", ".value"),
names_pattern = "(.*)_(.*)"
)
kable(forma, digits = 2,
caption = "Indici di forma")
| Variabile | Asimmetria | Curtosi |
|---|---|---|
| year | 0.00 | -1.30 |
| month | 0.00 | -1.22 |
| sales | 0.72 | -0.31 |
| volume | 0.88 | 0.18 |
| median_price | -0.36 | -0.62 |
| listings | 0.65 | -0.79 |
| months_inventory | 0.04 | -0.17 |
Il dataset in esame contiene 240 osservazioni di 8 variabili statistiche. L’unica variabile qualitativa nominale è “city”, che identifica la città di riferimento e presenta quattro diverse modalità (Beaumont, Bryan-College Station, Tyler, Wichita Falls). Data la sua natura di variabile qualitativa non ha un ordine naturale e le analisi conducibili su di essa riguardano la distribuzione di frequenza assoluta e relativa e la moda come unico indice di tendenza centrale. Non è possibile calcolare media, mediana o indici di variabilità basati su distanze poiché le categorie non sono ordinabili. Le variabili “year” e “month” sono variabili quantitative discrete che permettono di scandire la dimensione tempo e per le quali l’ordinamento è intrinseco ma la distanza numerica non descrive una relazione quantitativa tra le categorie. In particolare “year” è temporale lineare e riguarda il periodo di osservazione e raccolta dei dati che si estende per cinque anni, dal 2010 al 2014, e permette analisi di trend e serie storiche, è ordinabile e le distanze temporali sono significative ed è utile al fine di calcolare tassi di crescita e variazioni; mentre “month” è una variabile temporale ciclica e risulta utile per analisi di stagionalità. Per questa variabile gli indici classici come media aritmetica possono essere calcolati dal punto di vista tecnico, ma risultano di scarso interesse interpretativo: ad esempio, la “media dei mesi” non descrive una caratteristica significativa del fenomeno. Per entrambe le variabili è possibile creare aggregazioni, ad esempio (trimestri, semestri, quadrimestri) e condurre analisi comparative tra periodi. Invece la variabile temporale “month_inventory” non rappresenta solo un punto nel tempo ma una misura economica che quantifica l’ammontare di offerta disponibile. Pertanto quest’ultima si può considerare come variabile quantitativa continua su cui è possibile calcolare tutti gli indici di posizione, variabilità e forma. Le variabili “sales” e “listings” rappresentano rispettivamente il numero totale di vendite immobiliari e il numero totale di annunci attivi pertanto si possono definire come variabili quantitative discreta e, come tali, possono assumere solo valori interi e positivi. Su di esse è possibile calcolare gli indici di posizione e di variabilità. Infine le variabili “volume” e “median_price” sono variabili quantitative continue, e per loro è possibile calcolare tutti gli indici di posizione, variabilità e forma.
Dall’analisi del dataset a disposizione emerge che, la variabile “city” mostra una distribuzione di frequenze perfettamente uniforme infatti ogni modalità presenta lo stesso numero di occorrenze cioè 60 e una frequenza relativa pari al 25%. La moda quindi non è definita univocamente dato che tutte le modalità sono equiprobabili. Analogamente le distribuzioni di frequenze relative alle variabili “year” e “month” suggeriscono distribuzioni uniformi avendo rispettivamente 48 occorrenze all’anno con frequenza relativa del 20% e 20 occorrenze al mese con frequenza relativa pari all’8.33%. Pertanto il dataset risulta ben bilanciato anche temporalmente. Le vendite mensili hanno una media di circa 192 unità e una mediana di 175,5, con una deviazione standard pari a circa 79. Il volume medio delle transazioni è di circa 31 milioni, con una dispersione piuttosto elevata, mentre il prezzo mediano degli immobili si colloca attorno ai 133 mila dollari, con una variabilità più contenuta. Le inserzioni hanno una media di circa 1738 unità, mentre l’inventario espresso in mesi ha una media di poco superiore a 9 mesi. L’asimmetria mostra che sales, volume e listings sono asimmetriche a destra, mentre median_price presenta una lieve asimmetria negativa e months_inventory è quasi simmetrica.
La variabile con più alta variabilità è quella che presenta un coefficiente di variabilità (CV) maggiore mentre quella più asimmetrica è quella che presenta una skewness maggiore: nel caso in esame le due variabili coincidono ed è la variabile “volume” rispettivamente con CV pari a 53.71 e skewness pari a +0.88. Alla luce dei risultati ottenuti emerge che la variabilità è molto alta rispetto alla media che quindi rappresenta poco bene il fenomeno e i dati sono poco concentrati attorno al valor medio infatti la deviazione standard (16.65) si discosta molto dalla media (31.01). In più l’asimmetria positiva indica che la distribuzione è asimmetrica verso destra, con coda lunga verso valori alti e con probabili outlier molto elevati; tuttavia complessivamente l’asimmetria è moderata e ciò è visibile anche dal fatto che la media 31.01 è maggiore della mediana 27.06.
sales_cl <- cut(dati$sales, breaks = 5)
freq_sales <- table(sales_cl)
distr_freq_sales <- as.data.frame(
cbind(
freq_ass=table(sales_cl),
freq_rel=table(sales_cl)/N,
freq_cum_ass=cumsum(table(sales_cl)),
freq_cum_rel=cumsum(table(sales_cl)/N)
)
)
La variabile scelta è sales ed è stata suddivisa in cinque classi equispaziate garantendo un buon dettaglio informativo dato che le classi permettono di calcolare la forma della distribuzione, adeguata leggibilità e bilanciamento senza perdite di informazione. In questo modo ogni classe ha la stessa ampiezza numerica ma diversa frequenza di osservazioni all’interno di ciascuna classe. La distribuzione di frequenze ottenuta è riportata nella seguente tabella:
kable(distr_freq_sales, digits = 3,
caption = "Distribuzione di frequenza della variabile sales")
| freq_ass | freq_rel | freq_cum_ass | freq_cum_rel | |
|---|---|---|---|---|
| (78.7,148] | 84 | 0.350 | 84 | 0.350 |
| (148,217] | 77 | 0.321 | 161 | 0.671 |
| (217,285] | 41 | 0.171 | 202 | 0.842 |
| (285,354] | 27 | 0.112 | 229 | 0.954 |
| (354,423] | 11 | 0.046 | 240 | 1.000 |
gini.index <- function(x){
ni <- table(x)
fi <- ni / sum(ni)
J <- length(ni)
gini <- 1 - sum(fi^2)
gini_norm <- gini / ((J - 1) / J)
return(gini_norm)
}
gini.index(sales_cl)
## [1] 0.9132812
#creazione del grafico a barre
ymax <- max(freq_sales)
barplot(freq_sales,
main = "Distribuzione di frequenze di vendite mensili",
xlab = "Classi di vendite",
ylab = "Frequenza",
col = "steelblue",
names.arg = rownames(freq_sales),
ylim = c(0, ymax * 1.15)
)
La classe modale è la prima, definita nell’intervallo (79, 148] e contiene 84 osservazioni, rappresenta la fascia di vendite più frequente nel dataset e anche il primo quartile. La classe mediana è relativa al secondo intervallo (148, 217] e infine il terzo quartile è la terza classe, definita nell’intervallo (217, 285]. La distribuzione di frequenze, rappresentata mediante grafico a barre, mostra un’evidente asimmetria positiva dato che le barre diminuiscono progressivamente in altezza da sinistra verso destra e la coda destra si estende verso valori alti ma con frequenze decrescenti indicando possibili outlier in determinati periodi. L’asimmetria suggerisce che la media sarà maggiore della mediana. L’indice di eterogeneità di Gini normalizzato è stato calcolato sulla distribuzione delle frequenza delle classi e risulta essere pari a 0.91 = 91% indicando appunto che la distribuzione è molto eterogenea: i dati non sono concentrati in una sola classe ma distribuiti su tutte anche se in modo non uniforme.
N <- nrow(dati)
N_beaumont <- sum(dati$city == "Beaumont")
P_Beaumont <- N_beaumont/N
print(P_Beaumont)
## [1] 0.25
N_luglio <- sum(dati$month == 7)
P_july <- N_luglio/N
print(P_july)
## [1] 0.08333333
N_dic_2012_all <- sum(dati$month == 12 & dati$year == 2012)
P_dice_2012_all <- N_dic_2012_all/N
print(P_dice_2012_all)
## [1] 0.01666667
N_dic_2012_beaum <- sum(dati$month == 12 & dati$year == 2012 & dati$city == "Beaumont")
P_dic_2012_beaum <- N_dic_2012_beaum/N
print(P_dic_2012_beaum)
## [1] 0.004166667
dati$price <- (dati$volume * 1000000) / dati$sales
dati$efficiency <- (dati$sales / dati$listings) * 100
La probabilità che venga estratta la città Beaumont è 0.25. Essendo la variabile city uniforme tutte le modalità che assume sono equiprobabili pertanto ogni città avrà il 25% di probabilità di essere estratta casualmente. La probabilità che la riga estratta riporti invece il mese di luglio è 0.0834, infine la probabilità che riporti il mese di dicembre è 0.0167 considerando tutte le città, oppure 0.0041 per una città specifica, ad esempio Beaumont ma essendo ogni città equiprobabile il valore rimane invariato per tutte.
Il prezzo medio degli immobili si può calcolare dividendo il valore totale delle vendite per il numero totale di vendite, dopo aver reso l’unità di misura coerente, ovvero price = (volume x 1000000)/sales. Questa variabile quantitativa continua rappresenta una stima del prezzo medio per immobile nel periodo considerato, fornisce un’informazione complementare al prezzo mediano e risulta più sensibile ai mesi con transazioni di valore elevato. Invece l’efficacia degli annunci si può calcolare come rapporto tra il numero totale di vendite e il numero di annunci attivi, cioè efficacy = sales / listings. E’ una variabile quantitativa continua che sintetizza il rapporto tra domanda e offerta quindi misura la dinamica del mercato immobiliare e risulta utile per valutare l’equilibrio domanda-offerta.
#Analisi condizionata
#Statistiche per città, anno e mese (sales)
summary_city <- dati %>%
group_by(city) %>%
summarise(mean_sales = mean(sales),
sd_sales = sd(sales),
mean_price = mean(price),
sd_price = sd(price),
mean_volume = mean(volume),
sd_volume = sd(volume))
kable(summary_city, digits = 2,
caption = "Statistiche descrittive per città")
| city | mean_sales | sd_sales | mean_price | sd_price | mean_volume | sd_volume |
|---|---|---|---|---|---|---|
| Beaumont | 177.38 | 41.48 | 146640.4 | 11232.13 | 26.13 | 6.97 |
| Bryan-College Station | 205.97 | 84.98 | 183534.3 | 15149.35 | 38.19 | 17.25 |
| Tyler | 269.75 | 61.96 | 167676.8 | 12350.51 | 45.77 | 13.11 |
| Wichita Falls | 116.07 | 22.15 | 119430.0 | 11398.48 | 13.93 | 3.24 |
summary_year <- dati %>%
group_by(year) %>%
summarise(mean_sales = mean(sales),
sd_sales = sd(sales),
mean_volume = mean(volume),
sd_volume = sd(volume))
kable(summary_year, digits = 2,
caption = "Statistiche descrittive per anno")
| year | mean_sales | sd_sales | mean_volume | sd_volume |
|---|---|---|---|---|
| 2010 | 168.67 | 60.54 | 25.68 | 10.80 |
| 2011 | 164.12 | 63.87 | 25.16 | 12.20 |
| 2012 | 186.15 | 70.91 | 29.27 | 14.52 |
| 2013 | 211.92 | 84.00 | 35.15 | 17.93 |
| 2014 | 230.60 | 95.51 | 39.77 | 21.19 |
summary_month <- dati %>%
group_by(month) %>%
summarise(mean_sales = mean(sales),
sd_sales = sd(sales),
mean_volume = mean(volume),
sd_volume = sd(volume))
kable(summary_month, digits = 2,
caption = "Statistiche descrittive per mese")
| month | mean_sales | sd_sales | mean_volume | sd_volume |
|---|---|---|---|---|
| 1 | 127.40 | 43.38 | 19.00 | 8.37 |
| 2 | 140.85 | 51.07 | 21.65 | 10.09 |
| 3 | 189.45 | 59.18 | 29.38 | 12.02 |
| 4 | 211.70 | 65.40 | 33.30 | 14.52 |
| 5 | 238.85 | 83.12 | 39.70 | 19.02 |
| 6 | 243.55 | 95.00 | 41.30 | 21.08 |
| 7 | 235.75 | 96.27 | 39.12 | 21.41 |
| 8 | 231.45 | 79.23 | 38.01 | 18.05 |
| 9 | 182.35 | 72.52 | 29.60 | 15.22 |
| 10 | 179.90 | 74.95 | 29.08 | 15.13 |
| 11 | 156.85 | 55.47 | 24.81 | 11.15 |
| 12 | 169.40 | 60.75 | 27.09 | 12.57 |
ymax_s <- max(summary_city$mean_sales)
barplot(summary_city$mean_sales,
main = "Figura 1: Vendite medie mensili per città",
xlab = "Città",
ylab = "Vendite medie",
col = "steelblue",
ylim = c(0, ymax_s * 1.15),
names.arg = summary_city$city)
ymax_p <- max(summary_city$mean_price)
barplot(summary_city$mean_price,
main = "Figura 2: Prezzo medio stimato degli immobili per città",
xlab = "Città",
ylab = "Prezzo medio [$]",
col = "blue",
ylim = c(0, ymax_p * 1.15),
names.arg = summary_city$city)
month_names <- c("Gennaio", "Febbraio", "Marzo", "Aprile",
"Maggio", "Giugno", "Luglio", "Agosto",
"Settembre", "Ottobre", "Novembre", "Dicembre")
ymax_m <- max(summary_month$mean_sales)
barplot(summary_month$mean_sales,
names.arg = month_names,
col = "darkorange",
main = "Figura 3: Vendite medie mensili",
xlab = "Mese",
ylab = "Vendite medie",
ylim = c(0, ymax_m * 1.15))
plot(summary_year$year,
summary_year$mean_sales,
type = "o",
pch = 16,
col = "steelblue",
lwd = 2,
ylim = c(min(summary_year$mean_sales),
max(summary_year$mean_sales)),
main = "Figura 4: Vendite medie annuali",
xlab = "Anno",
ylab = "Vendite medie")
#Punto 8 del progetto
#Grafico per confronto prezzo tra città
ggplot(dati, aes(x = city, y = price, fill = city)) +
geom_boxplot(alpha = 0.7, outlier.color = "red") +
labs(
title = "Figura 5: Distribuzione del prezzo medio stimato per città",
x = "Città",
y = "Prezzo medio stimato [$]"
) +
theme_minimal() +
theme(legend.position = "none")
#Grafico per boxplot volume per città
ggplot(dati, aes(x = city, y = volume, fill = city)) +
geom_boxplot(alpha = 0.7) +
labs(
title = "Figura 6: Distribuzione del volume delle vendite per città",
x = "Città",
y = "Volume"
) +
theme_minimal() +
theme(legend.position = "none")
#Grafico per boxplot volume per anno
ggplot(dati, aes(x = factor(year), y = volume, fill = factor(year))) +
geom_boxplot(alpha = 0.7) +
labs(
title = "Figura 7: Distribuzione del volume delle vendite per anno",
x = "Anno",
y = "Volume"
) +
theme_minimal() +
theme(legend.position = "none")
#aggregazione
sales_month_city_year <- dati %>%
group_by(city, year, month) %>%
summarise(total_sales = sum(sales), .groups = "drop")
month_names_s <- c("Gen", "Feb", "Mar", "Apr",
"Mag", "Giu", "Lug", "Ago",
"Set", "Ott", "Nov", "Dic")
sales_month_city_year <- sales_month_city_year %>%
mutate(month = factor(month,
levels = 1:12,
labels = month_names_s))
#grafico a barre sovrapposte
ggplot(sales_month_city_year,
aes(x = factor(month), y = total_sales, fill = city)) +
geom_col() +
facet_wrap(~ year) +
labs(
title = "Figura 8: Vendite totali mensili per città e anno",
x = "Mese",
y = "Vendite totali"
) +
theme_minimal()
#grafico a barre normalizzato
ggplot(sales_month_city_year,
aes(x = factor(month), y = total_sales, fill = city)) +
geom_col(position = "fill") +
facet_wrap(~ year) +
labs(
title = "Figura 9: Distribuzione percentuale delle vendite mensili",
x = "Mese",
y = "Proporzione"
) +
theme_minimal()
#Line chart confronto tra città e periodi storici
sales_year_city <- dati %>%
group_by(city, year) %>%
summarise(mean_sales = mean(sales), .groups = "drop")
ggplot(sales_year_city,
aes(x = year, y = mean_sales, color = city)) +
geom_line(linewidth = 1) +
geom_point() +
labs(
title = "Figura 10: Andamento delle vendite medie nel tempo per città",
x = "Anno",
y = "Vendite medie"
) +
theme_minimal()
Dall’analisi delle figure 2 e 5 si può osservare come ogni città abbia un proprio livello di prezzo ben definito e stabile nel tempo. Bryan-College Station si posiziona come il mercato più costoso con prezzi attorno ai 185 mila dollari, seguita da Tyler sui 170 mila. Beaumont si colloca in una fascia intermedia attorno ai 145 mila dollari, mentre Wichita Falls rappresenta l’opzione più accessibile con prezzi medi di circa 120 mila dollari. Si può notare è che questi gap di prezzo rimangono costanti durante tutto il periodo analizzato, suggerendo che ogni città abbia caratteristiche economiche e demografiche proprie che mantengono i mercati separati l’uno dall’altro.
Guardando i volumi di transazione nelle figure 1 e 6, Tyler emerge come il mercato più attivo con circa 45 vendite al mese in media, rappresentando da sola quasi la metà di tutte le transazioni dell’area. Questa città mostra però anche una volatilità significativa, con alcuni mesi che arrivano a superare le 80 unità vendute. Bryan-College Station e Beaumont si attestano su livelli intermedi con rispettivamente 33 e 27 vendite mensili, mentre Wichita Falls rappresenta un mercato molto più piccolo con solo 14 transazioni al mese in media. Questo volume ridotto potrebbe creare problemi di liquidità per chi vuole vendere rapidamente in quella zona.
Uno degli aspetti più significativi dell’analisi riguarda l’evoluzione temporale delle vendite visibile nelle figure 4, 7 e 10. Dopo aver toccato il minimo nel 2011 con circa 165 vendite medie, il mercato ha iniziato una crescita costante e sostenuta che ha portato le vendite a 230 unità nel 2014, quasi raddoppiando in tre anni. Questa ripresa però non è stata uniforme: Tyler e Bryan-College Station hanno guidato la crescita con incrementi molto robusti passando rispettivamente da 230 a 350 unità e da 170 a 265 unità annuali, mentre Beaumont e Wichita Falls sono rimaste relativamente piatte, fenomeno probabilmente legato a fondamentali economici locali diversi tra le città.
Il mercato texano mostra, nelle figure 3 e 8 una stagionalità molto pronunciata che si ripete con notevole regolarità ogni anno. Durante i mesi estivi, particolarmente tra maggio e luglio, le vendite raggiungono picchi di 230-240 unità mensili, mentre gennaio rappresenta sistematicamente il mese più debole con appena 125 vendite. Questo differenziale di quasi il 90% è probabilmente dovuto a fattori multipli: il clima più favorevole per i traslochi, la fine dell’anno scolastico che facilita i trasferimenti familiari, e probabilmente anche cicli legati alle chiusure fiscali aziendali. La consistenza di questo pattern anno dopo anno indica che si tratta di dinamiche strutturali del mercato piuttosto che fluttuazioni casuali.
Nonostante la crescita complessiva del mercato, le proporzioni relative tra le città sono rimaste stabili come si nota nelle figure 8 e 9. Tyler mantiene costantemente una quota tra il 40 e il 50% delle vendite totali, mentre Bryan-College Station e Beaumont si spartiscono circa il 20-25% ciascuna, lasciando a Wichita Falls una quota minoritaria del 10-15%. Questa stabilità nelle quote di mercato, combinata con la persistenza dei gap di prezzo, rafforza l’idea di mercati locali distinti con barriere geografiche o economiche che prevengono una vera integrazione regionale.
L’analisi rivela alcune caratteristiche importanti da considerare per eventuali modelli predittivi e visibili dalle figure 3, 4, 6 e 7 . Tyler presenta una variabilità molto più alta rispetto alle altre città, con presenza di outlier significativi che potrebbero distorcere analisi basate su medie semplici. La forte componente stagionale richiederebbe la separazione di trend e stagionalità. Inoltre, la presenza dei pattern potrebbe funzionare bene per le previsioni a breve termine, mentre per il lungo termine sarebbe necessario aggiungere variabili economiche esterne ad esempio tassi di occupazione, crescita demografica e sviluppo industriale locale.
È importante sottolineare alcune limitazioni significative di questa analisi. I dati si fermano al 2014, quindi sono ormai datati di oltre dieci anni e potrebbero non riflettere le dinamiche attuali del mercato, soprattutto considerando eventi successivi come la pandemia e i cambiamenti nei tassi di interesse. Inoltre, l’analisi si concentra solo su prezzi medi e volumi, senza informazioni sulle caratteristiche specifiche delle proprietà come metratura, età, condizioni o localizzazione precisa all’interno di ogni città.