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 ottimizzazione delle inserzioni immobiliari.
Identificare e interpretare i trend storici delle vendite immobiliari in Texas. Valutare l’efficacia delle strategie di marketing delle inserzioni immobiliari. Offrire una rappresentazione grafica dei dati che evidenzi la distribuzione dei prezzi e delle vendite tra città, mesi e anni.
L’analisi statistica proposta permetterà a Texas Realty Insights di ottimizzare le loro strategie di mercato, identificando città con opportunità di crescita e valutando l’efficacia delle inserzioni immobiliari nel tempo. Grazie a una visione chiara e strutturata dei dati, l’azienda potrà prendere decisioni basate su informazioni concrete, migliorando la gestione delle vendite immobiliari in Texas.
data <- read.csv("C:/Users/fede_/Documents/professionai/statistica_descrittiva/realestate_texas.csv")
attach(data)
cat("Rows:", nrow(data), "Columns:", ncol(data), "\n")
## Rows: 240 Columns: 8
head(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
print(unique(city))
## [1] "Beaumont" "Bryan-College Station" "Tyler"
## [4] "Wichita Falls"
print(unique(year))
## [1] 2010 2011 2012 2013 2014
print(unique(month))
## [1] 1 2 3 4 5 6 7 8 9 10 11 12
Il dataset è composto da 240 osservazioni e 8 variabili. Ciascuna
osservazione rappresenta la registrazione di diverse informazioni per
una determinata città, in un determinato anno e mese. Sono presenti 4
città, registrate ogni mese tra il 2010 e il 2014 (4 città x 5 anni x 12
mesi = 240). Per ciascuna città, in ciascun anno e mese, il dataset
riporta: il numero e il valore totale delle vendite, il prezzo mediano
di vendita, il numero di annunci attivi, e il tempo richiesto per
vendere tutte le inserzioni.
Certamente, potrebbe essere interessante indagare come queste variabili
varino nel tempo, analizzando le differenze tra le diverse città.
Sarebbe interessante, però, indagare anche la relazione tra le diverse
variabli. Per esempio, si potrebbe osservare come varino il tempo
richiesto per vendere tutte le inserzioni, il numereo e il valore totale
delle vendite, al variare del prezzo mediano o del numero di annunci
attivi.
library(moments)
measures <- c("Minimo", "Q1", "Q3", "Massimo", "Mediana", "Media")
vars <- c("sales", "volume", "median_price", "listings", "months_inventory")
results <- matrix(nrow = length(measures), ncol = length(vars))
rownames(results) <- measures
colnames(results) <- vars
for (i in seq_along(vars)) {
x <- data[[vars[i]]]
results[ , i] <- c(
min(x),
quantile(x, 0.25),
quantile(x, 0.75),
max(x),
median(x),
mean(x)
)
}
results <- as.data.frame(results)
results <- round(results, 3)
print(results)
## sales volume median_price listings months_inventory
## Minimo 79.000 8.166 73800.0 743.000 3.400
## Q1 127.000 17.660 117300.0 1026.500 7.800
## Q3 247.000 40.893 150050.0 2056.000 10.950
## Massimo 423.000 83.547 180000.0 3296.000 14.900
## Mediana 175.500 27.062 134500.0 1618.500 8.950
## Media 192.292 31.005 132665.4 1738.021 9.193
Nel complesso, osservando questi indici è possibile fare diverse considerazioni. Il valore totale medio delle vendite in un mese è di circa 31 milioni, con un range che va da un minimo di 8 milioni ad un massimo di 83 milioni a mese. Mediamente, ogni mese sono stati venduti circa 192 mila immobili. Inoltre, nei 5 anni considerati (2010-2014), nel 75% dei mesi gli immobili venduti sono stati almeno 127 mila. In media, il prezzo mediano di vendita è stato di circa 132 mila dollari, con un massimo di 180 mila dollari. Il numero minimo di annunci attivi in un mese è stato di 743, con un massimo di 3296. Nel 25% dei casi sono sempre stati più di 1000, mentre solo nel 25% dei casi sono stati più di 2000. Infine, in media sono serviti circa 9 mesi per vendere tutte le inserzioni del mese, con un massimo di più di un anno (15 mesi) e uun minimo di poco più di un trimestre.
measures <- c("Variance", "DevStd","CV", "Asimmetria", "Curtosi")
vars <- c("sales", "volume", "median_price", "listings", "months_inventory")
results <- matrix(nrow = length(measures), ncol = length(vars))
rownames(results) <- measures
colnames(results) <- vars
for (i in seq_along(vars)) {
x <- data[[vars[i]]]
results[ , i] <- c(
var(x),
sd(x),
sd(x)/mean(x),
skewness(x),
kurtosis(x)
)
}
results <- as.data.frame(results)
results <- round(results, 3)
print(results)
## sales volume median_price listings months_inventory
## Variance 6344.300 277.271 513572983.089 566568.966 5.307
## DevStd 79.651 16.651 22662.149 752.708 2.304
## CV 0.414 0.537 0.171 0.433 0.251
## Asimmetria 0.718 0.885 -0.365 0.649 0.041
## Curtosi 2.687 3.177 2.377 2.208 2.826
La variabile con varianza e deviazione standard più ampie è il prezzo mediano di vendita. Tuttavia, questi indici risentono della scala della misura, rendendo impossibile un confronto tra diverse varabili. Per questo, la variabile con maggiore variabilità è il valore totale delle vendite in un mese, con un coefficiente di variazione (CV) di 0.537. Inoltre, la stessa variable è anche la più asimmetrica, con un indice di asimmetria di 0.885. Questo ci fa intuire che la distribuzione sia schiacciata a destra, con una lunga coda a sinistra
categories <- cut(
median_price,
breaks = c(70000, 100000, 120000, 140000, 160000, 190000),
labels = c("<100 mila", "100-120 mila", "120-140 mila", "140-160 mila", ">160 mila")
)
ni <- table(categories)
fi <- ni / dim(data)[1]
Ni <- cumsum(ni)
Fi <- Ni / dim(data)[1]
freq_tab <- cbind(ni, fi, Ni, Fi)
print(freq_tab)
## ni fi Ni Fi
## <100 mila 26 0.1083333 26 0.1083333
## 100-120 mila 40 0.1666667 66 0.2750000
## 120-140 mila 75 0.3125000 141 0.5875000
## 140-160 mila 78 0.3250000 219 0.9125000
## >160 mila 21 0.0875000 240 1.0000000
barplot(fi,
main="Distribuzione delle Classi del Prezzo Mediano",
xlab="Classe di Prezzo Mediano",
ylab="Frequenze Relative",
col="blue",
names.arg=rownames(freq_tab))
calculate_gini <- function(fi){
fi2 = fi^2
J = length(fi)
gini = 1 - sum(fi2)
gini_norm = gini / ((J-1)/J)
return(gini_norm)
}
gini <- calculate_gini(fi)
cat("Gini index = ", gini)
## Gini index = 0.9369358
Il prezzo mediano è stato suddiviso in classi ad intervalli approssimativamente regolari (20 mila dollari). Ciò che emerge subito dalla tavola di frequenze è che in più del 60% dei casi il prezzo mediano è stato tra 120 e 160 mila dollari. Inoltre sia la tavola di frequenze che il grafico a barre confermano un’asimmetria della distribuzione verso valori maggiori di 120 mila dollari. Infine l’indice di gini ha rivelato un’alta eterogeinà tra le classi estratte.
La probabilità che, presa una riga a caso del dataset, essa riporti la città “Beaumont”, o che riporti il mese di luglio, o che riporti dicembre 2012 può essere calcolata secondo l’accezione classica della probabilità. Nello specifico, la probabilità di specifici eventi di cui conosciamo le frequenze può essere calcolata come numero di casi favorevoli su numero di casi possibili. In questo caso dunque, la probabilità che un’osservazione sia stata registrata a Beaumont corrisponde a 1/4 = 0.250, poichè Beaumont è una città di 4 possibili città equamente distribuite. Analogamente, la probabilità che una registrazione sia avvenuta a luglio è data dalla ripetizione di luglio per 5 anni per 4 città (=20) sul totale delle possibili osservazioni: 20/240 = 0.833. Infine, la probabilità che la registrazione sia avvenuta nel dicembre 2012 è di 4/240 = 0.017, poichè dicembre 2012 compare una volta per ogni città (N=4).
data$prezzo_medio <- (volume * 1e6) / sales
efficacia_annunci <- listings / sales
data$efficacia_annunci <- (efficacia_annunci - min(efficacia_annunci)) / (max(efficacia_annunci) - min(efficacia_annunci))
Sono state create due nuove variabili. Il prezzo medio dell’immobile
per ogni mese considerato. La variabile è stata calcolata come il valore
totale delle vendite diviso per il numero delle vendite. Il valore
totale delle vendite, è stato riportato sulla scala dei milioni, per
avere il prezzo medio sulla scala delle centinaia di migliaia.
L’efficiacia degli annunci invece è stata calcolata come il rapporto tra
il numero di annunci attiv i n un determinato mese e il numero di
vendite. La misura è stata poi riscalata tra 0 e 1 per avere un indice
con dei limiti prestabiliti.
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
vars <- names(data)[4:8]
summary_table <- data %>%
group_by(city) %>%
summarise(across(
all_of(vars),
list(
media = ~mean(.x, na.rm = TRUE)
),
.names = "{.col}"
), .groups = "drop")
print("Mean for each variable grouped by city")
## [1] "Mean for each variable grouped by city"
print(summary_table)
## # A tibble: 4 × 6
## city sales volume median_price listings months_inventory
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Beaumont 177. 26.1 129988. 1679. 9.97
## 2 Bryan-College Station 206. 38.2 157488. 1458. 7.66
## 3 Tyler 270. 45.8 141442. 2905. 11.3
## 4 Wichita Falls 116. 13.9 101743. 910. 7.82
vars <- names(data)[4:8]
summary_table <- data %>%
group_by(city) %>%
summarise(across(
all_of(vars),
list(
sd = ~sd(.x, na.rm = TRUE)
),
.names = "{.col}"
), .groups = "drop")
print("Standard deviation for each variable grouped by city")
## [1] "Standard deviation for each variable grouped by city"
print(summary_table)
## # A tibble: 4 × 6
## city sales volume median_price listings months_inventory
## <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 Beaumont 41.5 6.97 10105. 91.1 1.65
## 2 Bryan-College Station 85.0 17.2 8852. 253. 2.25
## 3 Tyler 62.0 13.1 9337. 227. 1.89
## 4 Wichita Falls 22.2 3.24 11320. 73.8 0.781
vars <- names(data)[4:8]
summary_table <- data %>%
group_by(year) %>%
summarise(across(
all_of(vars),
list(
media = ~mean(.x, na.rm = TRUE)
),
.names = "{.col}"
), .groups = "drop")
print("Mean for each variable grouped by year")
## [1] "Mean for each variable grouped by year"
print(summary_table)
## # A tibble: 5 × 6
## year sales volume median_price listings months_inventory
## <int> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2010 169. 25.7 130192. 1826 9.97
## 2 2011 164. 25.2 127854. 1850. 10.9
## 3 2012 186. 29.3 130077. 1777. 9.88
## 4 2013 212. 35.2 135723. 1678. 8.15
## 5 2014 231. 39.8 139481. 1560. 7.06
vars <- names(data)[4:8]
summary_table <- data %>%
group_by(year) %>%
summarise(across(
all_of(vars),
list(
sd = ~sd(.x, na.rm = TRUE)
),
.names = "{.col}"
), .groups = "drop")
print("Standard deviation for each variable grouped by year")
## [1] "Standard deviation for each variable grouped by year"
print(summary_table)
## # A tibble: 5 × 6
## year sales volume median_price listings months_inventory
## <int> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 2010 60.5 10.8 21822. 785. 2.08
## 2 2011 63.9 12.2 21318. 780. 2.07
## 3 2012 70.9 14.5 21432. 738. 1.61
## 4 2013 84.0 17.9 21708. 744. 1.69
## 5 2014 95.5 21.2 25625. 707. 1.75
vars <- names(data)[4:8]
summary_table <- data %>%
group_by(month) %>%
summarise(across(
all_of(vars),
list(
media = ~mean(.x, na.rm = TRUE)
),
.names = "{.col}"
), .groups = "drop")
print("Mean for each variable grouped by month")
## [1] "Mean for each variable grouped by month"
print(summary_table)
## # A tibble: 12 × 6
## month sales volume median_price listings months_inventory
## <int> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 127. 19.0 124250 1647. 8.84
## 2 2 141. 21.7 130075 1692. 9.06
## 3 3 189. 29.4 127415 1757. 9.40
## 4 4 212. 33.3 131490 1826. 9.72
## 5 5 239. 39.7 134485 1824. 9.68
## 6 6 244. 41.3 137620 1833. 9.70
## 7 7 236. 39.1 134750 1821. 9.62
## 8 8 231. 38.0 136675 1786. 9.39
## 9 9 182. 29.6 134040 1749. 9.18
## 10 10 180. 29.1 133480 1710. 8.94
## 11 11 157. 24.8 134305 1653. 8.66
## 12 12 169. 27.1 133400 1558. 8.12
vars <- names(data)[4:8]
summary_table <- data %>%
group_by(month) %>%
summarise(across(
all_of(vars),
list(
sd = ~sd(.x, na.rm = TRUE)
),
.names = "{.col}"
), .groups = "drop")
print("Standard deviation for each variable grouped by month")
## [1] "Standard deviation for each variable grouped by month"
print(summary_table)
## # A tibble: 12 × 6
## month sales volume median_price listings months_inventory
## <int> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 43.4 8.37 25151. 705. 1.97
## 2 2 51.1 10.1 22823. 711. 1.98
## 3 3 59.2 12.0 23442. 727. 2.06
## 4 4 65.4 14.5 21458. 770. 2.24
## 5 5 83.1 19.0 18796. 790. 2.38
## 6 6 95.0 21.1 19231. 812. 2.41
## 7 7 96.3 21.4 21945. 827. 2.50
## 8 8 79.2 18.0 22488. 816. 2.45
## 9 9 72.5 15.2 24344. 803. 2.52
## 10 10 75.0 15.1 26358. 779. 2.44
## 11 11 55.5 11.2 24691. 741. 2.37
## 12 12 60.7 12.6 22810. 693. 2.27
Il maggior numero di vendite è avvenuto nella città di Tyler, che ha
registrato anche il maggior valore totale delle vendite nei cinque anni.
Tuttavia, Tyler non è la città con il prezzo mediano maggiore, primato
che spetta invece a Bryan-College Station. Nonostante queste siano le
prime due città sia per vendite, che per valore totale delle vendite,
che anche per prezzo mediano, esse presentano tendenze opposte per
quanto riguarda il numero di annunci e di mesi richiesti per evaderli
tutti. Mentre Tyler presenta i valori massi tra le 4 città,
Bryan-College Station presenta i valori minimi.
Questa tendenza invertita è presneta anche guardando l’informazione
media per anno, collassando le città. Infatti, mentre le vendite, il
valore totale di vendita, e il prezzo mediano sono aumentati negli anni,
il numero di annunci attivi e i mesi richiesti per evaderli sono
progressivamente diminuiti.
Infne, i mesi estivi sembrano essere quelli in cui il mercato
immobiliare presenta un’attività più intensa. Nello specifico, il mese
di Giugno è quello che registra il maggior numero di vendite e di valore
totale. Un fattore molto interessante è anche che il prezzo mediano di
vendita è influenzato dal mese, regitrando anche in questo caso il
massimo valore nel mese di Giugno.
library(ggplot2)
ggplot(data, aes(x = city, y = median_price)) +
geom_boxplot(fill = "lightblue", color = "darkblue") +
labs(
title = "Distribuzione del prezzo mediano per città",
x = "Città",
y = "Prezzo mediano"
) +
theme_minimal()
ggplot(data, aes(x = city, y = median_price, fill = factor(year))) +
geom_boxplot(position = position_dodge(width = 0.8)) +
labs(
title = "Prezzo mediano per città e anno",
x = "Città",
y = "Prezzo mediano",
fill = "Anno"
) +
theme_minimal()
Tutte le città hanno mostrato un aumento medio del prezzo mediano negli
anni. Tuttavia, mentre la variazione di prezzo a Beaumont e Wichita
Falls è stata lieve, le città di Tyler e Bryan-College Station hanno
mostrato un aumento del prezzo mediano esponenziale, Bryan-College
Station (dove gli immobili hanno un prezzo mediano sistematicamente più
alto di tutte le altre città) che ha mostrato un picco nel 2014 con un
prezzo mediano pari circa 170 mila dollari in media.
ggplot(data, aes(x = city, y = sales, fill = factor(month))) +
geom_boxplot(position = position_dodge(width = 0.8)) +
labs(
title = "Vendite per città e mese",
x = "Città",
y = "Vendite",
fill = "Mese"
) +
theme_minimal()
Come notato in precedenza, il numero di vendita sembra crescere durante
i mesi estivi. Tuttavia c’è da notare come questi picchi siano
particolarmente marcati a Bryan-College Station e Tyler. Può essere
interessante notare che le vendite a Bryan-College Station nei mesi di
Gennaio, Febbraio, e Marzo, sono sovrapponibili a quelle a Beaumont.
data$date <- as.Date(paste(data$year, data$month, "01", sep = "-"), format = "%Y-%m-%d")
ggplot(data, aes(x = date, y = sales, color = city)) +
geom_line(linewidth = 1) +
labs(
title = "Andamento delle vendite nel tempo",
x = "Data",
y = "Vendite",
color = "Città"
) +
theme_minimal()
Anche in questo caso si vedono i cicli annuali delle vendite con i picchi presenti durante i mesi estivi. Si vede anche come Wichita Falls non mostri alcuna tendenza all’aumento delle vendite, al contrario di Beaumon, seppur in misura minore rsipetto a Bryan-College Station e Tyler.
ggplot(data, aes(x = city, y = volume, fill = factor(year))) +
geom_boxplot(position = position_dodge(width = 0.8)) +
labs(
title = "Valore totale delle vendite per città e anno",
x = "Città",
y = "Valore totale delle vendite",
fill = "Anno"
) +
theme_minimal()
Anche considerando il valore totale delle vendite si può notare una
crescita esponenziale che caratterizza prevalentemente Bryan-College
Station e Tyler. Tuttavia, in questo caso, anche Beaumont mostra un
incremento che sembrerebbe esponenziale.
data$month_names <- factor(month, levels = 1:12, labels = month.name, ordered = TRUE)
monthly_totals <- data %>%
group_by(month_names, city) %>%
summarise(total_sales = sum(sales), .groups = "drop")
ggplot(monthly_totals, aes(x = month_names, y = total_sales, fill = city)) +
geom_bar(stat = "identity") +
labs(
title = "Totale vendite mensili per città",
x = "Mese",
y = "Vendite totali",
fill = "Città"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
monthly_percentages <- monthly_totals %>%
group_by(month_names) %>%
mutate(perc = total_sales / sum(total_sales)) %>%
ungroup()
ggplot(monthly_percentages, aes(x = month_names, y = perc, fill = city)) +
geom_bar(stat = "identity") +
scale_y_continuous(labels = scales::percent) +
labs(
title = "Distribuzione percentuale delle vendite per mese e città",
x = "Mese",
y = "Percentuale",
fill = "Città"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
city_year_month <- data %>%
group_by(city, year, month_names) %>%
summarise(total_sales = sum(sales), .groups = "drop")
city_year_month$city_year <- paste(city_year_month$city, city_year_month$year, sep = "_")
ggplot(city_year_month, aes(x = month_names, y = total_sales, fill = city)) +
geom_bar(stat = "identity") +
facet_grid(rows = vars(year)) +
labs(
title = "Distribuzione mensile delle vendite per città (divisa per anno)",
x = "Mese",
y = "Vendite totali",
fill = "Città"
) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
ggplot(data, aes(x = date, y = months_inventory, color = city)) +
geom_line(linewidth = 1) +
labs(
title = "Numero di annunci attivi nel tempo",
x = "Data",
y = "Annunci attivi",
color = "Città"
) +
theme_minimal()
Il tempo richiesto per vendere tutte le inserzioni mostra una solida tendenza a descrescere in utte le città, tranne a Wichita Falls dove il tempo richiesto era già sistematicamente più basse rispetto a quello delle altre città. Tuttavia, tra il 2013 e il 2014, a Bryan-College Station il tempo richiesto è arrivato ad essere addirittura il minore rispetto alle altre città. A Tyler e Beaumont i tempi erano i maggiori, fino alla fine del 2014 quando sono arrivati ad essere ai livelli di Wichita Falls. Anche in questo caso si possono osservare le oscillazioni all’interno dello stesso anno.
In generale il mercato immobiliare in Texas sembra essere molto
attivo e promettente. Questo aspetto viene evidenziato dalla presenza di
tendenze positive per quanto riguarda vendite, ricavi totali, e valore
mediano degli immobili. In questo, la città di Bryan-College Station
sembra essere quella più promettente, seguita da Tyler e Beaumont. Al
contrario, a Wichita Falls sembra che il mercato sia stagnante. Tutti
gli indici non mostrano incrementi degni di nota e sono sistematicamente
più bassi rispetto a quelli delle altre città.
Il mercato immobilirare si intensifica particolarmente nela tarda
primavera e nei mesi estivi. In questi periodi, il numero delle vendite
sale, ma anche il valore mediano degli immobili venduti.
Infine, nella maggior parte delle città, alla fine del 2014 sono
richiesti mediamente circa 7 mesi per vendere dalla pubblicazione
dell’annuncio. L’unica eccezione è Bryan-College Station, dove bastano
poco più di 3 mesi per vendere l’immobile. Inoltre, in utti i casi (tra
Wichita Falls) il tempo richiesto è in forte diminuzione.