#Carico il dataset e lo visualizzo

# Installare i pacchetti se non sono già installati
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
library(ggplot2)
library("tidyr")
dataset <- read.csv("C:\\Users\\lory2\\Downloads\\realestate_texas.csv", header = TRUE, stringsAsFactors = FALSE)
head(dataset)
##       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

City: variabile categorica nominale, può essere usata per raggruppare i dati sulle diverse città e fare confronti utilizzando i box plot(ad esempio)

Year: variabile categorica ordinata, utile per analizzare l’andamento di una variabile in funzione del tempo

Month: variabile categorica ordinata, anch’essa utile per analizzare l’andamento nel tempo (in questo caso riferendoci ad un anno specifico)

Sales: variabile quantitativa discreta, è possibile calcolare gli indici di posizione

Volume: variabile quantitativa continua, è possibile calcolare gli indici di posizione anche in questo caso

Median_price: variabile quantitativa continua

Listings: variabile quantitativa discreta, si potrebbe analizzare il numero di annunci attivi tispetto a vendite e volume per capire se esiste una correlazione tra loro

Months_inventory: variabile quantitativa continua, utilizzabile per capire l’andamento del mercato nel tempo

#Calcolo indici di posizione e distribuzione di frequenza

# Libreria necessaria per calcolare asimmetria e curtosi
if (!require(e1071)) install.packages("e1071")
## Caricamento del pacchetto richiesto: e1071
library(e1071)

# Funzione per calcolare indici di posizione, variabilità e forma
calcola_statistiche <- function(dataset) {
  variabili <- names(dataset)
  
  for (variabile in variabili) {
    valori <- dataset[[variabile]]
    
    # Verifica sul tipo di variabile (numerica?)
    if (is.numeric(valori)) {
      cat("Variabile:", variabile, "\n")
      cat("Media:", mean(valori, na.rm = TRUE), "\n")
      cat("Mediana:", median(valori, na.rm = TRUE), "\n")
      cat("Deviazione standard:", sd(valori, na.rm = TRUE), "\n")
      cat("Varianza:", var(valori, na.rm = TRUE), "\n")
      cat("Asimmetria:", skewness(valori, na.rm = TRUE), "\n")
      cat("Curtosi:", kurtosis(valori, na.rm = TRUE), "\n")
      cat("\n")
    } else {
      # Distribuzione di frequenza per variabili non numeriche
      cat("Variabile categoriale/ordinale:", variabile, "\n")
      print(table(valori))
      cat("\n")
    }
  }
}

# Convertiamo year e month in variabili fattoriali così da trattarle correttamente come variabili categoriche
dataset$year <- as.factor(dataset$year)
dataset$month <- factor(dataset$month, levels = 1:12, labels = c("Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"))

# Distribuzione di frequenza per year e month
cat("Distribuzione per year:\n")
## Distribuzione per year:
print(table(dataset$year))
## 
## 2010 2011 2012 2013 2014 
##   48   48   48   48   48
cat("\nDistribuzione per month:\n")
## 
## Distribuzione per month:
print(table(dataset$month))
## 
## Gen Feb Mar Apr Mag Giu Lug Ago Set Ott Nov Dic 
##  20  20  20  20  20  20  20  20  20  20  20  20
calcola_statistiche(dataset)
## Variabile categoriale/ordinale: city 
## valori
##              Beaumont Bryan-College Station                 Tyler 
##                    60                    60                    60 
##         Wichita Falls 
##                    60 
## 
## Variabile categoriale/ordinale: year 
## valori
## 2010 2011 2012 2013 2014 
##   48   48   48   48   48 
## 
## Variabile categoriale/ordinale: month 
## valori
## Gen Feb Mar Apr Mag Giu Lug Ago Set Ott Nov Dic 
##  20  20  20  20  20  20  20  20  20  20  20  20 
## 
## Variabile: sales 
## Media: 192.2917 
## Mediana: 175.5 
## Deviazione standard: 79.65111 
## Varianza: 6344.3 
## Asimmetria: 0.7136206 
## Curtosi: -0.33552 
## 
## Variabile: volume 
## Media: 31.00519 
## Mediana: 27.0625 
## Deviazione standard: 16.65145 
## Varianza: 277.2707 
## Asimmetria: 0.8792182 
## Curtosi: 0.1505673 
## 
## Variabile: median_price 
## Media: 132665.4 
## Mediana: 134500 
## Deviazione standard: 22662.15 
## Varianza: 513572983 
## Asimmetria: -0.3622768 
## Curtosi: -0.6427292 
## 
## Variabile: listings 
## Media: 1738.021 
## Mediana: 1618.5 
## Deviazione standard: 752.7078 
## Varianza: 566569 
## Asimmetria: 0.6454431 
## Curtosi: -0.8101534 
## 
## Variabile: months_inventory 
## Media: 9.1925 
## Mediana: 8.95 
## Deviazione standard: 2.303669 
## Varianza: 5.306889 
## Asimmetria: 0.04071944 
## Curtosi: -0.1979448

La distribuzione delle variabili categoriche risulta uniforme in quanto il numero di osservazioni per le diverse città nei mesi e negli anni è la stessa. Sales e volume riportano una asimmetria positiva, questo implica che ci sono pochi dati con valori molto piu alti della media che influenzano la curva Sales ha una distribuzione relativamente piatta in quanto ha una curtosi negativa, così come median_price, listings e months_inventory Months_inventory, listings e median_price riportano valori di media e mediana vicini tra loro, suggerendo una distribuzinoe piuttosto equilibrata Sales e volume hanno dei valori di media più alti rispetto alla mediana, suggerendo che i valori estremi influenzano i risultati

#Confronto tra variabili di diversa natura

# Funzione per calcolare il Coefficiente di Variazione (CV)
calcola_cv <- function(x) {
  media <- mean(x, na.rm = TRUE)
  deviazione_standard <- sd(x, na.rm = TRUE)
  cv <- (deviazione_standard / media) * 100
  return(cv)
}

# Calcolo del CV per le variabili numeriche
cv_sales <- calcola_cv(dataset$sales)
cv_volume <- calcola_cv(dataset$volume)
cv_median_price <- calcola_cv(dataset$median_price)
cv_listings <- calcola_cv(dataset$listings)
cv_months_inventory <- calcola_cv(dataset$months_inventory)

# Creazione di un data frame per visualizzare i risultati
cv_results <- data.frame(
  Variabile = c("Sales", "Volume", "Median Price", "Listings", "Months Inventory"),
  Coefficiente_Variazione = c(cv_sales, cv_volume, cv_median_price, cv_listings, cv_months_inventory)
)

print(cv_results)
##          Variabile Coefficiente_Variazione
## 1            Sales                41.42203
## 2           Volume                53.70536
## 3     Median Price                17.08218
## 4         Listings                43.30833
## 5 Months Inventory                25.06031

#Calcolo indice di Gini # Suddivisione della variabile “sales” in classi

breaks <- seq(0, max(dataset$sales, na.rm = TRUE), by = 50) 
dataset$sales_class <- cut(dataset$sales, breaks = breaks, right = FALSE)

# Creare una distribuzione di frequenze
frequenze <- table(dataset$sales_class)

# Visualizzare la distribuzione di frequenze
print(frequenze)
## 
##    [0,50)  [50,100) [100,150) [150,200) [200,250) [250,300) [300,350) [350,400) 
##         0        20        69        58        33        34        14         9
# Creare un grafico a barre
barplot(frequenze, 
        main = "Distribuzione delle vendite",
        xlab = "Classi di Vendite",
        ylab = "Frequenza",
        col = "lightblue", 
        border = "black")

# Funzione per calcolare l'indice di Gini
calcola_gini <- function(x) {
  ni=table(x)
  fi=ni/length(x)
  fi2=fi^2
  J=length(table(x))
  
  gini = 1-sum(fi2)
  gini.normalizzato=gini/((J-1)/J)
  return(gini.normalizzato)
}

# Calcolare l'indice di Gini per la variabile sales
gini_sales <- calcola_gini(dataset$sales_class)
cat("\nIndice di Gini per le vendite:", gini_sales)
## 
## Indice di Gini per le vendite: 0.9236706

Il valore dell’indice di gini suggerisce che c’è una forte concentrazione di vendite in pochi valori. Questo potrebbe accadere se una o più città hanno avuto vendite molto elevate rispetto alle altre. #Calcolo probabilità ed efficacia annunci

# Probabilità Beaumont
casi_beaumont <- sum(dataset$city == "Beaumont")
totale_righe <- nrow(dataset)
prob_beaumont <- casi_beaumont / totale_righe
cat("Probabilità che la città sia Beaumont:", prob_beaumont)
## Probabilità che la città sia Beaumont: 0.25
# Probabilità Luglio
casi_luglio <- sum(dataset$month == "Lug")
prob_luglio <- casi_luglio / totale_righe
cat("Probabilità che il mese sia Luglio:", prob_luglio)
## Probabilità che il mese sia Luglio: 0.08333333
# Probabilità mese Dicembre e anno 2012
casi_dicembre_2012 <- sum(dataset$month == "Dic" & dataset$year == 2012)
prob_dicembre_2012 <- casi_dicembre_2012 / totale_righe
cat("Probabilità che il mese sia Dicembre 2012:", prob_dicembre_2012)
## Probabilità che il mese sia Dicembre 2012: 0.01666667
# Calcolo prezzo medio immobili in dollari
dataset$prezzo_medio <- dataset$volume * 1e6 / dataset$sales
# Calcolo efficacia annunci
dataset$efficacia_annunci <- dataset$sales / dataset$listings

head(dataset)
##       city year month sales volume median_price listings months_inventory
## 1 Beaumont 2010   Gen    83 14.162       163800     1533              9.5
## 2 Beaumont 2010   Feb   108 17.690       138200     1586             10.0
## 3 Beaumont 2010   Mar   182 28.701       122400     1689             10.6
## 4 Beaumont 2010   Apr   200 26.819       123200     1708             10.6
## 5 Beaumont 2010   Mag   202 28.833       123100     1771             10.9
## 6 Beaumont 2010   Giu   189 27.219       122800     1803             11.1
##   sales_class prezzo_medio efficacia_annunci
## 1    [50,100)     170626.5        0.05414220
## 2   [100,150)     163796.3        0.06809584
## 3   [150,200)     157697.8        0.10775607
## 4   [200,250)     134095.0        0.11709602
## 5   [200,250)     142737.6        0.11405985
## 6   [150,200)     144015.9        0.10482529

L’efficacia degli annunci può comprendere valori tra 0 e 1, in tal caso misuriamo semplicemente l’efficacia, valori molto vicino allo zero possono significare un periodo non ottimale per la vendita oltre che annunci poco efficaci, un valore superiore ad 1 indica che ci sono state più vendite di quelle proposte, ciò può significare una forte domanda di mercato.

#Grafici ## Raggruppamento dei dati

# Raggruppamento dati per città, anno e mese, e calcolo media e deviazione standard
statistiche_condizionate <- dataset %>%
  group_by(city, year, month) %>%
  summarise(
    media_sales = mean(sales, na.rm = TRUE),
    sd_sales = sd(sales, na.rm = TRUE),
    media_volume = mean(volume, na.rm = TRUE),
    sd_volume = sd(volume, na.rm = TRUE)
  ) %>%
  mutate(
    sd_sales = replace_na(sd_sales, 0),
    sd_volume = replace_na(sd_volume, 0)
  )
## `summarise()` has grouped output by 'city', 'year'. You can override using the
## `.groups` argument.
head(statistiche_condizionate)
## # A tibble: 6 × 7
## # Groups:   city, year [1]
##   city     year  month media_sales sd_sales media_volume sd_volume
##   <chr>    <fct> <fct>       <dbl>    <dbl>        <dbl>     <dbl>
## 1 Beaumont 2010  Gen            83        0         14.2         0
## 2 Beaumont 2010  Feb           108        0         17.7         0
## 3 Beaumont 2010  Mar           182        0         28.7         0
## 4 Beaumont 2010  Apr           200        0         26.8         0
## 5 Beaumont 2010  Mag           202        0         28.8         0
## 6 Beaumont 2010  Giu           189        0         27.2         0

Boxplot vendite per città

#Boxplot delle vendite per città
ggplot(dataset, aes(x = city, y = sales)) +
  geom_boxplot(fill = "lightblue") +
  labs(title = "Distribuzione delle vendite per città", x = "Città", y = "Vendite") +
  theme_minimal()

Il boxplot mostra le due città con il maggior numero di vendite che sono Bryan e Tyler, possiamo notare come la media di vendite su Bryan sia molto inferiore rispetto a quella di Tyler. Inoltre, il range di valori IQR per bryan risulta essere piu ampio rispetto a quello di Tyler. Un ulteriore confronto di interesse è quello tra Bryan e Beaumont, in quanto nonostante l’IQR sia notevolmente differente, la media risulta essere piuttosto simile. Da ciò si può dedurre che, basandoci solo sul numero di vendite, che Tyler è la città migliore per n. di vendite, mentre Bryan e Beaumont sono pressoché simili a meno di una forte variabilità di Bryan.

Boxplot della distribuzione del prezzo mediano tra le città

# Boxplot della distribuzione del prezzo mediano tra le città
ggplot(dataset, aes(x = city, y = median_price)) +
  geom_boxplot(fill = "lightgreen", color = "darkgreen") +
  labs(title = "Distribuzione del prezzo mediano per città", 
       x = "Città", 
       y = "Prezzo Mediano (in $)") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Il boxplot mette in evidenza Bryan come città con i prezzi piu alti, a seguire Tyler, Beaumont e Wichita. Ciò può dare una spiegazione al boxplot precedente in cui si visualizzava solo il numero di vendite, in quanto Bryan ha costi molto alti ma una media di vendita simile a Beaumont, che ha un prezzo molto piu basso. Questo implica un possibile fatturato maggiore per Bryan che, probabilmente, risulta in ricavi maggiori. Tyler potrebbe essere comunque la città migliore anche in termini di fatturato in quanto ha dei prezzi minori rispetto a Bryan, ma non eccessivamente.

Boxplot della distribuzione del prezzo mediano tra le città

# Aggrega i dati per mese, città e anno
aggregated_data <- dataset %>%
  group_by(month, city, year) %>%
  summarise(total_sales = sum(sales), .groups = 'drop')

# Grafico a barre del totale delle vendite per mese e città
ggplot(aggregated_data, aes(x = month, y = total_sales, fill = city)) +
  geom_bar(stat = "identity", position = "dodge") +
  labs(title = "Totale delle vendite per mese e città", 
       x = "Mese", 
       y = "Totale Vendite") +
  scale_fill_brewer(palette = "Set3") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Il grafico permette di visualizzare l’effetto della stagionalità sulle diverse città, Tyler e Bryan risultano essere piuttosto influenzate in quanto si ha una crescita da Maggio ad Agosto, meno marcata per Tyler in quanto rimane piuttosto stabile da Settembre a Dicembre. Bryan invece subisce l’effetto in modo piu marcato in quanto il numero totale di vendite risulta essere molto basso da Settembre a Febbraio, per poi avere una crescita da Marzo raggiungendo il picco a Luglio. Le altre due città non sembrano subire in modo influente l’effetto stagionale.

Line chart per l’andamento delle vendite nel tempo per anno e mese

# Line chart per l'andamento delle vendite nel tempo per anno e mese
ggplot(dataset, aes(x = month, y = sales, group = year, color = as.factor(year))) +
  geom_line() +
  labs(title = "Andamento delle vendite per mese e anno", 
       x = "Mese", 
       y = "Vendite") +
  facet_wrap(~ city) +
  theme_minimal() +
  scale_color_brewer(palette = "Set1") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Definisci una palette graduale di colori per gli anni
colors_gradient <- colorRampPalette(c("lightblue", "blue", "darkblue"))(length(unique(dataset$year)))
# Line chart con colori graduali per gli anni
ggplot(dataset, aes(x = month, y = sales, group = year, color = year)) +
  geom_line() +
  labs(title = "Andamento delle vendite per mese e anno", 
       x = "Mese", 
       y = "Vendite") +
  facet_wrap(~ city) +  
  theme_minimal() +
  scale_color_manual(values = colors_gradient, name = "Anno") +  # Usa la palette di colori personalizzata
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

i Line chart mettono in evidenza l’andamento nei vari mesi su diversi anni per ogni città. Bryan ha mantenuto circa lo stesso andamento, con una crescita del numero di vendite dal 2010 al 2014(che inizia ad essere significativa dal 2012). Beaumont ha un andamento mensile piuttosto simile di anno in anno, anche qui si osserva un aumento delle vendite dal 2010 al 2014. Considerazioni simili valgono anche per Tyler, che aumenta il numero di vendite. Wichita invece risulta avere all’incirca lo stesso numero di vendite, l’aumento è molto inferiore rispetto a quello degli altri grafici. Si può inoltre osservare come la stagionalità incida molto su Bryan, un pò meno per Tyler ed è quasi ininfluente per le restanti.

Boxplot per confrontare la distribuzione del volume delle vendite tra città e anni

# Boxplot per confrontare la distribuzione del volume delle vendite tra città e anni
ggplot(dataset, aes(x = city, y = volume, fill = as.factor(year))) +
  geom_boxplot() +
  labs(title = "Distribuzione del valore totale delle vendite tra città e anni", 
       x = "Città", 
       y = "Valore totale delle vendite (in milioni $)") +
  scale_fill_brewer(palette = "Paired", name = "Anno") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Dal boxplot emerge la rapida crescita del valore totale di vendite per le città di Bryan e Tyler, è possibile anche notare come l’IQR di bryan risulti sempre piu ampio rispetto a quello di Tyler, indicando quindi una maggiore variabilità. Nonostante gli IQR abbiano dei range “in comune”, la media di Tyler è sempre piu alta.

Grafico a barre sovrapposte con variabile Year integrata

# Grafico a barre sovrapposte con variabile Year integrata
ggplot(aggregated_data, aes(x = month, y = total_sales, fill = city)) +
  geom_col(position = "stack") +  
  labs(title = "Totale delle vendite per mese, città e anno", 
       x = "Mese", 
       y = "Totale Vendite") +
  scale_fill_brewer(palette = "Set3", name = "Città") +
  facet_wrap(~ year) +  
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Il grafico permette di visualizzare meglio il contributo di ogni città sul totale delle vendite, per ogni mese ed anno specifico. Si nota ancora una volta come i contributi delle città Bryan e Tyler siano maggiori rispetto agli altri.

Grafico a barre normalizzato per mostrare la proporzione delle vendite nei mesi per città

# Grafico a barre normalizzato per mostrare la proporzione delle vendite nei mesi per città
ggplot(aggregated_data, aes(x = month, y = total_sales, fill = city)) +
  geom_bar(stat = "identity", position = "fill") +  # Normalizzazione delle barre
  labs(title = "Proporzione delle vendite per mese e città (normalizzato)", 
       x = "Mese", 
       y = "Proporzione Vendite") +
  scale_fill_brewer(palette = "Set3", name = "Città") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

Per visualizzare il contributo in percentuale è utile normalizzare il grafico a barre sovrapposte.