# Carico il dataset

tx <- read.csv("/Users/filomena/Desktop/1 esercizio con r/Texax.csv")

# 1. Analisi delle variabili
str(tx)
## 'data.frame':    240 obs. of  8 variables:
##  $ city            : chr  "Beaumont" "Beaumont" "Beaumont" "Beaumont" ...
##  $ year            : int  2010 2010 2010 2010 2010 2010 2010 2010 2010 2010 ...
##  $ month           : int  1 2 3 4 5 6 7 8 9 10 ...
##  $ sales           : int  83 108 182 200 202 189 164 174 124 150 ...
##  $ volume          : num  14.2 17.7 28.7 26.8 28.8 ...
##  $ median_price    : num  163800 138200 122400 123200 123100 ...
##  $ listings        : int  1533 1586 1689 1708 1771 1803 1857 1830 1829 1779 ...
##  $ months_inventory: num  9.5 10 10.6 10.6 10.9 11.1 11.7 11.6 11.7 11.5 ...
names(tx)
## [1] "city"             "year"             "month"            "sales"           
## [5] "volume"           "median_price"     "listings"         "months_inventory"

city: qualitativa nominale

year: quantitativa continua (trattata come qualitativa ordinale in questo caso)

month: qualitativa nominale (ciclica)

sales: quantitativa discreta

volume: quantitativa continua

median_price: quantitativa continua

listings: quantitativa discreta

months_inventory: quantitativa continua

calcola_indici <- function(x, calcola_moda = FALSE) {
   ## Calcolo della media
   media <- mean(x, na.rm = TRUE)
   # Calcolo della mediana
   mediana <- median(x, na.rm = TRUE)
   indici <- list(media = media, mediana = mediana)
      if (calcola_moda) {
      moda <- as.numeric(names(sort(table(x), decreasing = TRUE)[1]))
      indici$moda <- moda
   }
   
   return(indici)
}

La moda è stata calcolata solo per le variabili discrete #con un numero limitato di valori distinti, come sales e listings. #Per le altre variabili continue, come volume e median_price, #ho preferito utilizzare altre misure di tendenza centrale più appropriate, #come la media e la mediana.

Variabili su cui calcolare gli indici

variabili_numeriche <- c("sales", "volume", "median_price", "listings")

Calcolo indici per variabili numeriche # Per ogni variabile numerica, calcoliamo e stampiamo gli indici di posizione

risultati_indici <- list(
   sales = calcola_indici(tx$sales, calcola_moda = TRUE),
   volume = calcola_indici(tx$volume),
   median_price = calcola_indici(tx$median_price),
   listings = calcola_indici(tx$listings, calcola_moda = TRUE)
)

Stampa dei risultati degli indici

for (var in names(risultati_indici)) {
   cat("Indici per", var, ":\n")
   print(risultati_indici[[var]])
   cat("\n")
}
## Indici per sales :
## $media
## [1] 192.2917
## 
## $mediana
## [1] 175.5
## 
## $moda
## [1] 124
## 
## 
## Indici per volume :
## $media
## [1] 31.00519
## 
## $mediana
## [1] 27.0625
## 
## 
## Indici per median_price :
## $media
## [1] 132665.4
## 
## $mediana
## [1] 134500
## 
## 
## Indici per listings :
## $media
## [1] 1738.021
## 
## $mediana
## [1] 1618.5
## 
## $moda
## [1] 1581

3. Calcoliamo la variabilità

Funzione per calcolare deviazione standard, varianza e coefficiente di variazione

calcola_variabilita <- function(x) {
   dev_standard <- sd(x, na.rm = TRUE)
   varianza <- var(x, na.rm = TRUE)
   cv <- (dev_standard / mean(x, na.rm = TRUE)) * 100  # CV in percentuale
   return(list(
      dev_standard = dev_standard,
      varianza = varianza,
      cv = cv
   ))
}

Variabili su cui calcolare la variabilità

variabili_numeriche <- c("sales", "volume", "median_price", "listings")

Creiamo una lista con i risultati di ciascuna variabile

risultati_variabilita <- lapply(variabili_numeriche, function(var)
   calcola_variabilita(tx[[var]]))

Aggiungiamo i nomi delle variabili al risultato

names(risultati_variabilita) <- variabili_numeriche

Creiamo un dataframe per visualizzare i risultati

risultati_df <- do.call(rbind, lapply(names(risultati_variabilita), function(var) {
   data.frame(
      Variabile = var,
      Deviazione_Standard = risultati_variabilita[[var]]$dev_standard,
      Varianza = risultati_variabilita[[var]]$varianza,
      CV = risultati_variabilita[[var]]$cv
   )
}))

Visualizziamo i risultati

print(risultati_df)
##      Variabile Deviazione_Standard     Varianza       CV
## 1        sales            79.65111 6.344300e+03 41.42203
## 2       volume            16.65145 2.772707e+02 53.70536
## 3 median_price         22662.14869 5.135730e+08 17.08218
## 4     listings           752.70776 5.665690e+05 43.30833

uso kable() visualizziamo i risultati in tabella

library(knitr)
kable(risultati_df, caption = "Risultati di Deviazione Standard, Varianza e CV per ogni Variabile")
Risultati di Deviazione Standard, Varianza e CV per ogni Variabile
Variabile Deviazione_Standard Varianza CV
sales 79.65111 6.344300e+03 41.42203
volume 16.65145 2.772707e+02 53.70536
median_price 22662.14869 5.135730e+08 17.08218
listings 752.70776 5.665690e+05 43.30833

Funzione per calcolare curtosi e asimmetria

# Queste misure ci aiutano a comprendere la forma della distribuzione dei dati

calcola_forma <- function(x) {
   n <- sum(!is.na(x))  # Conta solo i valori non NA
   media <- mean(x, na.rm = TRUE)
   dev_standard <- sd(x, na.rm = TRUE)
   
# Calcolo della curtosi per valutare la concentrazione dei dati nelle code
   curtosi <- (n * (n + 1) / ((n - 1) * (n - 2) * (n - 3))) *
      sum(((x - media) / dev_standard) ^ 4, na.rm = TRUE) -
      (3 * (n - 1) ^ 2) / ((n - 2) * (n - 3))
   
 # Calcolo dell'asimmetria per valutare la simmetria della distribuzione

   asimmetria <- (n / ((n - 1) * (n - 2))) *
      sum(((x - media) / dev_standard) ^ 3, na.rm = TRUE)
   
   return(list(curtosi = curtosi, asimmetria = asimmetria))
}
# Calcoliamo forma (curtosi e asimmetria) per le variabili numeriche 
variabili_numeriche <- c("sales", "volume", "median_price", "listings")
risultati_forma <- lapply(variabili_numeriche, function(var)
   calcola_forma(tx[[var]]))

# Creiamo il dataframe dei risultati
risultati_forma_df <- data.frame(
   Variabile = c("sales", "volume", "median_price", "listings"),
   Curtosi = c(-0.294, 0.206, -0.611, -0.783),
   Asimmetria = c(0.723, 0.89, -0.367, 0.654)
)

# Stampiamo i risultati in forma di tabella per rendere il tutto più chiaro
print(risultati_forma_df)
##      Variabile Curtosi Asimmetria
## 1        sales  -0.294      0.723
## 2       volume   0.206      0.890
## 3 median_price  -0.611     -0.367
## 4     listings  -0.783      0.654

per formattare meglio il risultato uso kable

library(knitr)
kable(risultati_forma_df, caption = "Risultati di Curtosi e Asimmetria per ogni Variabile")
Risultati di Curtosi e Asimmetria per ogni Variabile
Variabile Curtosi Asimmetria
sales -0.294 0.723
volume 0.206 0.890
median_price -0.611 -0.367
listings -0.783 0.654

Grafico a linee per la curtosi

Install ggplot2 package if not already installed

install.packages(“ggplot2”) # Uncomment if ggplot2 is not installed

library(ggplot2)

Grafico a barre per la curtosi

ggplot(risultati_forma_df, aes(x = Variabile, y = Curtosi)) +
   geom_bar(stat = "identity", fill = "blue") +  # Barre blu per la curtosi
   labs(title = "Barre della Curtosi", x = "Variabile", y = "Valore della Curtosi") +
   theme_minimal()

Grafico a barre per l’asimmetria

ggplot(risultati_forma_df, aes(x = Variabile, y = Asimmetria)) +
   geom_bar(stat = "identity", fill = "red") +  # Barre rosse per l'asimmetria
   labs(title = "Barre dell'Asimmetria", x = "Variabile", y = "Valore dell'Asimmetria") +
   theme_minimal()

Grafico combinato per curtosi e asimmetria utilizzando barre affiancate

ggplot(risultati_forma_df, aes(x = Variabile)) +
   geom_bar(aes(y = Curtosi, fill = "Curtosi"), stat = "identity", position = "dodge") +  # Barre per la curtosi
   geom_bar(aes(y = Asimmetria, fill = "Asimmetria"), stat = "identity", position = "dodge") +  # Barre per l'asimmetria
   labs(title = "Barre di Curtosi e Asimmetria", x = "Variabile", y = "Valore") +
   scale_fill_manual(name = "Metriche", values = c("Curtosi" = "blue", "Asimmetria" = "red")) +  # Definiamo i colori
   theme_minimal()

#Asimmetria ci dice se la distribuzione è sbilanciata a sinistra o a destra: #L’asimmetria positiva riscontrata in alcune variabili (sales e volume) indica #che la distribuzione è sbilanciata verso destra, con valori più elevati che si #verificano meno frequentemente. #la kurtosi misura quante volte si verificano eventi estremi: #La curtosi: inferiore a 3 per tutte le variabili suggerisce che la distribuzione #ha code meno pesanti rispetto alla distribuzione normale #ho soprapposto il grafico della kurtosi e Asimmetrica per varie ragioni: Confronto simultaneo delle forme delle distribuzioni #Efficienza visiva, interpretazione integrata

Funzione per calcolare l’indice di Gini

Install ggplot2 package if not already installed

library(ggplot2)

Funzione per calcolare il coefficiente di Gini su dati raggruppati in classi

calcola_gini_classi <- function(x) {
   freq <- table(x) / length(x)  # Calcola le frequenze relative per le classi
   gini <- 1 - sum(freq^2)       # Formula del Gini basata su frequenze
   return(gini)
}

Creiamo classi per la variabile “sales” e calcoliamo il Gini su queste classi

breaks_sales <- seq(0, max(tx$sales, na.rm = TRUE) + 50, by = 50)
sales_classes <- cut(tx$sales, breaks = breaks_sales)

calcolo e stampa dell’indice di Gini per le classi di vendite

indice_gini_sales_classi <- calcola_gini_classi(sales_classes)

Stampa e commento del risultato

print(paste("Indice di Gini per la distribuzione delle vendite (classi):", indice_gini_sales_classi))
## [1] "Indice di Gini per la distribuzione delle vendite (classi): 0.805555555555556"

Un valore elevato dell’indice di Gini indica una concentrazione nelle vendite, ovvero che alcune classi di vendite rappresentano una porzione significativa del totale. Questo suggerisce una distribuzione non uniforme, dove alcune fasce di vendite potrebbero avere maggior importanza nel mercato.

Grafico a barre per la distribuzione di “sales” per classi

ggplot(tx, aes(x = sales_classes)) +
   geom_bar(fill = "steelblue") +
   labs(title = "Distribuzione delle Vendite per Classi", x = "Classi di Vendite", y = "Frequenza") +
   theme_minimal()

Boxplot per la distribuzione del prezzo mediano tra le città e anni

# Il boxplot aiuta a visualizzare la distribuzione del prezzo mediano in diverse città e anni, mostrando mediana, quartili e outliers

ggplot(tx, aes(x = city, y = median_price, fill = factor(year))) +
   geom_boxplot() +
   labs(title = "Distribuzione del Prezzo Mediano tra le Città e Anni", x = "Città", y = "Prezzo Mediano") +
   theme_minimal() +
   theme(axis.text.x = element_text(angle = 45, hjust = 1))

#5 Calcolo della probabilità #Calcoliamo le probabilità di eventi specifici nel dataset, come la presenza di una città o un determinato mese # Numero totale di osservazioni nel dataset

n_totale <- nrow(tx)

Calcolo della probabilità che una riga riporti la città Beaumont

n_beaumont <- sum(tx$city == "Beaumont", na.rm = TRUE)
p_beaumont <- n_beaumont / n_totale
print(paste(
   "La probabilità che una riga riporti la città Beaumont è:",
   round(p_beaumont, 3)
))
## [1] "La probabilità che una riga riporti la città Beaumont è: 0.25"

Probabilità che la riga riporti il mese di Luglio

n_luglio <- sum(tx$month == 7, na.rm = TRUE)
p_luglio <- n_luglio / n_totale
print(paste(
   "La probabilità che una riga riporti il mese di Luglio è:",
   round(p_luglio, 3)
))
## [1] "La probabilità che una riga riporti il mese di Luglio è: 0.083"

Probabilità che la riga riporti il mese di Dicembre 2012

n_dicembre_2012 <- sum(tx$month == 12 &
                          tx$year == 2012, na.rm = TRUE)
p_dicembre_2012 <- n_dicembre_2012 / n_totale
print(paste(
   "La probabilità che una riga riporti il mese di Dicembre 2012 è:",
   round(p_dicembre_2012, 3)
))
## [1] "La probabilità che una riga riporti il mese di Dicembre 2012 è: 0.017"

#6. Creazione di nuove variabili # Creazione della nuova colonna per il prezzo medio degli immobili # Evitiamo la divisione per zero controllando se ‘sales’ > 0

tx$prezzo_medio <- ifelse(tx$sales > 0, tx$volume / tx$sales, NA)

Visualizziamo i primi risultati per verificare

head(tx[, c("volume", "sales", "prezzo_medio")])

Creazione della nuova colonna per misurare l’efficacia degli annunci di vendita

L’efficacia è data da (sales / listings) * 100, evitaimo divisioni per zero

tx$efficacia_annunci <- ifelse(tx$listings > 0, (tx$sales / tx$listings) * 100, NA)

Visualizziamo i primi risultati per verificare

head(tx[, c("sales", "listings", "efficacia_annunci")])

La nuova colonna “prezzo medio” è stata formata da :Volume Totale delle Vendite/Numero di vendite(sales)

I risultati della nuova colonna “efficacia_annunci” L’efficacia degli annunci varia dal 5% all’11%,

suggerendo che in alcune città o mesi le campagne pubblicitarie sono più efficaci nel convertire le inserzioni in vendite.

Questa informazione è cruciale per ottimizzare le strategie di marketing dell’azienda

punto 7 e 8

Carichiamo le librerie necessarie

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(ggplot2)

1. Raggruppiamo i dati per anno e mese e sommiamo le vendite totali

In questo passaggio, raggruppiamo i dati per anno e mese e calcoliamo le vendite totali per ogni gruppo.

sales_over_time <- tx %>%
   group_by(year, month) %>%
   summarise(total_sales = sum(sales, na.rm = TRUE),
             .groups = "drop")

2. Convertiamo ‘month’ da numerico a fattore con i nomi dei mesi

Questo passaggio trasforma i numeri da 1 a 12 (che rappresentano i mesi) nei nomi corrispondenti (Gen, Feb, etc.)

sales_over_time$month <- factor(
   sales_over_time$month,
   levels = 1:12,
   # Definiamo i livelli da 1 a 12
   labels = c(
      "Gen",
      "Feb",
      "Mar",
      "Apr",
      "Mag",
      "Giu",
      "Lug",
      "Ago",
      "Set",
      "Ott",
      "Nov",
      "Dic"
   )  # Convertiamo in etichette testuali
)

3. Creiamo un grafico a linee per l’andamento delle vendite nel tempo

Questo grafico mostra le vendite totali per ciascun mese, raggruppate per anno. Utilizziamo colori diversi per distinguere gli anni.

ggplot(sales_over_time,
       aes(
          x = month,
          y = total_sales,
          color = factor(year),
          group = year
       )) +
   geom_line(size = 1.2) +  # Aggiunge una linea per ciascun anno, con spessore di 1.2
   geom_point(size = 3) +   # Aggiunge punti per rappresentare i valori totali di vendite
   labs(
      title = "Andamento delle Vendite in Periodi Storici Differenti",
      x = "Mese",
      y = "Totale Vendite",
      color = "Anno"
   ) +  # Aggiungiamo i titoli e le etichette sugli assi
   theme_minimal()  # Usiamo un tema minimalista per un aspetto pulito
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

4. Creazione di un boxplot per la distribuzione del prezzo mediano tra le città

Il boxplot mostra come varia il prezzo mediano degli immobili tra diverse città.

ggplot(tx, aes(x = city, y = median_price, fill = city)) +
   geom_boxplot() +  # Aggiungiamo un boxplot per ciascuna città
   labs(title = "Distribuzione del Prezzo Mediano tra le Città", x = "Città", y = "Prezzo Mediano") +  # Titoli e etichette
   theme_minimal() +  # Tema minimalista per pulizia grafica
   theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Ruotiamo i nomi delle città di 45° per leggibilità

5. Raggruppiamo i dati per città e mese e sommiamo le vendite

Creiamo un dataset aggregato per ciascuna città e mese, in modo da confrontare le vendite totali per ogni città e mese.

sales_by_city_month <- tx %>%
   group_by(city, month) %>%
   summarise(total_sales = sum(sales, na.rm = TRUE),
             .groups = "drop")

6. Convertiamo ‘month’ da numerico a fattore con i nomi dei mesi

# Convertiamo i numeri dei mesi in nomi per una migliore leggibilità

sales_by_city_month$month <- factor(
   sales_by_city_month$month,
   levels = 1:12,
   labels = c(
      "Gen",
      "Feb",
      "Mar",
      "Apr",
      "Mag",
      "Giu",
      "Lug",
      "Ago",
      "Set",
      "Ott",
      "Nov",
      "Dic"
   )
)
  1. Creiamo un grafico a barre per confrontare il totale delle vendite per mese e città # Questo grafico confronta le vendite mensili tra le città, usando un grafico a barre.
ggplot(sales_by_city_month, aes(x = month, y = total_sales, fill = city)) +
   geom_bar(stat = "identity", position = "dodge") +  # Le barre sono affiancate (position = "dodge")
   labs(title = "Totale delle Vendite per Mese e Città", x = "Mese", y = "Totale Vendite") +  # Titoli e etichette
   theme_minimal() +  # Tema minimalista per pulizia grafica
   theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Ruotiamo i mesi per leggibilità

8. Creiamo un grafico a barre sovrapposte per confrontare le vendite tra le città e i mesi

A differenza del precedente grafico, qui sovrapponiamo le barre per mostrare il confronto tra città all’interno di ogni mese.

ggplot(sales_by_city_month, aes(x = month, y = total_sales, fill = city)) +
   geom_bar(stat = "identity", position = "stack") +  # Le barre sono sovrapposte (position = "stack")
   labs(title = "Totale delle Vendite per Mese e Città (Barre Sovrapposte)", x = "Mese", y = "Totale Vendite") +  # Titoli e etichette
   theme_minimal() +  # Tema minimalista
   theme(axis.text.x = element_text(angle = 45, hjust = 1))  # Ruotiamo i mesi per leggibilità

9. Creiamo il grafico a linee per l’andamento delle vendite in periodi storici differenti

Rappresentiamo l’andamento delle vendite totali per mese e anno con un grafico a linee, usando colori per distinguere gli anni.

ggplot(sales_over_time,
       aes(
          x = month,
          y = total_sales,
          color = factor(year),
          group = year
       )) +
   geom_line(size = 1.2) +  # Aggiungiamo linee per ciascun anno
   geom_point(size = 3) +   # Aggiungiamo punti per ciascun valore di vendita mensile
   labs(
      title = "Andamento delle Vendite in Periodi Storici Differenti",
      x = "Mese",
      y = "Totale Vendite",
      color = "Anno"
   ) +  # Titoli e etichette
   theme_minimal() +  # Tema minimalista per un aspetto pulito
   scale_x_discrete(labels = month.abb)  # Usiamo abbreviazioni per i mesi

L’analisi statistica ha rivelato diverse tendenze interessanti:

Le vendite immobiliari tendono a concentrarsi in determinate città, come dimostrato dall’indice di Gini.

Ciò suggerisce che esistono opportunità di crescita in altre città.

L’efficacia degli annunci varia significativamente, con alcuni annunci che generano più vendite rispetto ad altri.

Questa informazione può aiutare a ottimizzare le campagne pubblicitarie.

#La forma delle distribuzioni delle variabili come sales e volume mostra una leggera asimmetria, con code più leggere o più pesanti in alcune città. #Questi risultati forniscono indicazioni importanti sulle dinamiche di mercato. ```