Is there a difference in the price of unfurnished, semi-furnished and furnished houses?
The better furnished a house is, the higher the price.
# Load the dataset
housing <- read.table("Housing.csv",
header = TRUE,
sep = ",")
# Convert character columns to factors
housing$mainroad <- factor(housing$mainroad,
levels = c("no", "yes"),
labels = c("no", "yes"))
housing$guestroom <- factor(housing$guestroom,
levels = c("no", "yes"),
labels = c("no", "yes"))
housing$basement <- factor(housing$basement,
levels = c("no", "yes"),
labels = c("no", "yes"))
housing$hotwaterheating <- factor(housing$hotwaterheating,
levels = c("no", "yes"),
labels = c("no", "yes"))
housing$airconditioning <- factor(housing$airconditioning,
levels = c("no", "yes"),
labels = c("no", "yes"))
housing$prefarea <- factor(housing$prefarea,
levels = c("no", "yes"),
labels = c("no", "yes"))
housing$furnishingstatus <- factor(housing$furnishingstatus,
levels = c("unfurnished", "semi-furnished", "furnished"),
labels = c("unfurnished", "semi-furnished", "furnished"))
# Explore the dataset
head(housing)
str(housing)
'data.frame': 545 obs. of 13 variables:
$ price : int 13300000 12250000 12250000 12215000 11410000 10850000 10150000 10150000 9870000 9800000 ...
$ area : int 7420 8960 9960 7500 7420 7500 8580 16200 8100 5750 ...
$ bedrooms : int 4 4 3 4 4 3 4 5 4 3 ...
$ bathrooms : int 2 4 2 2 1 3 3 3 1 2 ...
$ stories : int 3 4 2 2 2 1 4 2 2 4 ...
$ mainroad : Factor w/ 2 levels "no","yes": 2 2 2 2 2 2 2 2 2 2 ...
$ guestroom : Factor w/ 2 levels "no","yes": 1 1 1 1 2 1 1 1 2 2 ...
$ basement : Factor w/ 2 levels "no","yes": 1 1 2 2 2 2 1 1 2 1 ...
$ hotwaterheating : Factor w/ 2 levels "no","yes": 1 1 1 1 1 1 1 1 1 1 ...
$ airconditioning : Factor w/ 2 levels "no","yes": 2 2 1 2 2 2 2 1 2 2 ...
$ parking : int 2 3 2 3 2 2 2 0 2 1 ...
$ prefarea : Factor w/ 2 levels "no","yes": 2 1 2 2 1 2 2 1 2 2 ...
$ furnishingstatus: Factor w/ 3 levels "unfurnished",..: 3 3 2 3 3 2 2 1 3 1 ...
I will use the variables, “price” and “furnishingstatus” to see if the furnishing status of a house has a significant effect on its price.
“Housing Prices Dataset” dataset sourced from https://www.kaggle.com/datasets/yasserh/housing-prices-dataset
# Explore the dataset
summary(housing)
price area bedrooms bathrooms stories mainroad guestroom basement
Min. : 1750000 Min. : 1650 Min. :1.000 Min. :1.000 Min. :1.000 no : 77 no :448 no :354
1st Qu.: 3430000 1st Qu.: 3600 1st Qu.:2.000 1st Qu.:1.000 1st Qu.:1.000 yes:468 yes: 97 yes:191
Median : 4340000 Median : 4600 Median :3.000 Median :1.000 Median :2.000
Mean : 4766729 Mean : 5151 Mean :2.965 Mean :1.286 Mean :1.806
3rd Qu.: 5740000 3rd Qu.: 6360 3rd Qu.:3.000 3rd Qu.:2.000 3rd Qu.:2.000
Max. :13300000 Max. :16200 Max. :6.000 Max. :4.000 Max. :4.000
hotwaterheating airconditioning parking prefarea furnishingstatus
no :520 no :373 Min. :0.0000 no :417 unfurnished :178
yes: 25 yes:172 1st Qu.:0.0000 yes:128 semi-furnished:227
Median :0.0000 furnished :140
Mean :0.6936
3rd Qu.:1.0000
Max. :3.0000
describe(housing)
describeBy(housing$price, housing$furnishingstatus)
Descriptive statistics by group
group: unfurnished
------------------------------------------------------------------------------------------
group: semi-furnished
------------------------------------------------------------------------------------------
group: furnished
Although the lowest price doesn’t really change with a better furnishing status, we can see that the highest price does which is also reflected in an increasing median and mean price.
# Plot prices by furnishing status
ggboxplot(housing,
x = "furnishingstatus",
y = "price",
xlab = "Furnishing Status",
ylab = "Price")
The boxplot again confirms the previous observation that the median price seems to go up with a better furnishing status.
I will need the One-way ANOVA or alternatively the Kruskal-Wallis Rank Sum Test since my hypothesis is concerned with the difference between the house prices from three populations from independent samples, i.e. the price of unfurnished, the price of semi-furnished and the price of furnished houses.
Yes, the variable “price” is numeric.
Yes, the data for the different furnishing status are independent populations.
# Test normality in both populations
housing %>%
group_by(furnishingstatus) %>%
shapiro_test(price)
NA
We reject H_0, i.e. that the distribution of the price is normal for every furnishing status at p < 0.001 and accept H_1, i.e. that the distribution of the price is NOT normal for every furnishing status.
# Test if the variance of the price is the same within all groups
leveneTest(housing$price, group = housing$furnishingstatus)
Levene's Test for Homogeneity of Variance (center = median)
Df F value Pr(>F)
group 2 7.4278 0.000657 ***
542
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
We reject H_0, i.e. that the population variances are the same and accept H_1 that the population variances are NOT the same.
Since both the normality and the homoscedasticity assumptions needed for the One-way ANOVA do not hold, I will continue by using the alternative non-parametric statistical test, the Kruskal-Wallis Rank Sum Test.
# Test the hypothesis that there is no significant difference in the median price between the furnishing status
kruskal.test(price ~ furnishingstatus,
data = housing)
Kruskal-Wallis rank sum test
data: price by furnishingstatus
Kruskal-Wallis chi-squared = 69.583, df = 2, p-value = 7.767e-16
We reject H_0 at p < 0.0001 and accept H_1 that at least one distribution location of house prices is NOT the same the other furnishing status.
# Determine the effect size
kruskal_effsize(price ~ furnishingstatus,
data = housing)
NA
According to the effect size ranges from Field, 2013, the effect size is moderate.
# Plot all results
pwc <- housing %>%
wilcox_test(price ~ furnishingstatus,
paired = FALSE,
p.adjust.method = "bonferroni")
Kruskal_results <- kruskal_test(price ~ furnishingstatus,
data = housing)
pwc <- pwc %>%
add_y_position(fun = "max", step.increase = 0.20)
ggboxplot(housing, x = "furnishingstatus", y = "price", add = "point") +
stat_pvalue_manual(pwc, hide.ns = FALSE) +
stat_summary(fun = median, geom = "point", shape = 16, size = 4,
aes(group = furnishingstatus), color = "darkred",
position = position_dodge(width = 0.8)) +
stat_summary(fun = median, color = "darkred",
position = position_dodge(width = 0.8),
geom = "text", vjust = -0.5, hjust = -1,
aes(label = round(after_stat(y), digits = 2), group = furnishingstatus)) +
labs(subtitle = get_test_label(Kruskal_results, detailed = TRUE),
caption = get_pwc_label(pwc))
We found that the distribution of house prices differs for at least one of the furnishing status (𝜒2 = 69.58, 𝑝 < 0.0001), the effect size was moderate (𝜂2 = 0.125). Post-Hoc tests revealed differences for two furnishing status (𝑝 < 0.0001), with the exception of semi-furnished vs. furnished houses.