Su richiesta di Texas Realty Insights, è stato analizzato un insieme di dati sulle vendite immobiliari in quattro città del Texas a partire da una tabella fornita dall’azienda stessa. I risultati di questa analisi saranno esposti in questo documento.
Dopo aver importato i dati e fornito delle indicazioni sul contesto in cui sono stati raccolti, saranno analizzate nel dettaglio le variabili coinvolte e si individueranno le caratteristiche più rilevanti in termini di variabilità e asimmetria. Dall’analisi delle singole variabili ci sposteremo poi sull’analisi condizionata di più variabili contemporaneamente anche tramite il supporto di simulazioni e rappresentazioni grafiche.
Questa sezione sarà dedicata all’importazione e a un’analisi di carattere generale dei dati.
I dati sono stati importati in un Dataframe R da un file CSV fornito dall’azienda committente.
df <- read.csv("realestate_texas.csv",
sep = ",")
Nella cella seguente saranno mostrate le dimensioni del dataset.
dim(df)
## [1] 240 8
La tabella è costituita da 240 osservazioni di cui sono state misurate 8 variabili. La cella seguente mostra le prime cinque righe del dataset.
head(df,
5)
## 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
La prima colonna, city, indica le città del Texas in cui sono state effettuate le rilevazioni. La cella seguente mostra i valori unici di questa colonna.
unique(df$city)
## [1] "Beaumont" "Bryan-College Station" "Tyler"
## [4] "Wichita Falls"
La colonna year indica l’anno a cui fa riferimento l’osservazione e, per questa analisi, sarà trattata come una variabile categorica e non come una variabile numerica. Di seguito si mostreranno i valori unici.
unique(df$year)
## [1] 2010 2011 2012 2013 2014
In modo analogo tratteremo come variabile categorica la colonna month, che indica il mese di riferimento dell’osservazione in formato numerico. Anche di questa colonna si mostreranno i valori unici.
unique(df$month)
## [1] 1 2 3 4 5 6 7 8 9 10 11 12
Nella cella seguente abbiamo verificato che il numero di righe della tabella è dato dal prodotto tra il numero di valori unici delle colonne city, year e month. Questo ci porta a confermare che i dati forniti rappresentino un riepilogo delle vendite sulla base di questi tre parametri.
length(unique(df$city)) *
length(unique(df$year)) *
length(unique(df$month)) == dim(df)[1]
## [1] TRUE
Passando alle variabili numeriche, i dati sulle vendite immobiliari sono indicati nelle colonne sales, volume e median_price, che indicano rispettivamente il numero di vendite registrate, il volume di vendite in milioni di dollari e il prezzo mediano, ossia la soglia di prezzo sotto cui sono stati venduti il 50% degli immobili. Di queste tre colonne sarà mostrato il range di valori nella cella seguente.
#Sales
range(df$sales)
## [1] 79 423
#Volume
range(df$volume) *
1000000
## [1] 8166000 83547000
#Median price
range(df$median_price)
## [1] 73800 180000
I dati sugli annunci immobiliari sono invece indicati nelle colonne listings e months_inventory, che riportano rispettivamente il numero di annunci attivi e i mesi previsti per vendere tutti gli annunci correnti. Anche in questo caso saranno mostrati i range di valori di queste colonne.
#Listings
range(df$listings)
## [1] 743 3296
#Months inventory
range(df$months_inventory)
## [1] 3.4 14.9
Riassumendo quanto esposto finora, possiamo dedurre quanto segue:
Il dettaglio riguardo ogni singola variabile sarà esplorato nella prossima sezione.
In questa sezione analizzeremo le variabili dal punto di vista della loro distribuzione.
Partendo dalle variabili categoriche, la cella seguente mostra le frequenze assolute e relative della colonna city. Non trattandosi di una variabile ordinale, non sono state calcolate le frequenze cumulate.
ni <- table(df$city)
fi <- ni/
dim(df)[1]
cbind(ni,
fi)
## ni fi
## Beaumont 60 0.25
## Bryan-College Station 60 0.25
## Tyler 60 0.25
## Wichita Falls 60 0.25
Come già anticipato nella precedente sezione, si osserva una distribuzione uniforme delle osservazioni tra le quattro città riportate nella tabella, a ulteriore conferma che i dati riguardano le vendite nell’arco di 60 mesi per ogni città.
In modo analogo, le due celle seguenti mostrano le distribuzioni di frequenze nelle colonne year e month che, ricordiamo, sono trattate come variabili qualitative di tipo ordinale per gli scopi di questa analisi.
ni <- table(df$year)
fi <- ni/
dim(df)[1]
Ni <- cumsum(ni)
Fi <- cumsum(fi)
cbind(ni,
fi,
Ni,
Fi)
## ni fi Ni Fi
## 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
ni <- table(df$month)
fi <- ni/
dim(df)[1]
Ni <- cumsum(ni)
Fi <- cumsum(fi)
cbind(ni,
fi,
Ni,
Fi)
## ni fi Ni Fi
## 1 20 0.08333333 20 0.08333333
## 2 20 0.08333333 40 0.16666667
## 3 20 0.08333333 60 0.25000000
## 4 20 0.08333333 80 0.33333333
## 5 20 0.08333333 100 0.41666667
## 6 20 0.08333333 120 0.50000000
## 7 20 0.08333333 140 0.58333333
## 8 20 0.08333333 160 0.66666667
## 9 20 0.08333333 180 0.75000000
## 10 20 0.08333333 200 0.83333333
## 11 20 0.08333333 220 0.91666667
## 12 20 0.08333333 240 1.00000000
Come anticipato in precedenza, la distribuzione dei dati è uniforme sia riguardo year che riguardo month. Osserviamo inoltre che metà delle osservazioni sono antecedenti al 2012 e riguardano il primo semestre di ogni anno.
Per quanto riguarda le variabili numeriche, come anche parzialmente evidenziato nella sezione precedente, le colonne presentano dati continui. Anche per agevolare la lettura di questi dati, è stata definita la funzione plot_distribution che, a partire da una colonna data in ingresso:
La funzione così definita è riportata nella cella seguente.
plot_distribution <- function(x){
mean_x <- mean(x)
sd_x <- sd(x)
quartiles_x <- quantile(x)
plot(density(x),
xlim = c(min(x),
max(x)),
main = "",
xlab = "",
ylab = "Freq. relativa")
lines(density(rnorm(1000000,
mean = mean_x,
sd = sd_x)),
lty = 2)
abline(v = quartiles_x[3],
col = "blue")
abline(v = quartiles_x[c(2,
4)],
col = "red")
abline(v = mean_x,
col = "green")
legend("bottom",
legend = c(paste("Mediana:",
round(quartiles_x[3],
1)),
paste("IQR:",
round(quartiles_x[2],1),
"-",
round(quartiles_x[4],1)),
paste("Media:",
round(mean_x,
1))),
col = c("blue",
"red",
"green"),
lty = c(1,
1,
1))
}
Testiamo la funzione plot_function sulla colonna sales del dataset.
plot_distribution(df$sales)
Osserviamo una distribuzione delle vendite asimmetrica rispetto alla normale con la stessa media e la stessa deviazione standard. Più nello specifico si evidenzia una tendenza a un basso numero di vendite per il 75% dei dati e una tendenza, seppur minore, a un numero di vendite comprese tra le 275 e le 300.
La cella seguente mostra la distribuzione della colonna volume.
plot_distribution(df$volume)
Il grafico è simile nella forma alla distribuzione vista con il numero di vendite, ma la seconda “gobba” di dati (intorno ai 50 milioni) è meno evidente rispetto al grafico precedente.
La cella seguente mostra la distribuzione della colonna median_price.
plot_distribution(df$median_price)
Il prezzo mediano è sì asimmetrico, ma in misura minore e soprattutto tende a mostrare come più frequenti i valori più alti, pur mostrando una tendenza minore intorno ai 100000 dollari.
La cella seguente mostra la distribuzione della colonna listings.
plot_distribution(df$listings)
Decisamente asimmetrica rispetto alla distribuzione normale, la colonna listings concentra il 50% dei dati tra i 1000 e i 2000 annunci attivi. La distribuzione mostra inoltre due tendenze minori, una nel primo 25% dei dati e l’altra tra i 2750 e i 3000 annunci attivi.
Infine, si mostra nella cella seguente la distribuzione della colonna months_inventory.
plot_distribution(df$months_inventory)
Come in median_price, i mesi di inventario tendono ad approssimare la distribuzione normale con la stessa media e la stessa deviazione standard, pur presentando una tendenza ai valori più bassi. Una seconda tendenza, di minore intensità, si osserva tra gli 11 e i 12 mesi.
Sulla base di quanto osservato in questa sezione, possiamo dedurre quanto segue:
In questa sezione ci concentreremo sulla variabilità e sull’asimmetria delle variabili viste in precedenza.
Come emerso nella sezione precedente, il diverso ordine di grandezza tra le variabili spinge a optare per il coefficiente di variazione come misura della variabilità dei dati, mentre per l’asimmetria sarà utilizzato l’indice di Fisher. Nella cella seguente è stata definita la funzione per il coefficiente di variazione ed è stata importata la libreria moments per il calcolo dell’asimmetria.
cv <- function(x){
return (sd(x)/
mean(x))*
100
}
library(moments)
Dalle colonne quantitative otterremo una tabella riassuntiva scores che calcola i valori di media, deviazione standard, coefficiente di variazione e indice di Fisher. Questa tabella è calcolata e stampata nella cella seguente.
columns <- c()
means <- c()
stdevs <- c()
cvs <- c()
fishers <- c()
for(i in 4:8){
columns <- append(columns,
colnames(df[i]))
means <- append(means,
mean(df[, i]))
stdevs <- append(stdevs,
sd(df[, i]))
cvs <- append(cvs,
cv(df[, i]))
fishers <- append(fishers,
skewness(df[, i]))
}
scores <- data.frame(
cols <- columns,
mean <- means,
sd <- stdevs,
cv <- cvs,
skew <- fishers
)
scores
## cols....columns mean....means sd....stdevs cv....cvs skew....fishers
## 1 sales 192.29167 79.651111 0.4142203 0.71810402
## 2 volume 31.00519 16.651447 0.5370536 0.88474203
## 3 median_price 132665.41667 22662.148687 0.1708218 -0.36455288
## 4 listings 1738.02083 752.707756 0.4330833 0.64949823
## 5 months_inventory 9.19250 2.303669 0.2506031 0.04097527
Nelle due celle seguenti, la tabella scores è stata ordinata in base ai valori del coefficiente di variazione e di asimmetria.
sort_by(scores[c(1,
4,
5)],
scores$cv....cvs)
## cols....columns cv....cvs skew....fishers
## 3 median_price 0.1708218 -0.36455288
## 5 months_inventory 0.2506031 0.04097527
## 1 sales 0.4142203 0.71810402
## 4 listings 0.4330833 0.64949823
## 2 volume 0.5370536 0.88474203
sort_by(scores[c(1,
4,
5)],
scores$skew....fishers)
## cols....columns cv....cvs skew....fishers
## 3 median_price 0.1708218 -0.36455288
## 5 months_inventory 0.2506031 0.04097527
## 4 listings 0.4330833 0.64949823
## 1 sales 0.4142203 0.71810402
## 2 volume 0.5370536 0.88474203
Notiamo che la colonna volume presenta sia la massima variabilità che la massima asimmetria. Visualizziamo nuovamente la sua distribuzione tramite la funzione plot_distribution.
plot_distribution(df$volume)
La colonna median_price, invece, presenta sia la minima variabilità che la minima asimmetria.
plot_distribution(df$median_price)
Dai risultati appena ottenuti possiamo dedurre quanto segue:
Il prezzo mediano sarà approfondito nella prossima sezione.
In questa sezione approfondiremo la distribuzione del prezzo mediano nel dataset suddividendolo in fasce di prezzo.
Allo scopo di interpretare più facilmente i dati, è stata aggiunta la colonna median_price_K che riscala la colonna median_price dividendone i valori per mille.
df$median_price_K <- df$median_price/
1000
Questa colonna è stata divisa in fasce da 10.000 dollari a partire da 70.000 dollari fino al massimo registrato di 180.000 dollari. Le fasce di prezzo sono state calcolate nella colonna median_price_CL.
df$median_price_CL <- cut(df$median_price_K,
breaks = seq(70,
180,
10))
Nella prima delle due celle che seguono sarà calcolata la distribuzione di frequenze delle classi di prezzo. La divisione in quartili del prezzo mediano, calcolata nella seconda cella, servirà come riferimento.
ni <- table(df$median_price_CL)
fi <- ni/
dim(df)[1]
Ni <- cumsum(ni)
Fi <- cumsum(fi)
cbind(ni,
fi,
Ni,
Fi)
## ni fi Ni Fi
## (70,80] 1 0.004166667 1 0.004166667
## (80,90] 10 0.041666667 11 0.045833333
## (90,100] 15 0.062500000 26 0.108333333
## (100,110] 23 0.095833333 49 0.204166667
## (110,120] 17 0.070833333 66 0.275000000
## (120,130] 29 0.120833333 95 0.395833333
## (130,140] 46 0.191666667 141 0.587500000
## (140,150] 39 0.162500000 180 0.750000000
## (150,160] 39 0.162500000 219 0.912500000
## (160,170] 15 0.062500000 234 0.975000000
## (170,180] 6 0.025000000 240 1.000000000
quantile(df$median_price_K)
## 0% 25% 50% 75% 100%
## 73.80 117.30 134.50 150.05 180.00
Nella cella seguente calcoleremo la media ponderata della suddivisione in classi e il rapporto percentuale con la media effettiva dei valori.
val_centrali <- seq(75,
175,
10)
weight_mean <- sum(val_centrali*ni)/
sum(ni)
weight_mean; round((weight_mean/
mean(df$median_price_K))*
100,
3)
## [1] 132.4167
## [1] 99.812
La cella che segue riepiloga in un grafico a barre la suddivisione nelle fasce di prezzo.
barplot(ni,
main = "Distribuzione del prezzo mediano (in migliaia di dollari)",
ylim = c(0,
50),
las = 2)
Infine, nella cella che segue calcoleremo l’indice di Gini della suddivisione in classi, che misura la tendenza del prezzo mediano a distribuirsi equamente tra le fasce indicate.
G <- 1 -
sum(fi^
2)
J <- length(fi)
gini <- G/
((J-1)/
J)
gini
## [1] 0.9586042
Da questi risultati osserviamo quanto segue:
In questa sezione ci occuperemo di effettuare delle simulazioni di probabilità sulle colonne city, month e year. In particolare, esamineremo tre eventi:
Ricordiamo brevemente che le tre colonne presentano ciascuna una distribuzione uniforme dei dati all’interno del dataset, perciò i risultati che si otterranno dalle simulazioni non cambieranno al variare dei parametri negli eventi da esaminare. Se poi noi utilizziamo un approccio classico alla probabilità, essa coinciderà con le frequenze relative dei valori in esame.
Nella cella seguente, calcoliamo quindi le probabilità degli eventi sopra citati.
p_beaumont <- sum(df$city == "Beaumont")/
dim(df)[1]
p_july <- sum(df$month == 7)/
dim(df)[1]
p_dec_12 <- sum(df$month == 12 &
df$year == 2012)/
dim(df)[1]
p_beaumont; p_july; p_dec_12
## [1] 0.25
## [1] 0.08333333
## [1] 0.01666667
Verifichiamo ora con un approccio frequentista questi risultati. L’idea è di simulare l’estrazione di un campione di questi dati e calcolare la frequenza relativa delle estrazioni in cui si verificano gli eventi descritti.
Per fare questo, definiamo la funzione simulate_extraction che, dato il numero N di simulazioni, estrae casualmente N record dal dataset.
simulate_extraction <- function(N){
rows <- sample(1:dim(df)[1],
N,
replace = TRUE)
return(df[rows, ])
}
Nella cella seguente costruiamo la tabella simulations che effettua fino a 100.000 simulazioni e calcola le frequenze relative degli eventi in esame (per semplicità, per un numero di simulazioni nullo, le frequenze saranno nulle a loro volta). All’interno della stessa cella, simulations sarà convertito in un dataframe per facilitare la visualizzazione della tabella.
simulations <- c()
for(N in seq(0,
100000,
1000)){
if(N == 0){
row_simulation <- c(N,
0,
0,
0)
}else{
df_simulation <- simulate_extraction(N)
row_simulation <- c(N,
sum(df_simulation$city == "Beaumont")/
N,
sum(df_simulation$month == 7)/
N,
sum(df_simulation$month == 12 &
df_simulation$year == 2012)/
N)
}
simulations <- rbind(simulations,
row_simulation)
}
simulations <- as.data.frame(simulations)
names(simulations) <- c("N. simulations",
"City = Beaumont",
"Month = July",
"Month-Year = December-2012")
Le tre celle seguenti riepilogano graficamente i risultati ottenuti. Il grafico a linee rappresenta le frequenze relative dei successi per il numero di simulazioni, mentre la linea tratteggiata rossa rappresenta la probabilità calcolata con l’approccio classico.
plot(simulations[c("N. simulations",
"City = Beaumont")],
main = "Estrazione della città di Beaumont",
xlab = "N. simulazioni",
ylab = "Freq. relative",
type = "l")
abline(h = p_beaumont,
col = "red",
lty = 2)
plot(simulations[c("N. simulations",
"Month = July")],
main = "Estrazione del mese di luglio",
xlab = "N. simulazioni",
ylab = "Freq. relative",
type = "l")
abline(h = p_july,
col = "red",
lty=2)
plot(simulations[c("N. simulations",
"Month-Year = December-2012")],
main = "Estrazione del mese di dicembre 2012",
xlab = "N. simulazioni",
ylab = "Freq. relative",
type = "l")
abline(h = p_dec_12,
col = "red",
lty=2)
Osserviamo che le frequenze relative dei tre eventi tenderanno alla probabilità calcolata all’aumentare del numero di prove. La fluttuazione di questi valori intorno alla probabilità è dovuta perlopiù alla casualità con cui sono stati estratti i campioni dalla funzione extract_simulations.
Questa sezione è dedicata alla creazione di nuove variabili a partire dalle colonne del dataset. Più nello specifico, saranno calcolati i seguenti indicatori:
Entrambi gli indicatori sono stati calcolati nella cella seguente. Allo scopo di facilitare la lettura e l’interpretazione dei dati, la colonna volume è stata moltiplicata per 1000000 (ricordiamo che il volume di vendite è espresso in milioni di dollari), mentre la colonna months_inventory è stata moltiplicata per 30 giorni e per 24 ore.
df$mean_price <- (df$volume*
1000000)/
df$sales
df$mean_inventory <- (df$months_inventory*
30*
24)/
df$listings
La cella seguente mostra le prime cinque righe delle colonne city, month e year insieme alle due colonne appena calcolate.
head(df[c("city",
"month",
"year",
"mean_price",
"mean_inventory")],
5)
## city month year mean_price mean_inventory
## 1 Beaumont 1 2010 170626.5 4.461840
## 2 Beaumont 2 2010 163796.3 4.539723
## 3 Beaumont 3 2010 157697.8 4.518650
## 4 Beaumont 4 2010 134095.0 4.468384
## 5 Beaumont 5 2010 142737.6 4.431395
Le due celle seguenti mostrano tramite la funzione plot_distribution le distribuzioni delle due nuove variabili.
plot_distribution(df$mean_price)
plot_distribution(df$mean_inventory)
Da questi risultati osserviamo quanto segue:
Questa sezione approfondirà il numero e il volume di vendita in base al tempo e alla città di riferimento.
La cella seguente mostrerà il numero di vendite nel tempo in base alla città di riferimento.
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
plot(filter(df,
city == "Beaumont")$sales,
main = "Vendite per città",
ylab = "Vendite",
ylim = c(min(df$sales),
max(df$sales)),
type = "l",
col = "blue",
xaxt = "n")
lines(filter(df,
city == "Bryan-College Station")$sales,
col="red")
lines(filter(df,
city=="Tyler")$sales,
col="darkgreen")
lines(filter(df, city == "Wichita Falls")$sales,
col="black")
legend("topleft",
legend = unique(df$city),
col = c("blue",
"red",
"darkgreen",
"black"),
lty=1)
axis(side = 1,
at = 1:60,
labels = unique(paste(df$month,
df$year,
sep = "/")),
las = 2)
Analogamente, la cella seguente mostra lo stesso tipo di grafico ma per i volumi di vendita.
plot(filter(df,
city == "Beaumont")$volume,
main = "Volume di vendite per città",
ylab = "Volume (in mln)",
ylim = c(min(df$volume),
max(df$volume)),
type = "l",
col = "blue",
xaxt = "n")
lines(filter(df,
city == "Bryan-College Station")$volume,
col="red")
lines(filter(df,
city == "Tyler")$volume,
col="darkgreen")
lines(filter(df,
city == "Wichita Falls")$volume,
col="black")
legend("topleft",
legend = unique(df$city),
col = c("blue",
"red",
"darkgreen",
"black"),
lty=1)
axis(side = 1,
at = 1:60,
labels =unique(paste(df$month,
df$year,
sep = "/")),
las = 2)
Si evidenzia quanto segue:
In questa sezione utilizzeremo la libreria ggplot per effettuare ulteriori analisi condizionate sul dataset.
Riprendendo dalla conclusione della precedente sezione, il grafico a barre nella cella seguente riepiloga le vendite in base alla città di riferimento.
library(ggplot2)
df_sales <- df %>%
group_by(city) %>%
summarise(
total_sales = sum(sales),
.groups = "drop"
)
ggplot(df_sales)+
geom_bar(aes(y = total_sales,
x = city),
stat = "identity")+
labs(title = "Vendite per città",
y = "Vendite",
x="Città")
Sempre condizionati dalla città di riferimento, i boxplot della cella seguente mostrano la distribuzione dei prezzi mediani.
ggplot(df)+
geom_boxplot(aes(y = median_price_K,
colour = city))+
scale_color_manual(values = c("blue",
"red",
"darkgreen",
"black"))+
labs(title = "Prezzo mediano per città",
y = "Prezzo mediano (in k)")
Infine, nella cella seguente i dati di vendita sono stati raggruppati in base all’anno e al mese di riferimento per poi essere mostrati in un grafico a linee.
df_time <- df %>%
group_by(year,
month) %>%
summarise(
total_sales = sum(sales),
.groups = "drop"
)
ggplot(df_time) +
geom_line(aes(x = paste(year,
month,
sep = "/"),
y = total_sales,
group = 1)) +
labs(title = "Vendite nel tempo",
x = "Mese e Anno",
y = "Vendite") +
scale_x_discrete(labels = paste(df_time$month,
df_time$year,
sep = "/"))+
theme(axis.text.x = element_text(angle = 90,
hjust = 1))
Da questi grafici osserviamo quanto segue:
L’ultima sezione del progetto è dedicata alle conclusioni che si sono potute trarre dai risultati delle precedenti sezioni.
Ricordiamo che il dataset fornito da Texas Realty Insights mostra i dati di vendita degli immobili nelle città di Beaumont, Bryan-College Station, Tyler e Wichita Falls nel quinquennio tra il 2010 e il 2014. Dalle simulazioni di calcolo delle probabilità sappiamo che la città, il mese e l’anno di riferimento dei record sono distribuiti nel dataset in modo uniforme.
Dall’analisi delle variabili e dagli indici di posizione, variabilità e forma è stata osservata una tendenza ai valori più bassi di vendite sia dal punto di vista del numero che da quello del volume. Ciò ci ha portato a dedurre un comportamento cauto nell’investimento immobiliare, mentre la minima variabilità e asimmetria registrate dal prezzo mediano hanno evidenziato una stabilità dei prezzi degli immobili, anche se la suddivisione in fasce di prezzo ci ha portato a concludere la tendenza a non concentrarsi su un unico valore, ma piuttosto a distribuirsi in modo quasi eterogeneo tra le fascie di prezzo.
Dal punto di vista degli annunci, l’esplorazione delle variabili ha contrapposto la stabilità dei mesi di inventario con la variabilità e l’asimmetria del numero di annunci attivi. Queste caratteristiche sono emerse anche nel calcolo del tempo medio di inventario, in cui si sono evidenziate sia la tendenza principale a evadere un annuncio in tempi molto brevi che una tendenza, seppur minore, ad avere tempi di vendita più lunghi.
Analizzando le vendite dal punto di vista delle città di riferimento, è emerso un comportamento ciclico del mercato immobiliare confermato anche dall’analisi delle vendite nel tempo, dove è emersa inoltre una crescita lineare delle vendite. Dall’ultima sezione, poi, è emerso che il maggiore numero di vendite si è registrato nella città di Tyler, mentre la fascia di prezzo mediano più elevata si è registrata nella città di Bryan-College Station.