Questo report analizza le tendenze del mercato immobiliare in Texas utilizzando dati storici sulle vendite di immobili.
# Installazione dei pacchetti necessari
required_packages <- c("dplyr", "moments", "ggplot2", "DescTools")
new_packages <- required_packages[!(required_packages %in% installed.packages()[,"Package"])]
if(length(new_packages)) install.packages(new_packages)
# Caricamento dei pacchetti
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
library(moments)
library(ggplot2)
library(DescTools)
# Imposta la directory di lavoro
setwd("/Users/feliziano/RWorkspace")
# Verifica della directory di lavoro corrente
getwd()
## [1] "/Users/feliziano/RWorkspace"
# Caricamento del dataset
data <- read.csv("realestate_texas.csv", sep = ",")
# Visualizzazione delle prime righe del dataset
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
# Calcolo delle statistiche descrittive
summary_stats <- data %>%
summarise(across(where(is.numeric), list(
mean = ~ mean(., na.rm = TRUE),
median = ~ median(., na.rm = TRUE),
sd = ~ sd(., na.rm = TRUE),
skewness = ~ skewness(., na.rm = TRUE),
kurtosis = ~ kurtosis(., na.rm = TRUE)
)))
library("glue")
# Visualizzazione delle statistiche descrittive
Di seguito sono riportate le statistiche descrittive calcolate:
| Metrica | Valore | Metrica | Valore |
|---|---|---|---|
| Year Mean | 2012 | Month Mean | 6.5 |
| Year Median | 2012 | Month Median | 6.5 |
| Year SD | 1.4171691 | Month SD | 3.4592669 |
| Year Skewness | 0 | Month Skewness | 0 |
| Year Kurtosis | 1.7 | Month Kurtosis | 1.7832168 |
| Sales Mean | 192.2916667 | Volume Mean | 31.0051875 |
| Sales Median | 175.5 | Volume Median | 27.0625 |
| Sales SD | 79.6511112 | Volume SD | 16.6514472 |
| Sales Skewness | 0.718104 | Volume Skewness | 0.884742 |
| Sales Kurtosis | 2.6868236 | Volume Kurtosis | 3.176987 |
| Median Price Mean | 1.3266542^{5} | Listings Mean | 1738.0208333 |
| Median Price Median | 1.345^{5} | Listings Median | 1618.5 |
| Median Price SD | 2.2662149^{4} | Listings SD | 752.7077561 |
| Median Price Skewness | -0.3645529 | Listings Skewness | 0.6494982 |
| Median Price Kurtosis | 2.3770382 | Listings Kurtosis | 2.20821 |
| Months Inventory Mean | 9.1925 | ||
| Months Inventory Median | 8.95 | ||
| Months Inventory SD | 2.3036686 | ||
| Months Inventory Skewness | 0.0409753 | ||
| Months Inventory Kurtosis | 2.8255525 |
sales,
volume, median_price)sales (numero totale di vendite):sales_mean): 192.2916667.sales_median): 175.5.sales_sd):
79.6511112.sales_skewness): 0.718104
(distribuzione leggermente asimmetrica a destra).sales_kurtosis): 2.6868236
(distribuzione leggermente più “appuntita” rispetto a una normale).Il numero di vendite varia significativamente, con una distribuzione leggermente asimmetrica verso destra, indicando la presenza di alcuni periodi o città con un numero di vendite più alto.
volume (valore totale delle vendite in milioni di
dollari):volume_mean): 31.0051875.volume_median): 27.0625.volume_sd):
16.6514472.volume_skewness): 0.884742
(distribuzione asimmetrica a destra).volume_kurtosis): 3.176987
(distribuzione più “appuntita” rispetto a una normale).median_price (prezzo mediano degli immobili
venduti):median_price_mean):
1.3266542^{5} dollari.median_price_median):
1.345^{5} dollari.median_price_sd):
2.2662149^{4} dollari.median_price_skewness):
-0.3645529 (distribuzione leggermente asimmetrica a sinistra).median_price_kurtosis):
2.3770382 (distribuzione leggermente più “appuntita” rispetto a una
normale).In questa sezione, identifichiamo la variabile con la maggiore variabilità (deviazione standard più alta) e quella con la distribuzione più asimmetrica (skewness più alto o più basso).
# Caricamento delle librerie necessarie
library(dplyr)
library(moments)
# Calcolo dell'indice di skewness per tutte le variabili numeriche
skewness_values <- data %>%
summarise(across(where(is.numeric), skewness, na.rm = TRUE))
## Warning: There was 1 warning in `summarise()`.
## ℹ In argument: `across(where(is.numeric), skewness, na.rm = TRUE)`.
## 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))
# Visualizzazione degli indici di skewness
print("Indici di skewness per le variabili numeriche:")
## [1] "Indici di skewness per le variabili numeriche:"
print(skewness_values)
## year month sales volume median_price listings months_inventory
## 1 0 0 0.718104 0.884742 -0.3645529 0.6494982 0.04097527
# Identificazione della variabile con la maggiore asimmetria
max_skewness_var <- names(which.max(abs(skewness_values)))
max_skewness_value <- skewness_values[[max_skewness_var]]
# Stampa del risultato
cat("La variabile con la maggiore asimmetria è:", max_skewness_var, "\n")
## La variabile con la maggiore asimmetria è: volume
cat("Il valore di skewness è:", max_skewness_value, "\n")
## Il valore di skewness è: 0.884742
# Confronto delle deviazioni standard
sd_comparison <- data %>%
summarise(across(where(is.numeric), sd, na.rm = TRUE))
print("Deviazioni standard:")
## [1] "Deviazioni standard:"
print(sd_comparison)
## year month sales volume median_price listings months_inventory
## 1 1.417169 3.459267 79.65111 16.65145 22662.15 752.7078 2.303669
# Confronto degli indici di skewness
skewness_comparison <- data %>%
summarise(across(where(is.numeric), skewness, na.rm = TRUE))
print("Indici di skewness:")
## [1] "Indici di skewness:"
print(skewness_comparison)
## year month sales volume median_price listings months_inventory
## 1 0 0 0.718104 0.884742 -0.3645529 0.6494982 0.04097527
volume, indicando che
il valore totale delle vendite varia significativamente.volume, suggerendo una
distribuzione asimmetrica a destra, con alcuni periodi o città che
contribuiscono in modo significativo al volume totale.# Distribuzione di frequenza per la variabile 'city'
city_freq <- table(data$city)
print(city_freq)
##
## Beaumont Bryan-College Station Tyler
## 60 60 60
## Wichita Falls
## 60
# Distribuzione di frequenza per la variabile 'year'
year_freq <- table(data$year)
print(year_freq)
##
## 2010 2011 2012 2013 2014
## 48 48 48 48 48
# Distribuzione di frequenza per la variabile 'month'
month_freq <- table(data$month)
print(month_freq)
##
## 1 2 3 4 5 6 7 8 9 10 11 12
## 20 20 20 20 20 20 20 20 20 20 20 20
Le variabili categoriche city, year e month hanno una distribuzione equa(concentrazione 0). Ciò è positivo poichè evita che la differenza nel numero di osservazioni possa condizionare le varie analisi.
breaks <- seq(
min(data$median_price, na.rm = TRUE),
max(data$median_price, na.rm = TRUE),
length.out = 6
)
data <- data %>%
mutate(median_price_class = cut(median_price, breaks = breaks, include.lowest = TRUE))
# Calcolo della distribuzione di frequenza per le classi
price_class_freq <- table(data$median_price_class)
# Stampa della distribuzione di frequenza
print("Distribuzione di frequenza delle classi di prezzo mediano:")
## [1] "Distribuzione di frequenza delle classi di prezzo mediano:"
# Crea la tabella di frequenza
freq_table <- table(data$median_price_class)
# Formatta i numeri
freq_table_formatted <- format(freq_table, scientific = FALSE, big.mark = ",")
# Stampa la tabella formattata
print(freq_table_formatted)
##
## [7.38e+04,9.5e+04] (9.5e+04,1.16e+05] (1.16e+05,1.38e+05] (1.38e+05,1.59e+05]
## "18" "40" "73" "84"
## (1.59e+05,1.8e+05]
## "25"
library(ggplot2)
library(ggplot2)
library(scales)
# Creazione del grafico
plot2 <- ggplot(data, aes(x = median_price_class)) +
geom_bar(fill = "darkorange", color = "black") +
labs(
title = "Distribuzione delle Classi di Prezzo Mediano",
x = "Classe di Prezzo",
y = "Frequenza"
) +
scale_x_discrete(labels = function(x) {
# Formattazione dei limiti delle classi per renderli leggibili
gsub("\\(|\\)|\\[|\\]", "", x) %>%
gsub(",", " - ", .) %>%
strsplit(split = " - ") %>%
lapply(function(y) paste0(format(as.numeric(y), big.mark = ".", decimal.mark = ","), collapse = " - ")) %>%
unlist()
}) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1)) # Rotazione delle etichette per leggibilità
# Visualizzazione del grafico
print(plot2)
# Find the most and least frequent classes
most_frequent_class <- names(which.max(table(data$median_price_class)))
least_frequent_class <- names(which.min(table(data$median_price_class)))
### Distribuzione delle classi di prezzo mediano
Il grafico mostra la suddivisione dei prezzi mediani in 5 intervalli equidistanti, ciascuno rappresentante un range di prezzo specifico. Di seguito, un’analisi dettagliata:
# Distribuzione di frequenza per le classi di 'median_price'
freq_table <- table(data$median_price_class)
print(freq_table)
##
## [7.38e+04,9.5e+04] (9.5e+04,1.16e+05] (1.16e+05,1.38e+05] (1.38e+05,1.59e+05]
## 18 40 73 84
## (1.59e+05,1.8e+05]
## 25
# Calcolo dell'indice di Gini
gini_index <- Gini(freq_table)
cat("L'indice di Gini per le classi di prezzo mediano è:", gini_index, "\n")
## L'indice di Gini per le classi di prezzo mediano è: 0.375
# Funzione per calcolare l'indice di Gini normalizzato
gini.index <- function(x) {
ni <- table(x) # Frequenze assolute
fi <- ni / length(x) # Frequenze relative
fi2 <- fi^2 # Quadrato delle frequenze relative
J <- length(table(x)) # Numero di modalità
gini <- 1 - sum(fi2) # Calcolo dell'indice di Gini
print(gini)
gini.normalizzato <- gini / ((J - 1) / J) # Normalizzazione
return(gini.normalizzato)
}
# Applicazione alla variabile median_price (utilizzando le classi create)
gini_median_price <- gini.index(data$median_price_class)
## [1] 0.7407292
# Stampa del risultato
print(paste("Indice di Gini normalizzato per 'median_price':", round(gini_median_price, 2)))
## [1] "Indice di Gini normalizzato per 'median_price': 0.93"
# Probabilità che una riga riporti la città "Beaumont"
prob_beaumont <- mean(data$city == "Beaumont")
# Probabilità che una riga riporti il mese di Luglio
prob_july <- mean(data$month == 7)
# Probabilità che una riga riporti il mese di dicembre 2012
prob_dec_2012 <- mean(data$month == 12 & data$year == 2012)
cat("Probabilità di 'Beaumont':", prob_beaumont, "\n")
## Probabilità di 'Beaumont': 0.25
cat("Probabilità di 'Luglio':", prob_july, "\n")
## Probabilità di 'Luglio': 0.08333333
cat("Probabilità di 'Dicembre 2012':", prob_dec_2012, "\n")
## Probabilità di 'Dicembre 2012': 0.01666667
Evento Probabilità Mese: Luglio 0.08
# Creazione delle nuove variabili
data <- data %>%
mutate(
avg_price = volume / sales, # Prezzo medio
listing_effectiveness = sales / listings # Efficacia degli annunci
)
# Visualizzazione delle prime righe con le nuove variabili
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
## median_price_class avg_price listing_effectiveness
## 1 (1.59e+05,1.8e+05] 0.1706265 0.05414220
## 2 (1.38e+05,1.59e+05] 0.1637963 0.06809584
## 3 (1.16e+05,1.38e+05] 0.1576978 0.10775607
## 4 (1.16e+05,1.38e+05] 0.1340950 0.11709602
## 5 (1.16e+05,1.38e+05] 0.1427376 0.11405985
## 6 (1.16e+05,1.38e+05] 0.1440159 0.10482529
plot_efficacia <- ggplot(data, aes(x = listing_effectiveness)) +
geom_histogram(
binwidth = 0.03, # Scelta ottimale per rappresentare la distribuzione
fill = "red",
color = "black"
) +
labs(
title = "Distribuzione dell'Efficacia degli Annunci di Vendita",
x = "Efficacia degli Annunci (Vendite per Annuncio)",
y = "Frequenza"
) +
theme_minimal()
# Visualizzazione del grafico
print(plot_efficacia)
## Analisi per anno
# Analisi per Anno
summary_year <- data %>%
group_by(year) %>%
summarise(
mean_sales = round(mean(sales, na.rm = TRUE), 2),
sd_sales = round(sd(sales, na.rm = TRUE), 2),
mean_median_price = round(mean(median_price, na.rm = TRUE), 2),
sd_median_price = round(sd(median_price, na.rm = TRUE), 2),
mean_efficacia_annunci = round(mean(listing_effectiveness, na.rm = TRUE), 2),
sd_efficacia_annunci = round(sd(listing_effectiveness, na.rm = TRUE), 2)
)
print("Summary per anno:" )
## [1] "Summary per anno:"
summary(summary_year)
## year mean_sales sd_sales mean_median_price
## Min. :2010 Min. :164.1 Min. :60.54 Min. :127854
## 1st Qu.:2011 1st Qu.:168.7 1st Qu.:63.87 1st Qu.:130077
## Median :2012 Median :186.2 Median :70.91 Median :130192
## Mean :2012 Mean :192.3 Mean :74.97 Mean :132665
## 3rd Qu.:2013 3rd Qu.:211.9 3rd Qu.:84.00 3rd Qu.:135723
## Max. :2014 Max. :230.6 Max. :95.51 Max. :139481
## sd_median_price mean_efficacia_annunci sd_efficacia_annunci
## Min. :21318 Min. :0.090 Min. :0.020
## 1st Qu.:21432 1st Qu.:0.100 1st Qu.:0.030
## Median :21708 Median :0.110 Median :0.030
## Mean :22381 Mean :0.118 Mean :0.036
## 3rd Qu.:21822 3rd Qu.:0.130 3rd Qu.:0.040
## Max. :25625 Max. :0.160 Max. :0.060
print(summary_year)
## # A tibble: 5 × 7
## year mean_sales sd_sales mean_median_price sd_median_price
## <int> <dbl> <dbl> <dbl> <dbl>
## 1 2010 169. 60.5 130192. 21822.
## 2 2011 164. 63.9 127854. 21318.
## 3 2012 186. 70.9 130077. 21432.
## 4 2013 212. 84 135723. 21708.
## 5 2014 231. 95.5 139481. 25625.
## # ℹ 2 more variables: mean_efficacia_annunci <dbl>, sd_efficacia_annunci <dbl>
Vendite medie: Si osserva una crescita costante del numero medio di vendite, che passa da 169.0 nel 2010 a 231.0 nel 2014. Questo trend indica un’espansione progressiva del mercato immobiliare.
Prezzo mediano: Anche il prezzo mediano degli immobili mostra un andamento positivo, aumentando da $130,192 nel 2010 a $139,481 nel 2014. Questo suggerisce un incremento generale dei valori immobiliari nel periodo considerato.
Efficacia degli annunci: L’efficacia degli annunci di vendita migliora gradualmente, raggiungendo il valore più alto nel 2014 (0.15). Questo miglioramento riflette probabilmente l’adozione di strategie di vendita più efficaci nel corso degli anni.
summary_month <- data %>%
group_by(month) %>%
summarise(
mean_sales = round(mean(sales, na.rm = TRUE), 2),
sd_sales = round(sd(sales, na.rm = TRUE), 2),
mean_median_price = round(mean(median_price, na.rm = TRUE), 2),
sd_median_price = round(sd(median_price, na.rm = TRUE), 2),
mean_listing_effectiveness = round(mean(listing_effectiveness, na.rm = TRUE), 2),
sd_listing_effectiveness = round(sd(listing_effectiveness, na.rm = TRUE), 2)
)
# Grafico: Efficacia degli Annunci per Mese
plot_month <- ggplot(summary_month, aes(x = as.factor(month), y = mean_listing_effectiveness)) +
geom_bar(stat = "identity", fill = "lightblue", color = "black") +
labs(
title = "Efficacia degli Annunci per Mese",
x = "Mese",
y = "Media Efficacia"
) +
theme_minimal()
print(plot_month)
# Calcolo delle statistiche per città
city_stats <- data %>%
group_by(city) %>%
summarise(
mean_sales = mean(sales, na.rm = TRUE),
sd_sales = sd(sales, na.rm = TRUE)
)
# Visualizzazione delle statistiche per città
print(city_stats)
## # A tibble: 4 × 3
## city mean_sales sd_sales
## <chr> <dbl> <dbl>
## 1 Beaumont 177. 41.5
## 2 Bryan-College Station 206. 85.0
## 3 Tyler 270. 62.0
## 4 Wichita Falls 116. 22.2
# Grafico a barre delle vendite medie per città
ggplot(city_stats, aes(x = reorder(city, -mean_sales), y = mean_sales, fill = city)) +
geom_bar(stat = "identity") +
labs(title = "Vendite medie per città", x = "Città", y = "Vendite medie") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
ggplot(data, aes(x = city, y = median_price, fill = city)) +
geom_boxplot() +
labs(title = "Distribuzione del Prezzo Mediano per Città", x = "Città", y = "Prezzo Mediano") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
## Andamento storico delle vendite
# Creazione della variabile data
data <- data %>%
mutate(date = as.Date(paste(year, month, "01", sep = "-"), format = "%Y-%m-%d"))
ggplot(data, aes(x = date, y = sales, color = city)) +
geom_line() +
labs(title = "Andamento Storico delle Vendite", x = "Data", y = "Vendite") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
## Media delle vendite per citta e mese
mean_sales_city_month <- data %>%
group_by(city, month) %>%
summarize(media_sales = mean(sales, na.rm = TRUE))
## `summarise()` has grouped output by 'city'. You can override using the
## `.groups` argument.
ggplot(mean_sales_city_month, aes(x = factor(month), y = media_sales, fill = city)) +
geom_bar(stat = "identity", position = "dodge") +
labs(title = "Media delle Vendite per Città e Mese", x = "Mese", y = "Media Vendite", fill = "Città") +
theme_minimal()
L’analisi del mercato immobiliare del Texas (2010-2014) ha rivelato trend chiave e differenze geografiche, basandosi su un dataset bilanciato di 240 osservazioni tra Beaumont, Bryan-College Station, Tyler e Wichita Falls. Ecco i punti principali emersi:
Il mercato immobiliare texano è in crescita, con differenze geografiche significative e una chiara stagionalità. Le città più grandi (Tyler e Bryan-College Station) dominano per volumi di vendita, mentre quelle più piccole (Wichita Falls) mostrano un’efficienza maggiore. La stagionalità estiva rappresenta un’opportunità strategica per le agenzie immobiliari, suggerendo la necessità di campagne mirate in questo periodo.
Questa analisi offre spunti pratici per ottimizzare le strategie di vendita e marketing, migliorando la comprensione delle dinamiche del mercato immobiliare texano.