The variable city is qualitative on a nominal scale, as
it identifies the city associated with each observation without any
natural ordering.
The variable year is quantitative and continuous, but in
this analysis it is treated as a qualitative ordinal variable, since the
years represent distinct time periods with a natural chronological
ordering.
The variable month is qualitative and nominal with a
cyclical structure. Although it is coded numerically from 1 to 12, these
values identify categories corresponding to the different months of the
year and have a cyclical structure: December and January, for example,
are consecutive months even though they are coded as 12 and 1,
respectively.
The variables sales and listings are
quantitative and discrete, as they represent counts and therefore take
integer values. volume, median price, and
months inventory are instead quantitative and continuous.
All continuous quantitative variables are measured on a ratio scale,
since an absolute zero is defined and ratios between values are
meaningful.
The variables city, year, and
month are mainly used as grouping variables and temporal
dimensions for analysing the other variables. In particular,
city allows us to compare the different local markets,
while year and month allow us to study the
temporal evolution and the seasonal component of the phenomenon.
For quantitative variables, measures of position, variability, and
shape can be calculated. The Gini index can instead be used to assess
distributional heterogeneity, both with respect to the variable
city and with respect to classes constructed from a
quantitative variable.
Temporal evolution can be represented using line charts, while bar charts are useful for comparing mean values across cities. The distributions of quantitative variables can finally be represented using boxplots.
texas <- read.csv('realestate_texas.csv', sep = ',')
attach(texas)
variables <- texas[, c("sales", "volume", "median_price",
"listings", "months_inventory")]
ind.pos <- data.frame(
Min = sapply(variables, min),
First_quartile = sapply(variables, quantile, probs=0.25),
Median = sapply(variables, median),
Mean = sapply(variables, mean),
Third_quartile = sapply(variables, quantile, probs=0.75),
Max = sapply(variables, max)
)
rownames(ind.pos) <- c(
"`sales`",
"`volume`",
"`median price`",
"`listings`",
"`months inventory`"
)
knitr::kable(
ind.pos,
digits = 2,
col.names = c("", "Min", "First quartile",
"Median", "Mean", "Third quartile", "Max"),
align = c("l", "r", "r", "r", "r", "r", "r"))
| Min | First quartile | Median | Mean | Third quartile | Max | |
|---|---|---|---|---|---|---|
sales |
79.00 | 127.00 | 175.50 | 192.29 | 247.00 | 423.00 |
volume |
8.17 | 17.66 | 27.06 | 31.01 | 40.89 | 83.55 |
median price |
73800.00 | 117300.00 | 134500.00 | 132665.42 | 150050.00 | 180000.00 |
listings |
743.00 | 1026.50 | 1618.50 | 1738.02 | 2056.00 | 3296.00 |
months inventory |
3.40 | 7.80 | 8.95 | 9.19 | 10.95 | 14.90 |
CV<-function(x){
return(sd(x)/mean(x)*100)
}
ind.var <- data.frame(
Standard_deviation = sapply(variables, sd),
Coefficient_of_variation = sapply(variables, CV)
)
rownames(ind.var) <- c(
"`sales`",
"`volume`",
"`median price`",
"`listings`",
"`months inventory`"
)
knitr::kable(
ind.var,
digits = 2,
col.names = c("", "Standard deviation", "Coefficient of variation"),
align = c("c", "c"))
| Standard deviation | Coefficient of variation | |
|---|---|---|
sales |
79.65 | 41.42 |
volume |
16.65 | 53.71 |
median price |
22662.15 | 17.08 |
listings |
752.71 | 43.31 |
months inventory |
2.30 | 25.06 |
library(moments)
correct_kurt <- function(x){
return(kurtosis(x)-3)
}
ind.for <- data.frame(
Fisher_Index = sapply(variables, skewness),
Kurtosis = sapply(variables, correct_kurt)
)
rownames(ind.for) <- c(
"`sales`",
"`volume`",
"`median price`",
"`listings`",
"`months inventory`"
)
knitr::kable(
ind.for,
digits = 3,
col.names = c("", "Fisher index", "Kurtosis"),
align = c("c", "c"))
| Fisher index | Kurtosis | |
|---|---|---|
sales |
0.718 | -0.313 |
volume |
0.885 | 0.177 |
median price |
-0.365 | -0.623 |
listings |
0.649 | -0.792 |
months inventory |
0.041 | -0.174 |
Looking at the results obtained, we can make several observations.
The variables median price and
months inventory have very similar means and medians,
suggesting that their distributions are particularly symmetric. Looking
at the measures of shape, we can see that this is indeed the case,
especially for months inventory.
The coefficient of variation allows us to compare the relative
dispersion of the different variables. We can therefore state that
volume has the highest relative variability, while
median price has the lowest relative variability.
All variables except median price have positively skewed
distributions, as indicated by the sign of the Fisher index. Regarding
kurtosis, the distribution of volume is leptokurtic, while
all the others are platykurtic.
The variable with the highest variability is volume,
because it has the highest coefficient of variation. volume
is also the most asymmetric variable, with positive skewness, since it
has the highest absolute value of the Fisher skewness index.
We divide the variable sales into classes. We choose the
number of classes using Sturges’ rule:
N <- round(1+log(length(sales), base = 2))
N
## [1] 9
Therefore, the number of classes is equal to 9.
The table below reports absolute and relative frequencies:
freq_ass<-table(sales_cl)
freq_rel<-table(sales_cl)/length(sales)
distr_frq_sales_cl<-cbind(freq_ass,freq_rel)
knitr::kable(
distr_frq_sales_cl,
digits = 2,
col.names = c("Classes", "Absolute frequency", "Relative frequency"),
align = c("c", "c"))
| Classes | Absolute frequency | Relative frequency |
|---|---|---|
| (78,116] | 45 | 0.19 |
| (116,155] | 50 | 0.21 |
| (155,193] | 46 | 0.19 |
| (193,231] | 27 | 0.11 |
| (231,270] | 23 | 0.10 |
| (270,308] | 26 | 0.11 |
| (308,346] | 10 | 0.04 |
| (346,385] | 9 | 0.04 |
| (385,423] | 4 | 0.02 |
For greater clarity, we now represent the absolute frequencies with a bar chart.
ggplot(data=texas)+
geom_bar(aes(x=sales_cl),
stat='count',
col='black',
fill='blue')+
labs(title = 'Distribution of monthly sales classes',
x='Sales classes',
y='Absolute frequencies')+
theme_classic()
gini.index<-function(x){
ni=table(x)
fi=ni/length(x)
fi2=fi^2
J=length(table(x))
gini=1-sum(fi2)
gini.norm=gini/((J-1)/J)
return(gini.norm)
}
paste("The Gini index is", round(gini.index(sales_cl), digits = 3))
## [1] "The Gini index is 0.954"
The heterogeneity index is very high, indicating a relatively even distribution of the number of sales across the different classes.
We create a new variable representing the average property price by
dividing total sales volume by the number of sales:
mean price = volume/sales x
1,000,000, since volume is expressed in millions of
dollars. We then measure listing effectiveness by introducing a variable
that gives the number of sales per listing: efficacy =
sales/listings.
To comment on and analyse these new variables, we can ask, for example, how their mean values vary across the different cities.
texas %>%
group_by(city) %>%
summarise(
mean_price = mean(mean_price),
efficacy = mean(listings_efficacy)
)%>%
knitr::kable(
digits = 3,
col.names = c("City", "Mean price", "Listing effectiveness"),
align = c("l", "r", "r"))
| City | Mean price | Listing effectiveness |
|---|---|---|
| Beaumont | 146640.4 | 0.106 |
| Bryan-College Station | 183534.3 | 0.147 |
| Tyler | 167676.8 | 0.093 |
| Wichita Falls | 119430.0 | 0.128 |
The table shows that, over the 2010–2014 period, Bryan-College Station had the highest prices and the highest listing effectiveness, while Wichita Falls had the lowest prices and Tyler had the lowest listing effectiveness.
We now calculate the mean values of the variables over the five years considered.
texas %>%
group_by(year) %>%
summarise(
mean_price = mean(mean_price),
efficacy = mean(listings_efficacy)
)%>%
knitr::kable(
digits = 3,
col.names = c("Year", "Mean price", "Listing effectiveness"),
align = c("l", "r", "r"))
| Year | Mean price | Listing effectiveness |
|---|---|---|
| 2010 | 150188.6 | 0.100 |
| 2011 | 148250.6 | 0.093 |
| 2012 | 150898.7 | 0.110 |
| 2013 | 158705.2 | 0.135 |
| 2014 | 163558.7 | 0.157 |
We can therefore observe that, overall across the four cities considered, both mean prices and listing effectiveness appear to have increased over the five years analysed, especially in 2013 and 2014.
We use the dplyr package to perform conditional statistical analyses by city, year, and month. The results are also represented graphically.
sales_city <- texas %>%
group_by(city)%>%
summarise(media=mean(sales),
dev.standard=sd(sales)
)
knitr::kable(
sales_city,
digits = 2,
col.names = c("City", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| City | Mean | Standard deviation |
|---|---|---|
| Beaumont | 177.38 | 41.48 |
| Bryan-College Station | 205.97 | 84.98 |
| Tyler | 269.75 | 61.96 |
| Wichita Falls | 116.07 | 22.15 |
ggplot(sales_city, aes(x = city, y = media)) +
geom_col(fill = 'blue') +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
), width = 0.2) +
labs(
x = "City",
y = "Mean sales",
title = "6.1.1 Mean sales by city"
)
sales_year <- texas %>%
group_by(year)%>%
summarise(media=mean(sales),
dev.standard=sd(sales))
knitr::kable(
sales_year,
digits = 2,
col.names = c("Year", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| Year | Mean | Standard deviation |
|---|---|---|
| 2010 | 168.67 | 60.54 |
| 2011 | 164.12 | 63.87 |
| 2012 | 186.15 | 70.91 |
| 2013 | 211.92 | 84.00 |
| 2014 | 230.60 | 95.51 |
ggplot(sales_year, aes(x = year, y = media)) +
geom_line(col = 'blue') +
geom_point() +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
),
width = 0.1, col='red'
) +
scale_x_continuous(breaks = 2010:2014) +
labs(
x = "Year",
y = "Mean sales",
title = "6.1.2 Mean sales by year"
)
sales_month <- texas %>%
group_by(month)%>%
summarise(media=mean(sales),
dev.standard=sd(sales))
knitr::kable(
sales_month,
digits = 2,
col.names = c("Month", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| Month | Mean | Standard deviation |
|---|---|---|
| 1 | 127.40 | 43.38 |
| 2 | 140.85 | 51.07 |
| 3 | 189.45 | 59.18 |
| 4 | 211.70 | 65.40 |
| 5 | 238.85 | 83.12 |
| 6 | 243.55 | 95.00 |
| 7 | 235.75 | 96.27 |
| 8 | 231.45 | 79.23 |
| 9 | 182.35 | 72.52 |
| 10 | 179.90 | 74.95 |
| 11 | 156.85 | 55.47 |
| 12 | 169.40 | 60.75 |
ggplot(sales_month, aes(x = month, y = media)) +
geom_line(col = 'blue') +
geom_point() +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
),
width = 0.1, col='red'
) +
scale_x_continuous(breaks = 1:12) +
labs(
x = "Month",
y = "Mean sales",
title = "6.1.3 Mean sales by month"
)
Mean sales values differ substantially across cities, with Tyler recording the highest mean and Wichita Falls the lowest. Over time, the annual mean increases, while the monthly pattern reveals a seasonal component, with generally higher values in the summer months.
volume_city<-texas %>%
group_by(city)%>%
summarise(media=mean(volume),
dev.standard=sd(volume))
knitr::kable(
volume_city,
digits = 2,
col.names = c("City", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| City | Mean | Standard deviation |
|---|---|---|
| Beaumont | 26.13 | 6.97 |
| Bryan-College Station | 38.19 | 17.25 |
| Tyler | 45.77 | 13.11 |
| Wichita Falls | 13.93 | 3.24 |
ggplot(volume_city, aes(x = city, y = media)) +
geom_col(fill = 'darkgreen') +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
), width = 0.2) +
labs(
x = "City",
y = "Mean sales volume",
title = "6.2.1 Mean sales volume by city"
)
volume_year<-texas %>%
group_by(year)%>%
summarise(media=mean(volume),
dev.standard=sd(volume))
knitr::kable(
volume_year,
digits = 2,
col.names = c("Year", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| Year | Mean | Standard deviation |
|---|---|---|
| 2010 | 25.68 | 10.80 |
| 2011 | 25.16 | 12.20 |
| 2012 | 29.27 | 14.52 |
| 2013 | 35.15 | 17.93 |
| 2014 | 39.77 | 21.19 |
ggplot(volume_year, aes(x = year, y = media)) +
geom_line(col = 'darkgreen') +
geom_point() +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
),
width = 0.1, col='red'
) +
scale_x_continuous(breaks = 2010:2014) +
labs(
x = "Year",
y = "Mean sales volume",
title = "6.2.2 Mean sales volume by year"
)
volume_month<-texas %>%
group_by(month)%>%
summarise(media=mean(volume),
dev.standard=sd(volume))
knitr::kable(
volume_month,
digits = 2,
col.names = c("Month", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| Month | Mean | Standard deviation |
|---|---|---|
| 1 | 19.00 | 8.37 |
| 2 | 21.65 | 10.09 |
| 3 | 29.38 | 12.02 |
| 4 | 33.30 | 14.52 |
| 5 | 39.70 | 19.02 |
| 6 | 41.30 | 21.08 |
| 7 | 39.12 | 21.41 |
| 8 | 38.01 | 18.05 |
| 9 | 29.60 | 15.22 |
| 10 | 29.08 | 15.13 |
| 11 | 24.81 | 11.15 |
| 12 | 27.09 | 12.57 |
ggplot(volume_month, aes(x = month, y = media)) +
geom_line(col = 'darkgreen') +
geom_point() +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
),
width = 0.1, col='red'
) +
scale_x_continuous(breaks = 1:12) +
labs(
x = "Month",
y = "Mean sales volume",
title = "6.2.3 Mean sales volume by month"
)
The pattern of total sales volume is consistent with that observed
for sales: Tyler has the highest values on average, while
Wichita Falls has the lowest. Here too, an increase is observed over the
period considered, together with marked variability across months.
list_city<-texas %>%
group_by(city)%>%
summarise(media=mean(listings),
dev.standard=sd(listings))
knitr::kable(
list_city,
digits = 2,
col.names = c("City", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| City | Mean | Standard deviation |
|---|---|---|
| Beaumont | 1679.32 | 91.13 |
| Bryan-College Station | 1458.13 | 252.53 |
| Tyler | 2905.05 | 226.75 |
| Wichita Falls | 909.58 | 73.76 |
ggplot(list_city, aes(x = city, y = media)) +
geom_col(fill = 'orange') +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
), width = 0.2) +
labs(
x = "City",
y = "Mean listings",
title = "6.3.1 Mean number of listings by city"
)
list_year<-texas %>%
group_by(year)%>%
summarise(media=mean(listings),
dev.standard=sd(listings))
knitr::kable(
list_year,
digits = 2,
col.names = c("Year", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| Year | Mean | Standard deviation |
|---|---|---|
| 2010 | 1826.00 | 785.02 |
| 2011 | 1849.65 | 780.38 |
| 2012 | 1776.81 | 738.45 |
| 2013 | 1677.60 | 743.52 |
| 2014 | 1560.04 | 706.71 |
ggplot(list_year, aes(x = year, y = media)) +
geom_line(col = 'orange') +
geom_point() +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
),
width = 0.1, col='red'
) +
scale_x_continuous(breaks = 2010:2014) +
labs(
x = "Year",
y = "Mean listings",
title = "6.3.2 Mean number of listings by year"
)
list_month<-texas %>%
group_by(month)%>%
summarise(media=mean(listings),
dev.standard=sd(listings))
knitr::kable(
list_month,
digits = 2,
col.names = c("Month", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| Month | Mean | Standard deviation |
|---|---|---|
| 1 | 1647.05 | 704.61 |
| 2 | 1692.50 | 711.20 |
| 3 | 1756.70 | 727.35 |
| 4 | 1825.70 | 770.43 |
| 5 | 1823.85 | 790.22 |
| 6 | 1833.25 | 811.63 |
| 7 | 1821.20 | 826.72 |
| 8 | 1786.30 | 815.87 |
| 9 | 1748.90 | 802.66 |
| 10 | 1710.35 | 779.16 |
| 11 | 1652.70 | 741.25 |
| 12 | 1557.75 | 692.57 |
ggplot(list_month, aes(x = month, y = media)) +
geom_line(col = 'orange') +
geom_point() +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
),
width = 0.1, col='red'
) +
scale_x_continuous(breaks = 1:12) +
labs(
x = "Month",
y = "Mean listings",
title = "6.3.3 Mean number of listings by month"
)
Regarding the number of active listings, Bryan-College Station has
lower mean values than the other cities. Over time, the annual mean
decreases over the period considered, while the monthly pattern shows
proportionally smaller variations than those observed for
sales and volume.
invent_city<-texas %>%
group_by(city)%>%
summarise(media=mean(months_inventory),
dev.standard=sd(months_inventory))
knitr::kable(
invent_city,
digits = 2,
col.names = c("City", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| City | Mean | Standard deviation |
|---|---|---|
| Beaumont | 9.97 | 1.65 |
| Bryan-College Station | 7.66 | 2.25 |
| Tyler | 11.32 | 1.89 |
| Wichita Falls | 7.82 | 0.78 |
ggplot(invent_city, aes(x = city, y = media)) +
geom_col(fill = 'purple') +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
), width = 0.2) +
labs(
x = "City",
y = "Mean months of inventory",
title = "6.4.1 Mean months of inventory by city"
)
invent_year<-texas %>%
group_by(year)%>%
summarise(media=mean(months_inventory),
dev.standard=sd(months_inventory))
knitr::kable(
invent_year,
digits = 2,
col.names = c("Year", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| Year | Mean | Standard deviation |
|---|---|---|
| 2010 | 9.97 | 2.08 |
| 2011 | 10.90 | 2.07 |
| 2012 | 9.88 | 1.61 |
| 2013 | 8.15 | 1.69 |
| 2014 | 7.06 | 1.75 |
ggplot(invent_year, aes(x = year, y = media)) +
geom_line(col = 'purple') +
geom_point() +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
),
width = 0.1, col='red'
) +
scale_x_continuous(breaks = 2010:2014) +
labs(
x = "Year",
y = "Mean months of inventory",
title = "6.4.2 Mean months of inventory by year"
)
invent_month<-texas %>%
group_by(month)%>%
summarise(media=mean(months_inventory),
dev.standard=sd(months_inventory))
knitr::kable(
invent_month,
digits = 2,
col.names = c("Month", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| Month | Mean | Standard deviation |
|---|---|---|
| 1 | 8.84 | 1.97 |
| 2 | 9.06 | 1.98 |
| 3 | 9.40 | 2.06 |
| 4 | 9.72 | 2.24 |
| 5 | 9.68 | 2.38 |
| 6 | 9.70 | 2.41 |
| 7 | 9.62 | 2.50 |
| 8 | 9.39 | 2.45 |
| 9 | 9.19 | 2.52 |
| 10 | 8.94 | 2.44 |
| 11 | 8.66 | 2.37 |
| 12 | 8.12 | 2.27 |
ggplot(invent_month, aes(x = month, y = media)) +
geom_line(col = 'purple') +
geom_point() +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
),
width = 0.1, col='red'
) +
scale_x_continuous(breaks = 1:12) +
labs(
x = "Month",
y = "Mean months of inventory",
title = "6.4.3 Mean months of inventory by month"
)
The variable months inventory has relatively low mean
values in Bryan-College Station and shows a decrease in the annual mean
starting in 2011. The monthly pattern has seasonal characteristics, less
pronounced than those observed for sales and
volume, but more pronounced than for
listings.
median_city<-texas %>%
group_by(city)%>%
summarise(media=mean(median_price),
dev.standard=sd(median_price))
knitr::kable(
median_city,
digits = 2,
col.names = c("City", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| City | Mean | Standard deviation |
|---|---|---|
| Beaumont | 129988.3 | 10104.99 |
| Bryan-College Station | 157488.3 | 8852.24 |
| Tyler | 141441.7 | 9336.54 |
| Wichita Falls | 101743.3 | 11320.03 |
ggplot(median_city, aes(x = city, y = media)) +
geom_col(fill = 'lightgreen') +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
), width = 0.2) +
labs(
x = "City",
y = "Mean median price",
title = "6.5.1 Mean median price by city"
)
median_year<-texas %>%
group_by(year)%>%
summarise(media=mean(median_price),
dev.standard=sd(median_price))
knitr::kable(
median_year,
digits = 2,
col.names = c("Year", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| Year | Mean | Standard deviation |
|---|---|---|
| 2010 | 130191.7 | 21821.76 |
| 2011 | 127854.2 | 21317.80 |
| 2012 | 130077.1 | 21431.52 |
| 2013 | 135722.9 | 21708.08 |
| 2014 | 139481.2 | 25625.41 |
ggplot(median_year, aes(x = year, y = media)) +
geom_line(col = 'lightgreen') +
geom_point() +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
),
width = 0.1, col='red'
) +
scale_x_continuous(breaks = 2010:2014) +
labs(
x = "Year",
y = "Mean median price",
title = "6.5.2 Mean median price by year"
)
median_month<-texas %>%
group_by(month)%>%
summarise(media=mean(median_price),
dev.standard=sd(median_price))
knitr::kable(
median_month,
digits = 2,
col.names = c("Month", "Mean", "Standard deviation"),
align = c("l", "c", "c"))
| Month | Mean | Standard deviation |
|---|---|---|
| 1 | 124250 | 25151.28 |
| 2 | 130075 | 22822.59 |
| 3 | 127415 | 23442.03 |
| 4 | 131490 | 21458.40 |
| 5 | 134485 | 18796.26 |
| 6 | 137620 | 19231.02 |
| 7 | 134750 | 21944.78 |
| 8 | 136675 | 22488.38 |
| 9 | 134040 | 24344.10 |
| 10 | 133480 | 26358.07 |
| 11 | 134305 | 24691.47 |
| 12 | 133400 | 22809.76 |
ggplot(median_month, aes(x = month, y = media)) +
geom_line(col = 'lightgreen') +
geom_point() +
geom_errorbar(
aes(
ymin = media - dev.standard,
ymax = media + dev.standard
),
width = 0.1, col='red'
) +
scale_x_continuous(breaks = 1:12) +
labs(
x = "Month",
y = "Mean median price",
title = "6.5.3 Mean median price by month"
)
Median price has considerably higher mean values in Bryan-College Station and lower values in Wichita Falls. Over the period considered, the annual mean also increases, while the seasonal pattern appears somewhat less pronounced than in the previous cases.
ggplot(data=texas)+
geom_boxplot(aes(x=city, y=median_price), fill='lightblue')+
labs(x='City', y='Median price', title = '7.1 Boxplot of median price by city')
texas3 <- data.frame(texas)
texas3$year <- as.character(texas$year)
Chart 7.1 highlights a clear difference in median price levels across the four cities. Bryan-College Station has the highest values, followed by Tyler, Beaumont, and finally Wichita Falls. Regarding dispersion, Wichita Falls has the widest interquartile range, while Bryan-College Station has a relatively more concentrated central distribution. There are also outliers for Beaumont, Wichita Falls, and Bryan-College Station.
ggplot(data=texas3)+
geom_boxplot(aes(x=year, y=volume, fill=city))+
labs(x='Years', y='Total sales volume (in millions of $)',
title = '7.2 Boxplot of total sales volume by year and city')
Chart 7.2 shows strong variability in total sales volume, which differs across cities and years. In several years, Bryan-College Station and Tyler have wider interquartile ranges, indicating greater dispersion of monthly values, while Wichita Falls generally shows lower variability. A shift towards higher values in later years can also be observed, together with an outlier for Beaumont in 2012.
ggplot(data=texas)+
geom_bar(aes(x=month, y=volume,
fill=city),
position = 'stack',
stat='identity',
col='black')+
facet_wrap(year, ncol=2)+
labs(title = '7.3 Total sales volume by month, year, and city',
x='Months',
y='Total sales volume (in millions of $)')+
scale_x_continuous(breaks=1:12)+
theme_classic()
Chart 7.3 shows the seasonal component of total sales volume and, at the
same time, the contribution of the individual cities. Overall values
tend to be higher in the spring and summer months and lower in the
winter months. The year 2010 shows a partially different pattern, with
the peak concentrated between April and June.
ggplot(data=texas)+
geom_bar(aes(x=month, y=volume,
fill=city),
position = 'fill',
stat='identity',
col='black')+
facet_wrap(year, ncol=2)+
labs(title = '7.4 Normalised total sales volume by month, year, and city',
x='Months',
y='Percentage share of total')+
scale_x_continuous(breaks=1:12)+
theme_classic()
The normalisation in 7.4 makes it possible to compare the relative contribution of the different cities independently of the absolute sales volume. Tyler and Bryan-College Station generally account for the largest shares of the total volume, while Beaumont and especially Wichita Falls contribute smaller shares. The proportions are fairly stable across the years.
texas2 <- data.frame(texas)
texas2$year <- rep(seq(2010+1/24,2014+23/24,1/12),times=4)
texas2$month <- NULL
ggplot(texas2, aes(x = year, y = sales, color = city, group = city)) +
geom_line(linewidth = 1) +
geom_point() +
labs(
x = "Year",
y = "Number of sales",
title = "7.5 Sales trend by city"
) +
scale_x_continuous(breaks = 2010:2014)
Finally, chart 7.5 shows the evolution of sales in the individual cities over the entire period considered. Beaumont, Bryan-College Station, and Tyler show an overall increasing trend, despite marked seasonal fluctuations. Wichita Falls remains at lower levels and does not show a clearly increasing or decreasing overall trend.
The analysis reveals a marked seasonal component in sales, with generally higher values in the late spring and summer months and lower values in the winter months. This pattern is present in most years, although 2010 is an exception, and it affects the individual cities to different degrees.
A second relevant feature is the strong heterogeneity among local markets. Tyler and Bryan-College Station generally show higher levels of both the number and value of sales, while Wichita Falls remains at the lowest levels. The disaggregated analysis also shows that the growth observed at the aggregate level is not uniform across all cities.
Over the period considered, the number of sales, sales volume, and median price show an overall increase starting in 2011, while the number of listings and months of inventory decrease. However, the high standard deviations observed in many analyses indicate that aggregate means do not fully represent the variability of individual markets. For this reason, analysis by city is essential for correctly interpreting the observed dynamics.
Based on the results obtained, Texas Realty Insights should take the seasonal component of sales into account when planning and interpreting data, avoiding direct comparisons between periods belonging to different seasons without considering this effect. In addition, the marked differences observed among local markets suggest complementing aggregate indicators with monitoring and analysis activities specific to each city.