Question: Are average resale prices different between two flat types in this teaching extract?
Concepts: Descriptive group comparison, Welch’s independent-samples t-test, interpretation and limitations. Data: 2023 HDB teaching extract.
This is a comparison of recorded transactions, not a causal estimate of flat-type effects. The source Week 3 lab also examines regions and ANOVA; those extensions remain for a later revision.
After you attempt the exercises: Open the complete solution notebook on GitHub.
from pathlib import Path
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# Works in a repository checkout and remotely (including Colab).
name = "hdb_data_2023.csv.xz"
candidates = [
Path("../datasets/singapore_hdb_ura") / name,
Path("src/content/datasets/singapore_hdb_ura") / name,
Path("datasets/singapore_hdb_ura") / name,
]
source = next((p for p in candidates if p.is_file()), "https://raw.githubusercontent.com/wcchin/geo-stat-vis/8cf3ddb0a7eff7d94018940e91f32d7482f32aaa/src/content/datasets/singapore_hdb_ura/" + name)
df = pd.read_csv(source, index_col=0)
assert {"resale_price", "resale_age"}.issubset(df.columns)
print(f"Loaded {len(df):,} records from {source}")
df[["resale_price", "resale_age"]].describe()1. Inspect categories¶
Choose two flat types with adequate observations.
print("Columns:", df.columns.tolist())
assert "flat_type" in df.columns, "Expected flat_type in the prepared HDB extract"
print(df["flat_type"].value_counts().head(10))
valid = df.dropna(subset=["flat_type", "resale_price"])
counts = valid["flat_type"].value_counts()
groups = counts.index[:2].tolist()
assert len(groups) == 2
a = valid.loc[valid["flat_type"] == groups[0], "resale_price"].astype(float)
b = valid.loc[valid["flat_type"] == groups[1], "resale_price"].astype(float)
print("Selected groups:", groups)
print(pd.DataFrame({"n":[len(a),len(b)], "mean":[a.mean(),b.mean()], "median":[a.median(),b.median()]},index=groups))2. Exercise — visual comparison¶
TODO: Plot a labelled boxplot of the selected groups. Identify the direction of the difference and possible outliers.
# TODO: create a boxplot using `[a, b]`, labelled with `groups`.
3. Exercise — inferential comparison¶
TODO: Conduct a two-sided Welch independent-samples t-test (scipy.stats.ttest_ind, equal_var=False). State the null hypothesis, p-value and a limitation of interpretation.
# TODO: import ttest_ind from scipy.stats and evaluate the two groups.
Reflection¶
Would a very small p-value establish why the groups differ? What other variables might explain part of the observed price differences?
Check your understanding¶
Try the exercises and write down your interpretation before comparing your work with the complete answers.