if ("volume" %in% names(df) && is.character(df$volume)) {
temp_vol <- gsub("\\.00$", "", df$volume)
temp_vol <- gsub("[^0-9.]", "", temp_vol)
df$volume_clean <- as.numeric(temp_vol)
cat("Colonna 'volume' pulita in 'volume_clean'")
na_count_vol <- sum(is.na(df$volume_clean))
if (na_count_vol > 0) {
warning(paste("Pulizia di 'volume' ha prodotto", na_count_vol, "valori NA. Verifica i dati originali problematici."))
}
} else if ("volume" %in% names(df) && is.numeric(df$volume)) {
df$volume_clean <- df$volume
cat("\nColonna 'volume' era già numerica, copiata in 'volume_clean'.\n")
} else {
warning("Colonna 'volume' non trovata.")
}
## Colonna 'volume' pulita in 'volume_clean'
if ("median_price" %in% names(df) && is.character(df$median_price)) {
temp_mp <- gsub("[^0-9.]", "", df$median_price)
df$median_price_clean <- as.numeric(temp_mp)
cat("Colonna 'median_price' pulita in 'median_price_clean'.\n")
na_count_mp <- sum(is.na(df$median_price_clean))
if (na_count_mp > 0) {
warning(paste("Pulizia di 'median_price' ha prodotto", na_count_mp, "valori NA. Verifica i dati originali problematici."))
}
} else if ("median_price" %in% names(df) && is.numeric(df$median_price)) {
df$median_price_clean <- df$median_price
cat("\nColonna 'median_price' era già numerica, copiata in 'median_price_clean'.\n")
} else {
warning("Colonna 'median_price' non trovata o di tipo inatteso.")
}
## Colonna 'median_price' pulita in 'median_price_clean'.
if ("year" %in% names(df) && "month" %in% names(df) && is.numeric(df$year) && is.numeric(df$month)) {
df$year_month <- as.Date(paste(df$year, df$month, "01", sep = "-"), format = "%Y-%m-%d")
cat("Variabile temporale 'year_month' creata/verificata.\n")
} else {
warning("Colonne 'year'/'month' non trovate o non numeriche. Impossibile creare 'year_month'.")
}
## Variabile temporale 'year_month' creata/verificata.
cat("\n--- Struttura del Dataframe dopo la pulizia mirata ---\n")
##
## --- Struttura del Dataframe dopo la pulizia mirata ---
str(df)
## 'data.frame': 240 obs. of 11 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 : chr "16.42" "18.09" "39.41.00" "39.39.00" ...
## $ median_price : chr "163800" "138200" "122400" "123200" ...
## $ 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 ...
## $ volume_clean : num 16.4 18.1 39.4 39.4 41.5 ...
## $ median_price_clean: num 163800 138200 122400 123200 123100 ...
## $ year_month : Date, format: "2010-01-01" "2010-02-01" ...
variabili <- data.frame(
Nome = names(df),
Tipo = sapply(df, class)
)
cat("\n--- Tipi Variabili Aggiornati ---\n")
##
## --- Tipi Variabili Aggiornati ---
print(variabili)
## Nome Tipo
## city city character
## year year integer
## month month integer
## sales sales integer
## volume volume character
## median_price median_price character
## listings listings integer
## months_inventory months_inventory numeric
## volume_clean volume_clean numeric
## median_price_clean median_price_clean numeric
## year_month year_month Date
analisi_possibili <- data.frame(
Nome = names(df),
Analisi_Suggerita = sapply(names(df), function(col_name) {
col_data <- df[[col_name]]
if (grepl("city", col_name)) return("Frequenze / Raggruppamento")
if (col_name %in% c("year", "month") && (is.numeric(col_data) || is.integer(col_data))) return("Analisi temporali / Raggruppamento")
if (inherits(col_data, "Date")) return("Serie Storiche / Trend")
if (col_name %in% c("sales", "listings", "months_inventory") && (is.numeric(col_data) || is.integer(col_data))) return("Analisi quantitativa (media, mediana, ecc.) / Visualizzazioni")
if (col_name %in% c("volume_clean", "median_price_clean") && is.numeric(col_data)) return("Analisi quantitativa (media, mediana, ecc.) / Visualizzazioni")
if (col_name %in% c("volume", "median_price") && is.character(col_data)) return("Tipo originale Character, usare versione _clean per analisi")
if (is.factor(col_data) || is.character(col_data)) return("Frequenze / Tabelle")
return("Verificare tipo e contesto")
})
)
cat("\n--- Analisi Possibili Suggerite ---\n")
##
## --- Analisi Possibili Suggerite ---
print(analisi_possibili)
## Nome
## city city
## year year
## month month
## sales sales
## volume volume
## median_price median_price
## listings listings
## months_inventory months_inventory
## volume_clean volume_clean
## median_price_clean median_price_clean
## year_month year_month
## Analisi_Suggerita
## city Frequenze / Raggruppamento
## year Analisi temporali / Raggruppamento
## month Analisi temporali / Raggruppamento
## sales Analisi quantitativa (media, mediana, ecc.) / Visualizzazioni
## volume Tipo originale Character, usare versione _clean per analisi
## median_price Tipo originale Character, usare versione _clean per analisi
## listings Analisi quantitativa (media, mediana, ecc.) / Visualizzazioni
## months_inventory Analisi quantitativa (media, mediana, ecc.) / Visualizzazioni
## volume_clean Analisi quantitativa (media, mediana, ecc.) / Visualizzazioni
## median_price_clean Analisi quantitativa (media, mediana, ecc.) / Visualizzazioni
## year_month Serie Storiche / Trend
#Calcola gli indici per le variabili numeriche
cat("\n--- Calcolo Indici Descrittivi ---\n")
##
## --- Calcolo Indici Descrittivi ---
numeric_cols_analyze <- names(df)[sapply(df, function(x) is.numeric(x) || is.integer(x))]
for (col in numeric_cols_analyze) {
cat("\n\nIndici per la colonna:", col, "\n")
col_data <- df[[col]]
valid_data <- col_data[!is.na(col_data)]
if(length(valid_data) > 0) {
media <- mean(valid_data)
mediana <- median(valid_data)
moda_table <- table(valid_data)
moda_values <- as.numeric(names(moda_table[moda_table == max(moda_table)]))
moda_print <- if(length(moda_values) == 1) as.character(moda_values) else paste(moda_values, collapse=", ")
dev_std <- sd(valid_data)
varianza <- var(valid_data)
intervallo <- range(valid_data)
skewness_value <- suppressWarnings(e1071::skewness(valid_data))
kurtosis_value <- suppressWarnings(e1071::kurtosis(valid_data))
cat("Media:", media, "\n")
cat("Mediana:", mediana, "\n")
cat("Moda (valore/i più frequente/i):", moda_print, "\n")
cat("Deviazione standard:", dev_std, "\n")
cat("Varianza:", varianza, "\n")
cat("Intervallo (Min, Max):", intervallo[1], ",", intervallo[2], "\n")
cat("Asimmetria (Skewness):", skewness_value, "\n")
cat("Curtosi:", kurtosis_value, "\n")
} else {
cat("Nessun dato numerico valido (non NA) trovato per l'analisi.\n")
}
}
##
##
## Indici per la colonna: year
## Media: 2012
## Mediana: 2012
## Moda (valore/i più frequente/i): 2010, 2011, 2012, 2013, 2014
## Deviazione standard: 1.417169
## Varianza: 2.008368
## Intervallo (Min, Max): 2010 , 2014
## Asimmetria (Skewness): 0
## Curtosi: -1.314137
##
##
## Indici per la colonna: month
## Media: 6.5
## Mediana: 6.5
## Moda (valore/i più frequente/i): 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12
## Deviazione standard: 3.459267
## Varianza: 11.96653
## Intervallo (Min, Max): 1 , 12
## Asimmetria (Skewness): 0
## Curtosi: -1.231612
##
##
## Indici per la colonna: sales
## Media: 192.2917
## Mediana: 175.5
## Moda (valore/i più frequente/i): 124
## Deviazione standard: 79.65111
## Varianza: 6344.3
## Intervallo (Min, Max): 79 , 423
## Asimmetria (Skewness): 0.7136206
## Curtosi: -0.33552
##
##
## Indici per la colonna: listings
## Media: 1738.021
## Mediana: 1618.5
## Moda (valore/i più frequente/i): 1581
## Deviazione standard: 752.7078
## Varianza: 566569
## Intervallo (Min, Max): 743 , 3296
## Asimmetria (Skewness): 0.6454431
## Curtosi: -0.8101534
##
##
## Indici per la colonna: months_inventory
## Media: 9.1925
## Mediana: 8.95
## Moda (valore/i più frequente/i): 8.1
## Deviazione standard: 2.303669
## Varianza: 5.306889
## Intervallo (Min, Max): 3.4 , 14.9
## Asimmetria (Skewness): 0.04071944
## Curtosi: -0.1979448
##
##
## Indici per la colonna: volume_clean
## Media: 37.94758
## Mediana: 35.18
## Moda (valore/i più frequente/i): 40.35
## Deviazione standard: 17.72691
## Varianza: 314.2433
## Intervallo (Min, Max): 9.4 , 93.34
## Asimmetria (Skewness): 0.7401135
## Curtosi: 0.087581
##
##
## Indici per la colonna: median_price_clean
## Media: 131915.5
## Mediana: 134500
## Moda (valore/i più frequente/i): 130000
## Deviazione standard: 25099.47
## Varianza: 629983492
## Intervallo (Min, Max): 10005 , 180000
## Asimmetria (Skewness): -1.131604
## Curtosi: 3.155215
non_numeric_cols <- names(df)[!sapply(df, function(x) is.numeric(x) || is.integer(x) || inherits(x, "Date"))]
if(length(non_numeric_cols) > 0) {
cat("\n--- Frequenze per Colonne Non Numeriche ---\n")
for(col in non_numeric_cols) {
cat("\nFrequenze per:", col, "\n")
print(table(df[[col]], useNA = "ifany"))
}
}
##
## --- Frequenze per Colonne Non Numeriche ---
##
## Frequenze per: city
##
## Beaumont Bryan-College Station Tyler
## 60 60 60
## Wichita Falls
## 60
##
## Frequenze per: volume
##
## 10.46 12.15 12.22 12.32 12.47 13.31 13.56 14.03
## 1 1 1 1 1 1 1 2
## 14.34 14.44 14.47 15.09 15.21 15.22 16.08 16.2
## 1 1 1 1 1 1 1 1
## 16.42 17.27 17.31 17.43 17.55 18.05 18.09 18.19
## 1 1 1 1 1 1 2 1
## 18.25 18.46 19.02 19.06 19.07 19.17 19.26 19.31
## 1 1 1 2 1 1 1 1
## 19.36 19.43 19.47 19.59 20.06 20.23 20.25 20.27
## 1 1 1 1 1 1 1 1
## 20.32 20.35 20.53 20.58 21.05 21.12 21.16 21.37
## 1 1 1 1 1 1 1 1
## 21.44 22.12 22.54 23.05 23.09 23.29 23.51 23.55
## 1 1 1 1 1 1 1 1
## 24.04.00 24.07.00 24.12.00 24.52.00 24.55.00 25.01.00 25.03.00 25.26.00
## 1 1 1 1 1 1 1 1
## 25.27.00 25.42.00 26.26.00 26.28.00 26.37.00 27.31.00 27.35.00 27.36.00
## 1 1 1 1 1 1 1 1
## 27.44.00 27.48.00 27.55.00 28.25.00 28.32.00 28.36.00 28.48.00 28.57.00
## 1 1 1 1 1 1 1 1
## 29.12.00 29.26.00 29.41.00 29.44.00 29.54.00 30.13.00 30.24.00 30.26.00
## 1 1 1 1 1 1 1 1
## 30.35.00 30.39.00 30.44.00 30.51.00 30.53.00 30.57.00 30.59.00 31.08.00
## 1 1 1 1 1 1 1 1
## 31.24.00 31.26.00 31.44.00 31.52.00 32.09.00 32.11.00 32.19.00 32.39.00
## 1 1 1 1 1 1 1 1
## 33.01.00 33.07.00 33.23.00 33.26.00 33.27.00 33.46.00 34.11.00 34.15.00
## 1 1 1 1 1 1 1 1
## 34.17.00 34.41.00 34.57.00 35.14.00 35.22.00 35.23.00 36.13.00 36.26.00
## 1 1 1 1 1 1 1 1
## 36.27.00 36.37.00 36.44.00 36.47.00 36.54.00 37.06.00 37.28.00 37.49.00
## 1 1 1 1 1 1 1 1
## 38.04.00 38.16.00 38.23.00 38.26.00 39.21.00 39.25.00 39.39.00 39.41.00
## 1 1 1 1 1 1 1 1
## 39.49.00 39.56.00 39.59.00 40.35.00 40.51.00 40.58.00 41.09.00 41.21.00
## 1 1 1 3 1 1 1 1
## 41.33.00 41.34.00 41.35.00 41.53.00 41.56.00 42.01.00 42.07.00 42.24.00
## 1 1 1 1 1 1 1 1
## 42.28.00 42.42.00 42.53.00 43.21.00 43.33.00 43.38.00 44.11.00 44.22.00
## 1 2 1 1 1 1 1 1
## 45.06.00 45.09.00 45.34.00 45.53.00 46.24.00 47.19.00 47.26.00 48.13.00
## 1 1 1 1 1 1 1 1
## 48.19.00 48.21.00 49.03.00 49.26.00 49.27.00 49.31.00 49.47.00 51.13.00
## 1 1 1 1 1 1 1 2
## 51.16.00 51.17.00 51.44.00 51.56.00 52.05.00 52.08.00 52.39.00 53.01.00
## 1 1 1 1 1 1 1 1
## 53.2 54.05.00 54.33.00 54.43.00 54.52.00 55.17.00 55.23.00 55.25.00
## 1 1 1 1 1 1 1 1
## 55.48.00 56.01.00 56.44.00 57.14.00 57.19.00 57.36.00 57.41.00 58.43.00
## 1 1 1 1 1 1 1 1
## 59.25.00 59.56.00 61.08.00 61.19.00 61.32.00 62.28.00 62.56.00 63.25.00
## 1 1 1 1 1 1 1 1
## 63.28.00 63.44.00 63.46.00 63.48.00 64.14.00 67.28.00 69.41.00 70.13.00
## 1 1 1 1 2 1 1 1
## 70.16.00 70.39.00 70.41.00 71.04.00 74.49.00 75.14.00 75.39.00 77.56.00
## 1 1 1 1 1 1 1 1
## 78.05.00 78.36.00 79.43.00 80.24.00 9.4 92.07.00 93.23.00 93.34.00
## 1 1 1 1 1 1 1 1
##
## Frequenze per: median_price
##
## 1,00E+05 100700 101400 102300 102500 102900 103800 104700
## 2 2 1 3 2 1 1 2
## 105000 105200 105800 106700 108000 108300 109100 109400
## 1 2 1 1 1 1 1 1
## 110000 111100 112100 113300 113600 114000 114300 115700
## 2 2 1 1 1 1 1 1
## 116000 116500 116700 117500 118200 118800 119200 120000
## 1 1 1 1 1 2 1 1
## 120600 120700 121100 121200 121300 121800 122400 122800
## 1 1 2 1 1 1 1 1
## 123100 123200 123800 124200 124300 126100 126200 127000
## 1 1 1 1 2 1 1 1
## 128100 128200 128800 129100 129200 129400 129600 130000
## 1 1 1 1 1 1 1 4
## 130700 130800 131200 131400 131500 132100 132400 132500
## 2 2 1 1 1 1 1 2
## 132800 132900 133200 133300 133600 133800 134100 134200
## 1 1 2 1 1 1 2 2
## 134300 134400 134500 134700 135000 135100 135300 135700
## 1 1 2 1 1 1 1 2
## 136000 136100 136300 136800 137600 138200 138300 138500
## 1 1 1 1 1 1 1 1
## 138900 139200 139400 139600 140000 140500 140600 140700
## 1 1 1 1 2 1 1 1
## 142000 142200 142400 142700 143100 143600 144000 144100
## 1 1 2 1 1 1 1 2
## 144600 144800 144900 145000 145800 146700 146900 147000
## 2 2 1 1 1 1 1 1
## 147400 147600 147700 147900 148100 148300 148400 148500
## 1 1 1 1 1 1 1 2
## 148700 148900 149100 149300 149400 150000 150200 150700
## 1 1 1 2 1 1 1 1
## 151000 151200 151500 151700 151900 152000 152100 152200
## 1 1 1 1 1 1 2 1
## 152300 152600 153100 153300 153900 154300 154400 155200
## 1 1 2 1 1 1 1 2
## 155300 155500 155600 155700 156200 156400 156500 156600
## 2 1 2 1 1 1 3 1
## 157300 158200 158800 159300 159400 159700 161000 161200
## 1 1 1 1 1 1 2 1
## 161400 161600 163700 163800 165200 165300 166100 167300
## 1 1 1 1 1 1 1 1
## 168500 169500 169600 170000 172200 172600 172800 176100
## 1 1 1 1 1 1 1 1
## 177300 180000 73800 82100 85900 86400 87000 87200
## 1 1 1 1 1 1 1 1
## 87500 88600 89400 90000 90800 91200 91700 92200
## 1 1 1 2 1 1 1 1
## 93000 94000 95000 96000 96700 97500 99300 99600
## 1 1 1 1 1 2 1 1
cat("\n--- Identificazione Max Variabilità e Asimmetria ---\n")
##
## --- Identificazione Max Variabilità e Asimmetria ---
dev_std_values <- numeric(0)
skewness_values <- numeric(0)
for (col in numeric_cols_analyze) {
valid_data <- df[[col]][!is.na(df[[col]])]
if (length(valid_data) > 1) {
dev_std_values[col] <- sd(valid_data)
}
if (length(valid_data) > 0) {
skewness_values[col] <- suppressWarnings(e1071::skewness(valid_data))
}
}
print("Contenuto di dev_std_values:")
## [1] "Contenuto di dev_std_values:"
print(dev_std_values)
## year month sales listings
## 1.417169 3.459267 79.651111 752.707756
## months_inventory volume_clean median_price_clean
## 2.303669 17.726908 25099.471956
print("Contenuto di skewness_values:")
## [1] "Contenuto di skewness_values:"
print(skewness_values)
## year month sales listings
## 0.00000000 0.00000000 0.71362055 0.64544309
## months_inventory volume_clean median_price_clean
## 0.04071944 0.74011347 -1.13160353
if (length(dev_std_values) > 0 && any(!is.na(dev_std_values))) {
max_dev_std_value <- max(dev_std_values, na.rm = TRUE)
max_dev_std_col <- names(dev_std_values)[which.max(dev_std_values)]
cat("\n\nVariabile con la maggiore variabilità (Deviazione Standard):\n")
cat("Colonna:", max_dev_std_col, "\n")
cat("Deviazione standard:", max_dev_std_value, "\n\n")
} else {
cat("\nImpossibile determinare la variabile con massima deviazione standard.\n")
}
##
##
## Variabile con la maggiore variabilità (Deviazione Standard):
## Colonna: median_price_clean
## Deviazione standard: 25099.47
if (length(skewness_values) > 0 && any(!is.na(skewness_values))) {
abs_skewness <- abs(skewness_values)
max_abs_skewness_value <- max(abs_skewness, na.rm = TRUE)
max_skewness_col <- names(skewness_values)[which.max(abs_skewness)]
original_max_skewness_value <- skewness_values[max_skewness_col]
cat("Variabile con la distribuzione più asimmetrica (Skewness Assoluto Massimo):\n")
cat("Colonna:", max_skewness_col, "\n")
cat("Asimmetria (Skewness):", original_max_skewness_value, "(Valore Assoluto Massimo:", max_abs_skewness_value, ")\n")
} else {
cat("\nImpossibile determinare la variabile con massima asimmetria.\n")
}
## Variabile con la distribuzione più asimmetrica (Skewness Assoluto Massimo):
## Colonna: median_price_clean
## Asimmetria (Skewness): -1.131604 (Valore Assoluto Massimo: 1.131604 )
cat("\n--- Analisi Distribuzione Sales Classificate ---\n")
##
## --- Analisi Distribuzione Sales Classificate ---
if ("sales" %in% names(df) && (is.numeric(df$sales) || is.integer(df$sales)) && sum(!is.na(df$sales)) > 0) {
sales_class <- cut(df$sales, breaks = 4,
labels = c("Basso", "Medio", "Alto", "Molto Alto"),
include.lowest = TRUE)
df$sales_class <- sales_class
cat("\nFrequenze per 'sales_class':\n")
print(summary(df$sales_class))
N <- sum(!is.na(df$sales_class))
if (N > 0) {
ni <- table(df$sales_class)
fi <- ni / N
Ni <- cumsum(ni)
Fi <- Ni / N
distr_freq_lungh_sales <- as.data.frame(cbind(ni, fi, Ni, Fi))
print("\nTabella Completa Frequenze (sales_class):")
print(distr_freq_lungh_sales)
barplot(ni, names.arg = names(ni), col = "pink",
main = "Distribuzione Frequenze Assolute (Sales Class)",
xlab = "Categorie di Sales", ylab = "Frequenza Assoluta")
gini.index <- function(x) {
valid_x <- x[!is.na(x)]
if (length(valid_x) == 0) return(NA)
ni <- table(valid_x)
fi <- ni / length(valid_x)
fi2 <- fi^2
J <- length(fi)
if (J <= 1) return(0)
gini <- 1 - sum(fi2)
gini.norm <- gini / ((J - 1) / J)
return(gini.norm)
}
gini_sales_class <- gini.index(df$sales_class)
cat("\nIndice di Gini Normalizzato per 'sales_class':", gini_sales_class, "\n")
} else {
cat("\nNessun dato valido in 'sales_class' per calcolare frequenze o Gini.\n")
}
} else {
warning(" Impossibile classificare e calcolare Gini.")
}
##
## Frequenze per 'sales_class':
## Basso Medio Alto Molto Alto
## 110 71 45 14
## [1] "\nTabella Completa Frequenze (sales_class):"
## ni fi Ni Fi
## Basso 110 0.45833333 110 0.4583333
## Medio 71 0.29583333 181 0.7541667
## Alto 45 0.18750000 226 0.9416667
## Molto Alto 14 0.05833333 240 1.0000000
##
## Indice di Gini Normalizzato per 'sales_class': 0.8851389
cat("\n--- Calcolo Probabilità ---\n")
##
## --- Calcolo Probabilità ---
if (exists("df") && nrow(df) > 0) {
total_rows <- nrow(df)
if ("city" %in% names(df)) {
prob_beaumont <- sum(df$city == "Beaumont", na.rm = TRUE) / total_rows
cat("Probabilità Beaumont:", prob_beaumont, "\n")
} else { cat("Colonna 'city' non trovata.\n") }
if ("month" %in% names(df) && is.numeric(df$month)) {
prob_july <- sum(df$month == 7, na.rm = TRUE) / total_rows
cat("Probabilità Luglio (mese == 7):", prob_july, "\n")
} else { cat("Colonna 'month' non trovata o non numerica.\n") }
if ("month" %in% names(df) && "year" %in% names(df) && is.numeric(df$month) && is.numeric(df$year)) {
prob_dec_2012 <- sum(df$month == 12 & df$year == 2012, na.rm = TRUE) / total_rows
cat("Probabilità Dicembre 2012:", prob_dec_2012, "\n")
} else { cat("Colonne 'month'/'year' non trovate o non numeriche.\n") }
} else { cat("Dataframe 'df' non trovato o vuoto.\n") }
## Probabilità Beaumont: 0.25
## Probabilità Luglio (mese == 7): 0.08333333
## Probabilità Dicembre 2012: 0.01666667
cat("\n--- Creazione Nuove Variabili: Prezzo Medio ed Efficacia Annunci ---\n")
##
## --- Creazione Nuove Variabili: Prezzo Medio ed Efficacia Annunci ---
if ("volume_clean" %in% names(df) && "sales" %in% names(df) && is.numeric(df$volume_clean) && (is.numeric(df$sales) || is.integer(df$sales))) {
df$average_price <- ifelse(!is.na(df$volume_clean) & !is.na(df$sales) & df$sales != 0,
(df$volume_clean * 1000) / df$sales,
NA)
average_price_mean <- mean(df$average_price, na.rm = TRUE)
cat("Media calcolata per average_price :", average_price_mean, "\n")
if (!is.na(average_price_mean)) {
df$average_price[is.na(df$average_price)] <- average_price_mean
cat("NA in 'average_price' sostituiti con la media.\n")
} else {
cat("Media di 'average_price' è NA, impossibile.\n")
}
cat("\nSommario 'average_price' dopo imputazione:\n")
print(summary(df$average_price))
cat("\nPrimi valori 'average_price':\n")
print(head(df$average_price))
} else {
warning("Colonne 'volume_clean' o 'sales' non trovate o non numeriche. Impossibile calcolare 'average_price'.")
}
## Media calcolata per average_price : 195.8766
## NA in 'average_price' sostituiti con la media.
##
## Sommario 'average_price' dopo imputazione:
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 106.3 168.7 196.1 195.9 220.9 313.4
##
## Primi valori 'average_price':
## [1] 197.8313 167.5000 216.5385 196.9500 205.5941 160.7937
if ("sales" %in% names(df) && "listings" %in% names(df) && (is.numeric(df$sales) || is.integer(df$sales)) && (is.numeric(df$listings) || is.integer(df$listings))) {
df$efficacia_annunci <- ifelse(!is.na(df$sales) & !is.na(df$listings) & df$listings > 0,
df$sales / df$listings,
NA)
cat("\nSommario 'efficacia_annunci':\n")
print(summary(df$efficacia_annunci))
cat("\nPrimi valori 'efficacia_annunci':\n")
print(head(df$efficacia_annunci))
} else {
warning("Colonne 'sales' o 'listings' non trovate o non numeriche. Impossibile calcolare 'efficacia_annunci'.")
}
##
## Sommario 'efficacia_annunci':
## Min. 1st Qu. Median Mean 3rd Qu. Max.
## 0.05014 0.08980 0.10963 0.11874 0.13492 0.38713
##
## Primi valori 'efficacia_annunci':
## [1] 0.05414220 0.06809584 0.10775607 0.11709602 0.11405985 0.10482529
required_cols_7 <- c("city", "year", "month", "listings")
if (all(required_cols_7 %in% names(df))) {
summary_listings_dplyr <- df %>%
filter(!is.na(listings)) %>%
group_by(city, year, month) %>%
summarise(
Media_Listings = mean(listings),
DeviazioneStandard_Listings = if(n() >= 2) sd(listings) else NA_real_,
n = n(),
.groups = 'drop'
)
print("Sommario Condizionato per Listings :")
print(head(summary_listings_dplyr))
} else {
missing_cols <- required_cols_7[!required_cols_7 %in% names(df)]
warning(paste("Colonne richieste per l'analisi condizionata mancanti:", paste(missing_cols, collapse=", "), ". Sezione 7 saltata."))
}
## [1] "Sommario Condizionato per Listings :"
## # A tibble: 6 × 6
## city year month Media_Listings DeviazioneStandard_Listings n
## <chr> <int> <int> <dbl> <dbl> <int>
## 1 Beaumont 2010 1 1533 NA 1
## 2 Beaumont 2010 2 1586 NA 1
## 3 Beaumont 2010 3 1689 NA 1
## 4 Beaumont 2010 4 1708 NA 1
## 5 Beaumont 2010 5 1771 NA 1
## 6 Beaumont 2010 6 1803 NA 1
cat("\n--- Altre visualizzazioni ---\n")
##
## --- Altre visualizzazioni ---
required_cols_8 <- c("city", "median_price_clean", "sales", "month", "year", "year_month")
if(all(required_cols_8 %in% names(df))) {
boxplot_sales_city <- ggplot(df, aes(x = city, y = sales)) +
geom_boxplot(fill = "lightgreen", outlier.color = "darkgreen", na.rm = TRUE) +
labs(title = "Distribuzione Valore Totale Vendite per Città",
x = "Città", y = "Valore Vendite") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
print(boxplot_sales_city)
boxplot_sales_year <- ggplot(df, aes(x = factor(year), y = sales)) +
geom_boxplot(fill = "orange", outlier.color = "red", na.rm = TRUE) +
labs(title = "Distribuzione Valore Totale Vendite per Anno",
x = "Anno", y = "Valore Vendite")
print(boxplot_sales_year)
vendite_mensili <- df %>%
filter(!is.na(sales)) %>%
group_by(city, month) %>%
summarise(TotaleVendite = sum(sales, na.rm = TRUE), .groups = 'drop')
if(nrow(vendite_mensili) > 0) {
stacked_barplot_sales_month_city <- ggplot(vendite_mensili, aes(x = factor(month), y = TotaleVendite, fill = city)) +
geom_col(position = "stack") +
labs(title = "Totale Vendite Mensiliper Città ",
x = "Mese", y = "Totale Vendite", fill = "Città") +
scale_x_discrete(limits = factor(1:12)) +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
print(stacked_barplot_sales_month_city)
}
linechart_median_price_time_city <- ggplot(df, aes(x = year_month, y = median_price_clean, color = city)) +
geom_line(na.rm = TRUE, size = 1, alpha=0.8) +
labs(title = "Andamento Prezzo Mediano nel Tempo per Città",
x = "Data", y = "Prezzo Mediano ") +
theme_minimal() +
scale_x_date(date_breaks = "1 year", date_labels = "%Y")
print(linechart_median_price_time_city)
} else {
missing_cols <- required_cols_8[!required_cols_8 %in% names(df)]
warning(paste("Colonne richieste per le visualizzazioni mancanti:", paste(missing_cols, collapse=", "), ". Sezione 8 saltata/parziale."))
}
## 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.
9. Conclusioni
Qualità dei Dati e Impatto Statistico:
str(df)) è la natura testuale (character)
delle variabili volume e median_price. Questa
non è solo una questione di formattazione, ma introduce un
errore di misurazione significativo e rende queste
colonne statisticamente inadatte all’analisi
quantitativa diretta senza una preventiva e accurata pulizia e
conversione numerica.volume nello
script si è rivelato inadeguato, portando alla creazione di variabili
derivate (volume_clean, average_price)
statisticamente non valide e potenzialmente fuorvianti.
Qualsiasi conclusione basata su queste variabili sarebbe infondata dal
punto di vista statistico.median_price
(boxplot, line chart) devono essere interpretate con estrema cautela.
Sebbene ggplot2 possa tentare una coercizione per il
plotting, l’ordine risultante potrebbe essere alfabetico o basato su
regole interne non statisticamente significative per un’analisi
numerica, potenzialmente distorcendo la percezione delle distribuzioni o
dei trend reali.Analisi Descrittiva:
sales, listings,
months_inventory sono state correttamente identificate come
numeriche e analizzate.listings presenta la
deviazione standard più elevata (~753), indicando una forte dispersione
dei valori attorno alla media e quindi una notevole eterogeneità nel
numero di annunci tra le diverse osservazioni (città/mese/anno).sales mostra una chiara
asimmetria positiva (skewness ~0.71). Questo implica che la
distribuzione del numero di vendite ha una coda destra più lunga, con la
presenza di valori relativamente alti che “tirano” la media, la quale
sarà probabilmente superiore alla mediana.efficacia_annunci
(sales/listings), calcolata su dati
affidabili, fornisce una misura interpretabile del tasso di conversione,
con una tendenza centrale che offre un benchmark per la
performance.Numero di Vendite (sales):
sales vs
Anno mostra un aumento del numero mediano di vendite mensili tra
il 2011 e il 2014.sales vs Tempo mostra picchi di vendite regolari
nei mesi primaverili/estivi e cali invernali per tutte le
città.Numero di Annunci (listings):
listings vs Anno per Mese suggerisce una generale
diminuzione del numero medio di annunci disponibili sul mercato
dal 2010/2011 verso il 2014.