Una volta installati i pacchetti, importo i pacchetti necessari all’analisi:
library(ggplot2)
library(dplyr)
library(moments)
library(stringr)
library(rstudioapi)
Importo il database e verifico se le prime righe del dataset sono state caricate correttamente
texas <- read.csv("Real Estate Texas.csv")
head(texas, 5)
## 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
Il dataframe è composto da 8 variabili e 240 osservazioni:
Character) Qualitativa
nominale. Rappresenta le città in cui sono stati raccolti i
dati;Integer) Variabile
quantitativa, ma in questo caso qualitativa ordinale. Si riferisce
all’anno;Integer) Qualitativa
nominale ciclica Poché presenta 12 livelli. Si riferisce ai
mesi;Integer) Quantitativa
discreta. Mostra il numero di vendite immobiliari effettuate in un
determinato mese/anno;Integer) Quantitativa
continua. Rappresenta il volume totale delle vendite in milioni di
dollari (in M$);Numeric)
Quantitativa continua. Indica il prezzo mediano delle proprietà
vendute in un determinato mese/anno (in $);Numeric) Quantitativa
discreta. Rappresenta il numero di annunci immobiliari attivi in un
determinato mese/anno;Numeric)
Quantitativa continua. Mostra nei mesi e anni il tempo che
intercorre tra la vendita e l’inserzione pertanto è un indicatore
temporale.Per poter analiizare gli indici di
posizione,variazione,
forma e distribuzione di frequenza
devo scegliere delle variabili quantitative pertanto le variabili sono:
sales, volume, median_price,
listings e months_inventory.
Per prima cosa definisco v.coeff per calcolare il
coefficiente di variazione:
v.coeff <- function(x){
return(sd(x)/mean(x)*100)
}
Definisco quindi un nuovo dataframe newdata.df dove vi
sono gli indici. La funzione attach() mi permette di
accedere facilmente alle variabili:
attach(texas)
texas.colnames <- colnames(texas)[4:8]
indexes = c("min", "1st quartile", "median", "3rd quartile", "max", "range",
"IQR", "mean", "std.dev", "var.coeff", "skewness", "kurtosis")
newdata.df <- data.frame(matrix(nrow = 0, ncol = length(indexes)))
colnames(newdata.df) = indexes
for (obj.name in texas.colnames) {
obj <- pull(texas,obj.name)
quartiles = as.numeric(quantile(obj))
df <- texas %>%
summarise(range=max(obj)-min(obj),
IQR=IQR(obj),
mean=mean(obj),
dev.st=sd(obj),
var.coeff=v.coeff(obj),
skewness=skewness(obj),
kurtosis=kurtosis(obj)-3)
row = c(quartiles,as.numeric(df))
newdata.df <- rbind(newdata.df, row)
}
newdata.df <- cbind(texas.colnames,newdata.df)
colnames(newdata.df) = c("variable", indexes)
newdata.df
## variable min 1st quartile median 3rd quartile max
## 1 sales 79.000 127.0000 175.5000 247.000 423.000
## 2 volume 8.166 17.6595 27.0625 40.893 83.547
## 3 median_price 73800.000 117300.0000 134500.0000 150050.000 180000.000
## 4 listings 743.000 1026.5000 1618.5000 2056.000 3296.000
## 5 months_inventory 3.400 7.8000 8.9500 10.950 14.900
## range IQR mean std.dev var.coeff skewness
## 1 344.000 120.0000 192.29167 79.651111 41.42203 0.71810402
## 2 75.381 23.2335 31.00519 16.651447 53.70536 0.88474203
## 3 106200.000 32750.0000 132665.41667 22662.148687 17.08218 -0.36455288
## 4 2553.000 1029.5000 1738.02083 752.707756 43.30833 0.64949823
## 5 11.500 3.1500 9.19250 2.303669 25.06031 0.04097527
## kurtosis
## 1 -0.3131764
## 2 0.1769870
## 3 -0.6229618
## 4 -0.7917900
## 5 -0.1744475
Scelgo la variabile city e mi determino la distribuzione di frequenza
N=dim(texas)[1]
table(texas["city"])
## city
## Beaumont Bryan-College Station Tyler
## 60 60 60
## Wichita Falls
## 60
freq_ass=table(texas$city)
freq_rel=table(texas$city)/N
distr_freq_CITY=cbind(freq_ass,freq_rel)
distr_freq_CITY
## freq_ass freq_rel
## Beaumont 60 0.25
## Bryan-College Station 60 0.25
## Tyler 60 0.25
## Wichita Falls 60 0.25
Possiamo dedurre che ci troviamo davanti ad una distribuzione quadrimodale, poiché le frequenze sono le stesse per tutte le città. Le osservazioni sono perfettamente distribuite sulle 4 categorie e quindi ci si aspetta che l’indice di gini per la variabile city sia pari a 1.
Esprimo alcune considerazioni:
volume ha il coefficiente di variazione più alto, il
che significa che ha la maggiore variazione;
volume ha anche una curtosi positiva, il che
significa che è leptocurtico;
Le altre variabili analizzate hanno una curtosi negativa, pertanto sono platicurtiche;
median_price ha una asimmetria negativa, visibile
come una coda sinistra più lunga;
Tutte le altre variabili hanno una asimmetria positiva, visibile come una coda destra più lunga;
volume ha la maggiore
asimmetria.
Definisco la funzione gini.index e verifichiamo se è
vero cià che abbiamo detto nel punto 2:
gini.index <- function(x){
J <- length(table(x))
fi2 <- (table(x)/length(x))^2
G <- 1 - sum(fi2)
gini <- G / ((J-1)/J)
return(gini)
}
gini.index(city)
## [1] 1
##5 5. “Indovina” l’indice di gini per la variabile city.
Come ipotizzato in precedenza (punto 2) sulla
variabile city l’indice di Gini è pari ad 1.
Dividiamo la variabile volume in classi, quindi
determino la distribuzione di frequenza e l’indice di Gini:
volume_classes <- cut(volume,
breaks = seq(min(volume), max(volume),
(max(volume)-min(volume))/15))
ni <- table(volume_classes)
fi <- ni/N
Ni <- cumsum(ni)
Fi <- Ni/N
volume_freq_distr <- as.data.frame(cbind(ni,fi,Ni,Fi))
volume_freq_distr
## ni fi Ni Fi
## (8.17,13.2] 24 0.100000000 24 0.1000000
## (13.2,18.2] 42 0.175000000 66 0.2750000
## (18.2,23.2] 26 0.108333333 92 0.3833333
## (23.2,28.3] 30 0.125000000 122 0.5083333
## (28.3,33.3] 27 0.112500000 149 0.6208333
## (33.3,38.3] 22 0.091666667 171 0.7125000
## (38.3,43.3] 17 0.070833333 188 0.7833333
## (43.3,48.4] 9 0.037500000 197 0.8208333
## (48.4,53.4] 17 0.070833333 214 0.8916667
## (53.4,58.4] 5 0.020833333 219 0.9125000
## (58.4,63.4] 7 0.029166667 226 0.9416667
## (63.4,68.5] 5 0.020833333 231 0.9625000
## (68.5,73.5] 4 0.016666667 235 0.9791667
## (73.5,78.5] 2 0.008333333 237 0.9875000
## (78.5,83.5] 2 0.008333333 239 0.9958333
gini.index(volume_classes)
## [1] 0.9614769
Effettuo un plotting mediante un istogramma delle
volume_classes:
barplot(volume_freq_distr$ni,
xlab = "",
ylab = "",
ylim = c(0,50),
main = "Volume classes frequencies",
col = "blue",
space = 0.1,
names.arg = rownames(volume_freq_distr),
las = 2)
##6. Qual è la probabilità che presa una riga a caso di questo dataset essa riporti la città “Beaumont”? E la probabilità che riporti il mese di Luglio? E la probabilità che riporti il mese di dicembre 2012?
Facciamo alcuni test di probabilità. Prima possiamo indagare le probabilità di occorrenze di Beaumont. Poiché la distribuzione è quadrimodale, possiamo prevedere un risultato di 0,25:
Beaumont_ext = filter(texas, city == "Beaumont")
Beaumont_N = dim(Beaumont_ext)[1]
Beaumont_prob = Beaumont_N/N
Beaumont_prob
## [1] 0.25
Adesso possiamo fare lo stesso con un mese, ad esempio Luglio, che è
rappresentato da 7 nella variabile month:
July_ext = filter(texas, month == 7)
July_N = dim(July_ext)[1]
July_prob = July_N/N
July_prob
## [1] 0.08333333
Combino ora due variabili come come da traccia dicembre e 2012
rispettivamente per le variabili month e
year:
Dec12_ext = filter(texas, year == 2012, month == 12)
Dec12_N = dim(Dec12_ext)[1]
Dec12_prob = Dec12_N/N
Dec12_prob
## [1] 0.01666667
Rendiamo il nostro dataframe più completo con nuove variabili:
avg_price: prezzo medio, definito con il rapporto
tra volume (in $) e sales;
sales_eff: fficienza delle vendite, che mostra
l’efficacia delle offerte di vendita, definita come il rapporto tra
sales e listings.
Creiamo un nuovo Dataframe texas_complete:
avg_price <- (volume*1000000)/sales
sales_eff <- sales/listings
texas_complete <- cbind(texas, avg_price, sales_eff)
head(texas_complete, 5)
## 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
## avg_price sales_eff
## 1 170626.5 0.05414220
## 2 163796.3 0.06809584
## 3 157697.8 0.10775607
## 4 134095.0 0.11709602
## 5 142737.6 0.11405985
Per l’ultima variabile, 1 rappresenta la massima efficienza delle vendite, 0 la minima; La massima efficienza delle vendite è stata osservata in:
Possiamo anche utilizzare il pacchetto dplyr per
riassumere alcune informazioni dal Dataframe. Proviamolo
texas_complete %>%
group_by(city) %>%
summarise(year = 2014, mean = mean(sales_eff),
std.dev = sd(sales_eff))
## # A tibble: 4 × 4
## city year mean std.dev
## <chr> <dbl> <dbl> <dbl>
## 1 Beaumont 2014 0.106 0.0267
## 2 Bryan-College Station 2014 0.147 0.0729
## 3 Tyler 2014 0.0935 0.0235
## 4 Wichita Falls 2014 0.128 0.0247
La visualizzazione può essere molto utile durante l’analisi statistica, in particolare per fare confronti. Possiamo confrontare il median_price tra le città utilizzando un boxplot:
cities = unique(city)
ggplot(data = texas_complete)+
geom_boxplot(aes(x=median_price/1000,
y=city),
fill = "orange",
colour = "red",
outlier.colour = "red",
outlier.shape = 1,
outlier.size = 2.5,
linewidth = 0.75,
outlier.stroke = 0.75,
)+
scale_y_discrete(labels = cities)+
scale_x_continuous(breaks = seq(70,180,10),
guide = guide_axis(angle = 45))+
labs(x="Median sale price (k$)",
y="City",
title = "Median sale price per city")+
theme_minimal()+
theme(plot.title = element_text(hjust = 0.5))
Possiamo osservare che Bryan-College Station ha il
prezzo mediano di vendita più alto, mentre Wichita
Falls il più basso. Tutte le città hanno una distribuzione
asimmetrica per il median_price. Tyler è
l’unica senza outlier.
Possiamo utilizzare il boxplot anche per confrontare il
volume tra le città:
ggplot(data = texas_complete)+
geom_boxplot(aes(x=volume,
y=city,
fill=factor(year)),)+
scale_fill_manual(
name = "Year",
breaks = factor(unique(year)),
values = c("lightblue", "lightblue1", "lightblue2",
"lightblue3", "lightblue4"),
labels = as.character(unique(year))
)+
scale_y_discrete(labels=cities)+
scale_x_continuous(breaks = seq(10,100,10))+
labs(x="Total value of sales (M$)",
y="City",
title = "Total value of sales per year")+
theme_minimal()+
theme(plot.title = element_text(hjust = 0.5))
Dal grafico possiamo dedurre che:
Tyler ha la mediana più alta del valore totale delle vendite;
Wichita Falls ha la mediana più bassa del valore totale delle vendite;
Wichita Falls è anche quasi costante, a differenza delle altre città.
L’istogramma può essere utilizzato per confrontare il
Volumera le città per mese. Per prima cosa, utilizziamo un
istogramma stacked (ossia impilato):
ggplot(data = texas_complete)+
geom_col(aes(x = factor(month.abb[month], levels = month.abb),
y = volume,
fill = city))+
labs(x = "Month",
y = "Total value of sales (M$)",
title = "Total value of sales per month")+
facet_wrap(~year,nrow = 1)+
scale_x_discrete(guide = guide_axis(angle = 90))+
scale_fill_discrete(name = "City",
labels = cities)+
theme_minimal()+
theme(legend.position = "bottom",
axis.text.x = element_text(size = 6),
plot.title = element_text(hjust = 0.5))
Effettuo una normalizzazione:
ggplot(data = texas_complete)+
geom_col(aes(x = factor(month.abb[month], levels = month.abb),
y = volume,
fill = city),
position = "fill")+
labs(x = "Month",
y = "Total value of sales (M$)",
title = "Total value of sales per month")+
facet_wrap(~year,nrow = 1)+
scale_x_discrete(guide = guide_axis(angle = 90))+
scale_fill_discrete(name = "City",
labels = cities)+
theme_minimal()+
theme(legend.position = "bottom",
axis.text.x = element_text(size = 6),
plot.title = element_text(hjust = 0.5))
Il valore totale delle vendite aumenta nel corso degli anni, principalmente grazie al contributo del valore totale delle vendite di Tyler e del prezzo mediano di Bryan-College Station, come visto in precedenza.
L’ultimo confronto che possiamo effettuare riguarda il median_price per mese tra le città durante l’anno. In questo caso, utilizzeremo un grafico a linee:
ggplot(data = texas_complete)+
geom_line(aes(x = factor(month.abb[month], levels = month.abb),
y=median_price/1000,
group=city,
col=city),
lwd=1
)+
facet_wrap(~year, nrow = 1)+
scale_x_discrete(guide = guide_axis(angle = 90))+
scale_color_discrete(name = "City")+
labs(x="Month",
y="Median sale price (k$)",
title = "Median sale price per month")+
theme_minimal()+
theme(legend.position = "bottom",
axis.text.x = element_text(size = 6),
plot.title = element_text(hjust = 0.5))
Ne risulta che il median_price è rimasto quasi costante
a Beaumont e Wichita Falls, mentre c’è
stato un aumento a Bryan-College Station e
Tyler, il che contribuisce ai risultati visti in
precedenza:
ggplot(data = texas_complete)+
geom_line(aes(x = factor(month.abb[month], levels = month.abb),
y=sales,
group=city,
col=city),
lwd=1
)+
facet_wrap(~year, nrow = 1)+
scale_x_discrete(guide = guide_axis(angle = 90))+
scale_color_discrete(name = "City")+
labs(x="Month",
y="Sales",
title = "Sales per month")+
theme_minimal()+
theme(legend.position = "bottom",
axis.text.x = element_text(size = 6),
plot.title = element_text(hjust = 0.5))