# 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)
)
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
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_numeriche <- c("sales", "volume", "median_price", "listings")
risultati_variabilita <- lapply(variabili_numeriche, function(var)
calcola_variabilita(tx[[var]]))
names(risultati_variabilita) <- variabili_numeriche
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
)
}))
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
library(knitr)
kable(risultati_df, caption = "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 |
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")
| Variabile | Curtosi | Asimmetria |
|---|---|---|
| sales | -0.294 | 0.723 |
| volume | 0.206 | 0.890 |
| median_price | -0.611 | -0.367 |
| listings | -0.783 | 0.654 |
library(ggplot2)
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()
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()
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
library(ggplot2)
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)
}
breaks_sales <- seq(0, max(tx$sales, na.rm = TRUE) + 50, by = 50)
sales_classes <- cut(tx$sales, breaks = breaks_sales)
indice_gini_sales_classi <- calcola_gini_classi(sales_classes)
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.
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()
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)
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"
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"
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)
head(tx[, c("volume", "sales", "prezzo_medio")])
tx$efficacia_annunci <- ifelse(tx$listings > 0, (tx$sales / tx$listings) * 100, NA)
head(tx[, c("sales", "listings", "efficacia_annunci")])
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)
sales_over_time <- tx %>%
group_by(year, month) %>%
summarise(total_sales = sum(sales, na.rm = TRUE),
.groups = "drop")
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
)
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.
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à
sales_by_city_month <- tx %>%
group_by(city, month) %>%
summarise(total_sales = sum(sales, na.rm = TRUE),
.groups = "drop")
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"
)
)
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à
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à
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
#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. ```