#Load libraries
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(summarytools)
library(readr)
library(moments)

# Dataset Import

RETexas_ds <- read_csv("Real Estate Texas.csv", show_col_types = FALSE)

#0: Primo sguardo ai dati

RETexas_ds
## # A tibble: 240 × 8
##    city      year month sales volume median_price listings months_inventory
##    <chr>    <dbl> <dbl> <dbl>  <dbl>        <dbl>    <dbl>            <dbl>
##  1 Beaumont  2010     1    83   14.2       163800     1533              9.5
##  2 Beaumont  2010     2   108   17.7       138200     1586             10  
##  3 Beaumont  2010     3   182   28.7       122400     1689             10.6
##  4 Beaumont  2010     4   200   26.8       123200     1708             10.6
##  5 Beaumont  2010     5   202   28.8       123100     1771             10.9
##  6 Beaumont  2010     6   189   27.2       122800     1803             11.1
##  7 Beaumont  2010     7   164   22.7       124300     1857             11.7
##  8 Beaumont  2010     8   174   25.2       136800     1830             11.6
##  9 Beaumont  2010     9   124   17.2       121100     1829             11.7
## 10 Beaumont  2010    10   150   23.9       138500     1779             11.5
## # ℹ 230 more rows
# Dall'import del dataset noto che è composto da 240 osservazioni e da 8 variabili
# Noto che le variaibli, ad esclusione di "city" che è del testo (character), sono tutte numeriche (double)

# Verifico se non ci sono valori mancanti

colSums(is.na(RETexas_ds))
##             city             year            month            sales 
##                0                0                0                0 
##           volume     median_price         listings months_inventory 
##                0                0                0                0
# Non sono presenti valori mancanti

#1: Analisi delle Variabili

RETexas_ds$city <- as.factor(RETexas_ds$city)
RETexas_ds$year <- as.factor(RETexas_ds$year)
RETexas_ds$month <- factor(RETexas_ds$month, levels = 1:12, labels = month.abb)
sapply(RETexas_ds, class)
##             city             year            month            sales 
##         "factor"         "factor"         "factor"        "numeric" 
##           volume     median_price         listings months_inventory 
##        "numeric"        "numeric"        "numeric"        "numeric"
# City è una variabile qualitativa nominale
# Year anche se ha valori numerici è stata considerata come una variabile qualitativa ordinale in quanto ha poco significato eseguire calcoli numerici su di essi
# Month, del tutto simile a Year, ha valori numerici, ma sono stati convertiti nei corrispondendeti mesi in formato testuale per facilitare la comprensione, e quindi la variabile è considerati variabile qualitativa ordinale
# Sales è una variabiale quantitativa discreta
# Volume è una variabile quantitativa continua
# Median Price è una variabile quantitativa continua
# Listings è una variabile quantitativa discreta
# Months Inventory è una variabile quantitativa continua

# Per le variabili qualitative ha senso constatare come sono distribuite, in modo da cogliere eventuali elementi maggioritari
# Mentre per le variabili quantitative si possono calcolare tutti gli indici di posizione in modo da avere una visione della loro distribuzione

#2: Indici di Posizione, Variabilità e Forma

num_var <- c("sales", "volume", "median_price", "listings", "months_inventory")
cat_var <- c("city", "year", "month")

# Creo una tabella che raccoglie tutte le informazioni statistiche delle variabili quantitative

num_var_stats <- data.frame(
  Variable = num_var,
  Min = round(sapply(RETexas_ds[num_var], min, na.rm = TRUE), 1),
  Q1 = round(sapply(RETexas_ds[num_var], function(x) quantile(x, probs = 0.25, na.rm = TRUE)), 1),
  Q3 = round(sapply(RETexas_ds[num_var], function(x) quantile(x, probs = 0.75, na.rm = TRUE)), 1),
  Max = round(sapply(RETexas_ds[num_var], max, na.rm = TRUE), 1),
  Range = round(sapply(RETexas_ds[num_var], function(x) max(x, na.rm = TRUE) - min(x, na.rm = TRUE)), 1),
  IQR = round(sapply(RETexas_ds[num_var], IQR, na.rm = TRUE), 1),
  Mean = round(sapply(RETexas_ds[num_var], mean, na.rm = TRUE), 2),
  Median = round(sapply(RETexas_ds[num_var], median, na.rm = TRUE), 2),
  Variance = round(sapply(RETexas_ds[num_var], var, na.rm = TRUE), 3),
  Std_Dev = round(sapply(RETexas_ds[num_var], sd, na.rm = TRUE), 3),
  RSD = round(sapply(RETexas_ds[num_var], function(x) (sd(x, na.rm = TRUE) / mean(x, na.rm = TRUE)) * 100), 3),
  Skewness = round(sapply(RETexas_ds[num_var], skewness, na.rm = TRUE), 3),
  Kurtosis = round(sapply(RETexas_ds[num_var], kurtosis, na.rm = TRUE), 3)
)

print(num_var_stats)
##                          Variable     Min       Q1       Q3      Max    Range
## sales                       sales    79.0    127.0    247.0    423.0    344.0
## volume                     volume     8.2     17.7     40.9     83.5     75.4
## median_price         median_price 73800.0 117300.0 150050.0 180000.0 106200.0
## listings                 listings   743.0   1026.5   2056.0   3296.0   2553.0
## months_inventory months_inventory     3.4      7.8     11.0     14.9     11.5
##                      IQR      Mean    Median    Variance   Std_Dev    RSD
## sales              120.0    192.29    175.50 6.34430e+03    79.651 41.422
## volume              23.2     31.01     27.06 2.77271e+02    16.651 53.705
## median_price     32750.0 132665.42 134500.00 5.13573e+08 22662.149 17.082
## listings          1029.5   1738.02   1618.50 5.66569e+05   752.708 43.308
## months_inventory     3.2      9.19      8.95 5.30700e+00     2.304 25.060
##                  Skewness Kurtosis
## sales               0.718    2.687
## volume              0.885    3.177
## median_price       -0.365    2.377
## listings            0.649    2.208
## months_inventory    0.041    2.826
# Dalla tabella contenente gli indici di posizione, variabilità e forma sulle variabili quantitative
# si nota come "volume" è la variabile maggiormente dispersa intorno alla sua media dato l'alto valore di RSD.
# Viceversa "median_price" è la variabile più concentrata intorno alla sua media.
# "sales, "volume" e "listing" sono variabili con distribuzione asimmettrica 
# dato che il valore di skewness è positivo, quindi con valori maggiormente sotto la media.
# Mentre la variabile  "median_price è distribuita asimmettricamente con skewness negativa, 
# quindi con valori maggiormente sopra la media.
# Infine la variabile "months_inventory" è considerabile distribuita simmetricamente,
# poichè ha un valore di skewness vicino allo 0.
# Analizzando l'indice di curtosi si può dire che le variabili "volume" e "month_inventory" hanno una distribuzione vicina a quella normale,
# mentre le altre mostrano valori maggiormente inferiori a 3, ciò implica che hanno distribuzioni platicurtiche.

# Distribuzioni di frequenze delle variabili qualitative

for (var in cat_var){
  print(var)
  ni <- table(RETexas_ds[[var]])
  fi <- round(100*prop.table(ni), 1)
  print(cbind(ni, fi))
}
## [1] "city"
##                       ni fi
## Beaumont              60 25
## Bryan-College Station 60 25
## Tyler                 60 25
## Wichita Falls         60 25
## [1] "year"
##      ni fi
## 2010 48 20
## 2011 48 20
## 2012 48 20
## 2013 48 20
## 2014 48 20
## [1] "month"
##     ni  fi
## Jan 20 8.3
## Feb 20 8.3
## Mar 20 8.3
## Apr 20 8.3
## May 20 8.3
## Jun 20 8.3
## Jul 20 8.3
## Aug 20 8.3
## Sep 20 8.3
## Oct 20 8.3
## Nov 20 8.3
## Dec 20 8.3
# Dalla distribuzione dele variabili qualitative si evince che tutte le osservazioni sono distibuite equamente per ognuna di esse.
# Nello specifico abbiamo 60 osservazioni per ogni città distribuite in modo da avere 20 osservazioni per ogni mese dell'anno dal 2010 al 2014
# Questo significa che c'è una sola osservazione per ogni combinazione "City"-"Year"-"Month"
# E infatti se calcolo il numero minimo di osservazioni avendo 4 citta, 5 anni e 12 mesi ottengo proprio 240.

#3: Identificazione delle variabili con maggiore Variabilità e Asimmetria

print(paste("La variabile con maggiore variabilità è", 
            num_var_stats[which.max(num_var_stats$RSD),1],
            "con valore", round(max(num_var_stats$RSD), 2)))
## [1] "La variabile con maggiore variabilità è volume con valore 53.7"
print(paste("La variabile più asimmetrica è", 
            num_var_stats[which.max(abs(num_var_stats$Skewness)),1],
            "con valore", round(max(num_var_stats$Skewness), 2)))
## [1] "La variabile più asimmetrica è volume con valore 0.88"
# Dall'analisi per il calcolo della variabile con il maggior variabilità e asimmetria si è constato che per entambe risulta essere il volume

#4: Creazione di classi per una variabile quantitativa

# Come variabile quantitativa scelgo "sales"
# Prima di esegurie la suddivisione calcolo tramite la regola di Sturges il numero ottimale di classi da avere

n_sales <- length(RETexas_ds$sales) # numero di osservazioni della variabile (in questo caso del tutto analogo al numero di righe del dataset)
k_sales <- ceiling(1 + log2(n_sales)) # numero di classi secondo la regola di Sturges

# creo una lista per vedere gli estremi delle classi create

breaks_sales <- seq(min(RETexas_ds$sales, na.rm = TRUE), max(RETexas_ds$sales, na.rm = TRUE), length.out = k_sales + 1)

breaks_sales
##  [1]  79.0000 117.2222 155.4444 193.6667 231.8889 270.1111 308.3333 346.5556
##  [9] 384.7778 423.0000
# sfrutto gli estremi per rinominare le etichette delle classi in modo da essere esplicative

labels_sales <- paste0(round(head(breaks_sales, -1), 0), " - ", round(tail(breaks_sales, -1), 0))

labels_sales
## [1] "79 - 117"  "117 - 155" "155 - 194" "194 - 232" "232 - 270" "270 - 308"
## [7] "308 - 347" "347 - 385" "385 - 423"
# creo una nuova variabile all'interno del dataset che indica a quale classe di sales ricade l'osservazione
# impongo che il valore inferiore del range sia contenuto nella classe

RETexas_ds$sales_class <- cut(RETexas_ds$sales,
                              breaks = breaks_sales,
                              include.lowest = TRUE,
                              labels = labels_sales)

# creo una tabella separata con le sole informazioni delle distribuzioni delle classi di sales

sales_class_freq <- as.data.frame(table(RETexas_ds$sales_class))
colnames(sales_class_freq) <- c("Sales_Range", "Frequenza")

print(sales_class_freq)
##   Sales_Range Frequenza
## 1    79 - 117        46
## 2   117 - 155        51
## 3   155 - 194        44
## 4   194 - 232        27
## 5   232 - 270        23
## 6   270 - 308        26
## 7   308 - 347        10
## 8   347 - 385         9
## 9   385 - 423         4
# grafico la tabella delle distribuzioni delle classi

ggplot(sales_class_freq, aes(x = Sales_Range, y = Frequenza, fill = Sales_Range)) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = Frequenza), vjust = -0.3, size = 5) +
  theme_minimal() +
  labs(title = "Distribuzione di Frequenze delle Classi di Sales",
       x = "Intervalli di Sales",
       y = "Frequenza") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        legend.position = "none")

# Dato che abbiamo categorizzato la variabile quantitativa sales è possibile constatare la sua eterogeneità tra le classi
# per fare ciò si può usare la misura dell'indice di eterogeneità di Gini

gini_index_sales <- 1 - sum((sales_class_freq$Frequenza/n_sales)^2)

print(paste("L'indice di Gini per le classi Sales:", round(gini_index_sales, 3)))
## [1] "L'indice di Gini per le classi Sales: 0.848"
# Per essere maggiormante significativo tale indice deve essere normalizzato tramite il valore massimo ottenibile
# il massimo indice possibile dipende dal numero di classi con cui è stata suddivisa la variabile
# una volta ottenuto basterà riportare il rapporto tra l'indice effettivo ed il massimo espresso in percentuale

max_gini_index_sales <- (k_sales - 1)/k_sales

gini_norm_index_sales <- (gini_index_sales/max_gini_index_sales)*100

print(paste("L'indice di Gini normalizzato per le classi Sales:", round(gini_norm_index_sales, 2), "%"))
## [1] "L'indice di Gini normalizzato per le classi Sales: 95.34 %"
# La variabile sales per come è stata distribuità presenta un elevato indice di eterogeneità, prossimo al massimo

# In modo del tutto analogo posso eseguire i vari step per la variabile medina_price

n_median_price <- length(RETexas_ds$median_price) # numero di osservazioni della variabile (in questo caso del tutto analogo al numero di righe del dataset)
k_median_price <- ceiling(1 + log2(n_median_price)) # numero di classi secondo la regola di Sturges

breaks_median_price <- seq(min(RETexas_ds$median_price, na.rm = TRUE), max(RETexas_ds$median_price, na.rm = TRUE), length.out = k_median_price + 1)

breaks_median_price
##  [1]  73800  85600  97400 109200 121000 132800 144600 156400 168200 180000
# a differenza delle sales, divido per 1000 i valori in modo da portare l'unità di misura in M$ e facilitare la lettura

labels_median_price <- paste0(round(head(breaks_median_price, -1), 0)/1000, " - ", round(tail(breaks_median_price, -1), 0)/1000)

labels_median_price
## [1] "73.8 - 85.6"   "85.6 - 97.4"   "97.4 - 109.2"  "109.2 - 121"  
## [5] "121 - 132.8"   "132.8 - 144.6" "144.6 - 156.4" "156.4 - 168.2"
## [9] "168.2 - 180"
RETexas_ds$median_price_class <- cut(RETexas_ds$median_price,
                              breaks = k_median_price,
                              include.lowest = TRUE,
                              labels = labels_median_price)

median_price_class_freq <- as.data.frame(table(RETexas_ds$median_price_class))
colnames(median_price_class_freq) <- c("Median_Price_Range", "Frequenza")

print(median_price_class_freq)
##   Median_Price_Range Frequenza
## 1        73.8 - 85.6         2
## 2        85.6 - 97.4        18
## 3       97.4 - 109.2        26
## 4        109.2 - 121        22
## 5        121 - 132.8        39
## 6      132.8 - 144.6        49
## 7      144.6 - 156.4        53
## 8      156.4 - 168.2        21
## 9        168.2 - 180        10
ggplot(median_price_class_freq, aes(x = Median_Price_Range, y = Frequenza, fill = Median_Price_Range)) +
  geom_bar(stat = "identity") +
  geom_text(aes(label = Frequenza), vjust = -0.3, size = 5) +
  theme_minimal() +
  labs(title = "Distribuzione di Frequenze delle Classi di Median Price",
       x = "Intervalli di Median Price [M$]",
       y = "Frequenza") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1),
        legend.position = "none")

gini_index_median_price <- 1 - sum((median_price_class_freq$Frequenza/n_median_price)^2)

print(paste("L'indice di Gini per le classi Median Price:", round(gini_index_median_price, 3)))
## [1] "L'indice di Gini per le classi Median Price: 0.848"
max_gini_index_median_price <- (k_median_price - 1)/k_median_price

gini_norm_index_median_price <- (gini_index_median_price/max_gini_index_median_price)*100

print(paste("L'indice di Gini normalizzato per le classi Median Price:", round(gini_norm_index_median_price, 2), "%"))
## [1] "L'indice di Gini normalizzato per le classi Median Price: 95.39 %"
# Anche la variabile median price per come è stata distribuità presenta un elevato indice di eterogeneità, prossimo al massimo

#5: Calcolo della probabilità

# Si vuole conoscere la probabilità che presa una riga a caso di questo dataset, essa riporti la città “Beaumont”
# Si vuole conoscere la probabilità che riporti il mese di Luglio
# Si vuole la probabilità che riporti il mese di dicembre 2012

# Per le prime due probabilità questi valori sono stati già ricavati durante il punto #2
# quando sono stati calcolate le frequenze relative per la variabili qualitative

# Quindi per la prima probabilità (city = Beaumont) il risultato è 0.25 (25%)
# Per la seconda probabilità ( month = Luglio) il risultato è 0.083 (8.3%)

# Per la terza probabiòlità ci basta fare il prodotto tra la frequenza relativa che sia dicembre (0.083) e quella che sia il 2012 (0.20)

0.20*0.083
## [1] 0.0166
# La probabilità di avere casualmente una osservazione del dicembre 2012 è 0.0166 (1.6%)

#6: Creazione di nuove variabili

# Devo creare una variabile che misuri il prezzo medio degli immobili
# per fare ciò, mi basta dividere il totale delle vendite (volume) di una osservazione per il rispettivo numero di vendite (sales)
# per semplicità di lettura, dato che il volume è espresso in milioni di dollari, moltiplico il valore per 10^6 in modo che il valore medio sia in dollari

RETexas_ds$mean_price <- round((RETexas_ds$volume/RETexas_ds$sales)*10^6, 0)

# Per misurare l'efficacia degli annunci eseguo un calcolo simile
# Divido il numero delle vendite effettuate (sales) per il numero di annunci attivi (listings)
# Per facilitare la lettura del dato molitplico per 100 il risultato così da avere un valore percentuale

RETexas_ds$listings_effectiveness <- round((RETexas_ds$sales/RETexas_ds$listings)*100, 2)

#7: Analisi condizionata

city_mean_price_stats <- RETexas_ds %>%
  group_by(city) %>%
  summarise(
    city_mean_price = mean(mean_price, na.rm = TRUE),
    sd_mean_price = sd(mean_price, na.rm = TRUE)
  ) %>%
  ungroup()

print(city_mean_price_stats)
## # A tibble: 4 × 3
##   city                  city_mean_price sd_mean_price
##   <fct>                           <dbl>         <dbl>
## 1 Beaumont                      146640.        11232.
## 2 Bryan-College Station         183534.        15149.
## 3 Tyler                         167677.        12351.
## 4 Wichita Falls                 119430.        11398.
year_mean_price_stats <- RETexas_ds %>%
  group_by(year) %>%
  summarise(
    year_mean_price = mean(mean_price, na.rm = TRUE),
    sd_mean_price = sd(mean_price, na.rm = TRUE)
  ) %>%
  ungroup()

print(year_mean_price_stats)
## # A tibble: 5 × 3
##   year  year_mean_price sd_mean_price
##   <fct>           <dbl>         <dbl>
## 1 2010          150189.        23280.
## 2 2011          148251.        24938.
## 3 2012          150899.        26438.
## 4 2013          158705.        26524.
## 5 2014          163559.        31741.
month_mean_price_stats <- RETexas_ds %>%
  group_by(month) %>%
  summarise(
    month_mean_price = mean(mean_price, na.rm = TRUE),
    sd_mean_price = sd(mean_price, na.rm = TRUE)
  ) %>%
  ungroup()

print(month_mean_price_stats)
## # A tibble: 12 × 3
##    month month_mean_price sd_mean_price
##    <fct>            <dbl>         <dbl>
##  1 Jan            145640.        29819.
##  2 Feb            148840.        25120.
##  3 Mar            151137.        23238.
##  4 Apr            151461.        26174.
##  5 May            158235.        25787.
##  6 Jun            161546.        23470.
##  7 Jul            156881.        27220.
##  8 Aug            156456.        28253.
##  9 Sep            156522.        29669.
## 10 Oct            155897.        32527.
## 11 Nov            154233.        29685.
## 12 Dec            154995.        27009.
ggplot(city_mean_price_stats, aes(x = city, y = city_mean_price/1000, fill = city)) +
  geom_bar(stat = "identity", alpha = 0.7) +
  geom_errorbar(aes(ymin = (city_mean_price - sd_mean_price)/1000, ymax = (city_mean_price + sd_mean_price)/1000), 
                width = 0.2, color = "black") +  # Barre di errore
  theme_minimal() +
  labs(title = "Media delle Vendite per Città",
       x = "Città", y = "Media Vendite [M$]") +
  theme(legend.position = "none")

ggplot(year_mean_price_stats, aes(x = year, y = year_mean_price/1000, fill = year)) +
  geom_bar(stat = "identity", alpha = 0.7) +
  geom_errorbar(aes(ymin = (year_mean_price - sd_mean_price)/1000, ymax = (year_mean_price + sd_mean_price)/1000), 
                width = 0.2, color = "black") +  # Barre di errore
  theme_minimal() +
  labs(title = "Media delle Vendite per Anno",
       x = "Anno", y = "Media Vendite [M$]") +
  theme(legend.position = "none")

ggplot(month_mean_price_stats, aes(x = month, y = month_mean_price/1000, fill = month)) +
  geom_bar(stat = "identity", alpha = 0.7) +
  geom_errorbar(aes(ymin = (month_mean_price - sd_mean_price)/1000, ymax = (month_mean_price + sd_mean_price)/1000), 
                width = 0.2, color = "black") +  # Barre di errore
  theme_minimal() +
  labs(title = "Media delle Vendite per Mese",
       x = "Mese", y = "Media Vendite [M$]") +
  theme(legend.position = "none")

#8: Creazione di visualizzazioni con ggplot2

# Usare un boxplot per confrontare le distribuzioni dei prezzi mediani fra le città

ggplot(RETexas_ds, aes(x = city, y = median_price/1000, fill = city)) +
  geom_boxplot(alpha = 0.7) +  # Boxplot con trasparenza
  theme_minimal() +
  labs(title = "Distribuzione del Prezzo Mediano per Città",
       x = "Città", y = "Prezzo Mediano (M$)") +
  theme(legend.position = "none",
        axis.text.x = element_text(angle = 45, hjust = 1)) 

# Usare un grafico a barre per confrontare il totale delle vendite per mese e città

sales_month_city <- RETexas_ds %>%
  group_by(city, month) %>%
  summarise(total_sales = sum(sales, na.rm = TRUE)) %>%
  ungroup()
## `summarise()` has grouped output by 'city'. You can override using the
## `.groups` argument.
ggplot(sales_month_city, aes(x = month, y = total_sales, fill = city)) +
  geom_bar(stat = "identity", position = "dodge", width = 0.8) +  # Barre affiancate per ogni città
  theme_minimal() +
  labs(title = "Andamento Totale delle Vendite per Mese e Città",
       x = "Mese", y = "Totale Vendite") +
  scale_x_discrete(limits = month.abb) +  # Ordina i mesi con abbreviazioni standard
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

ggplot(sales_month_city, aes(x = month, y = total_sales, fill = city)) +
  geom_bar(stat = "identity", position = "stack") +  # Barre impilate
  geom_text(aes(label = total_sales), 
            position = position_stack(vjust = 0.5),  # Posiziona le etichette al centro della barra
            color = "black", size = 2) +  # Imposta il colore e la dimensione del testo
  theme_minimal() +
  labs(title = "Vendite Totali per Mese e Città (Barre Impilate)",
       x = "Mese", y = "Totale Vendite") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

# Usare dei grafici line chart per confrontare l'andamento delle vendite nel tempo

sales_time <- RETexas_ds %>%
  group_by(year, month) %>%
  summarise(total_sales = sum(sales, na.rm = TRUE)) %>%
  ungroup()
## `summarise()` has grouped output by 'year'. You can override using the
## `.groups` argument.
ggplot(sales_time, aes(x = month, y = total_sales, color = year, group = year)) +
  geom_line(linewidth = 1) +  # Linee più spesse
  geom_point(size = 2) +  # Punti per maggiore leggibilità
  theme_minimal() +
  labs(title = "Andamento delle Vendite per Mese (Confronto tra Anni)",
       x = "Mese", y = "Totale Vendite", color = "Anno") +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

#9: Conclusioni

# Dalla analisi svolta si posso trarre le seguenti conclusioni:
# - Nel corso del tempo il prezzo medio e mediano di vendita delle case è stato più elevato nella città di Bryan-College Station, a seguire Tyler, Beaumont e infine Wichita Falss
# - La città in cui si finalizzano più vendite è Tyler, a seguire Bryan-College Station, Beaumont e infinte Wichita Falls
# - Non sono ci sono state nel corso degli anni sostanziali variazioni del prezzo medio di vendita
# - Il 2014 è stato l'anno che ha registrato il maggior numero di vendite per quasi ogni mese, mentre gli anni peggiori sono stati il 2010 e 2011
# - Si nota come nel corso degli anni l'azienda ha incrementato il numero di vendite
# - Seppur con una leggero rialzo durante i mesi di Giugno, non sono riscontrabili significative variazioni del prezzo medio di vendita tra i diversi mesi dell'anno
# - Tuttavia tra Maggio e Agosto si registrano in generale per tutte le città un maggior numero di vendite
# - Per ottimizzare le vendite bisogna cercare di replicare il modello di annunci impiegato nella città di Bryan-College Station tra il 2013 e il 2014 poichè sono quelli con la maggior efficacia
# In particolare modo bisogna applicarlo per la città di Tyler dove attualmente c'è un bassa efficacia degli annunci e quindi un potenziale margine da colmare per incrementare ulteriormente le vendite
# Questo risulta essere molto importante per i guadagni se si considera che Tyler è al secondo posto come prezzo medio di vendita delle case
# - Si potrebbe pensare di ridurre le risorse impiegate a Wichita Falls dato che attualmente è la città con il prezzo medio inferiore e che in valore assoluto registra il minor numero di vendite