* =============================================================================.
* GEROSTATS STATISTICS LAB.
* Complete worked analysis in IBM SPSS Statistics.
*
* Teaching dataset: gerostats_medication_review_cohort.csv.
* Dataset status: entirely synthetic; it contains no real patient records.
*
* HOW TO RUN.
* 1. Put this .sps file and the cohort .csv in the same folder.
* 2. Open this file in the SPSS Syntax Editor.
* 3. Replace the FILE path below with the full path to your CSV if needed.
* 4. Highlight one numbered section at a time and choose Run > Selection.
* =============================================================================.

* =============================================================================.
* 1. MEET THE COHORT: IMPORT, LABEL AND CHECK.
* =============================================================================.

GET DATA
  /TYPE=TXT
  /FILE='gerostats_medication_review_cohort.csv'
  /ENCODING='UTF8'
  /ARRANGEMENT=DELIMITED
  /FIRSTCASE=2
  /DELCASE=LINE
  /DELIMITERS=","
  /QUALIFIER='"'
  /VARIABLES=
    participant_id A7
    age_years F3.0
    sex F1.0
    lives_alone F1.0
    deprivation_score F3.0
    medication_count F2.0
    polypharmacy F1.0
    baseline_frailty F5.3
    baseline_disability F1.0
    med_review F1.0
    eq5d_6m F5.3
    disability_6m F1.0
    frailty_cat_6m F1.0
    falls_count_6m F2.0
    hospital_admission_6m F1.0
    followup_days F3.0.

DATASET NAME medlab WINDOW=FRONT.

VARIABLE LABELS
  participant_id "Synthetic participant identifier"
  age_years "Age at baseline (years)"
  sex "Sex recorded at baseline"
  lives_alone "Lives alone at baseline"
  deprivation_score "Synthetic deprivation score (higher = more deprived)"
  medication_count "Regular medicines at baseline"
  polypharmacy "Five or more regular medicines"
  baseline_frailty "Baseline frailty index"
  baseline_disability "Activity-limiting disability at baseline"
  med_review "Structured medication review"
  eq5d_6m "EQ-5D-style score at six months"
  disability_6m "Activity-limiting disability at six months"
  frailty_cat_6m "Frailty category at six months"
  falls_count_6m "Falls during six-month follow-up"
  hospital_admission_6m "Emergency hospital admission during follow-up"
  followup_days "Days to first admission or censoring".

VALUE LABELS
  sex 0 "Man" 1 "Woman"
  /lives_alone polypharmacy baseline_disability med_review disability_6m
    hospital_admission_6m 0 "No" 1 "Yes"
  /frailty_cat_6m 0 "Robust" 1 "Pre-frail" 2 "Frail".

VARIABLE LEVEL
  participant_id (NOMINAL)
  sex lives_alone polypharmacy baseline_disability med_review disability_6m
    hospital_admission_6m (NOMINAL)
  frailty_cat_6m (ORDINAL)
  age_years deprivation_score medication_count baseline_frailty eq5d_6m
    falls_count_6m followup_days (SCALE).

EXECUTE.

* Inspect the schema and the amount of usable information in each variable.
DISPLAY DICTIONARY.
FREQUENCIES VARIABLES=participant_id age_years baseline_frailty med_review
  disability_6m
  /FORMAT=NOTABLE
  /STATISTICS=MINIMUM MAXIMUM
  /ORDER=ANALYSIS.

* Check that the identifier appears once per row.
SORT CASES BY participant_id(A).
MATCH FILES FILE=* /BY participant_id /FIRST=first_id /LAST=last_id.
COMPUTE duplicate_id=(first_id=0 OR last_id=0).
FREQUENCIES VARIABLES=duplicate_id.

* =============================================================================.
* 2. CHARACTERISE THE DATA.
* =============================================================================.

* Categorical variables: counts, percentages and missing values.
FREQUENCIES VARIABLES=sex polypharmacy med_review frailty_cat_6m
  /ORDER=ANALYSIS.

* Continuous variables: mean, SD and range.
DESCRIPTIVES VARIABLES=age_years baseline_frailty eq5d_6m
  /STATISTICS=MEAN STDDEV MIN MAX.

* Median, quartiles, histograms and boxplots for skewed or bounded measures.
EXAMINE VARIABLES=baseline_frailty medication_count falls_count_6m eq5d_6m
  /PLOT=BOXPLOT HISTOGRAM NPPLOT
  /COMPARE=GROUPS
  /PERCENTILES(25,50,75)
  /STATISTICS=DESCRIPTIVES
  /CINTERVAL=95
  /MISSING=PAIRWISE
  /NOTOTAL.

* =============================================================================.
* 3. COMPARE TWO GROUPS.
* =============================================================================.

* Cross-tabulation and Pearson chi-square test.
* Row percentages answer: within each medication-review group, what proportion
* had disability at six months?
CROSSTABS
  /TABLES=med_review BY disability_6m
  /FORMAT=AVALUE TABLES
  /STATISTICS=CHISQ
  /CELLS=COUNT ROW COLUMN EXPECTED
  /COUNT ROUND CELL.

* Welch's result appears on the "equal variances not assumed" row.
T-TEST GROUPS=med_review(0 1)
  /MISSING=ANALYSIS
  /VARIABLES=eq5d_6m
  /ES DISPLAY(TRUE)
  /CRITERIA=CI(.95).

* Mann-Whitney test for the skewed baseline medication count.
NPAR TESTS
  /M-W=medication_count BY med_review(0 1)
  /MISSING ANALYSIS.

* =============================================================================.
* 4. RISK RATIO, RISK DIFFERENCE AND ODDS RATIO.
* =============================================================================.

* RISK adds the odds ratio and cohort risk ratios to the two-by-two table.
* Confirm the direction from the printed labels. With the ascending order below,
* SPSS prints the disability=1 cohort RR as no review / review; take its
* reciprocal to express review / no review, matching the course page.
CROSSTABS
  /TABLES=med_review BY disability_6m
  /FORMAT=AVALUE TABLES
  /STATISTICS=CHISQ RISK
  /CELLS=COUNT ROW COLUMN
  /COUNT ROUND CELL.

* =============================================================================.
* 5. CHOOSE REGRESSION FROM THE OUTCOME.
* =============================================================================.

* CONTINUOUS OUTCOME: multiple linear regression.
* The med_review coefficient is an adjusted mean difference.
REGRESSION
  /MISSING LISTWISE
  /STATISTICS COEFF OUTS R ANOVA CI(95) COLLIN TOL
  /DEPENDENT eq5d_6m
  /METHOD=ENTER med_review age_years sex lives_alone deprivation_score
    medication_count baseline_frailty baseline_disability
  /RESIDUALS HISTOGRAM(ZRESID) NORMPROB(ZRESID)
  /SAVE PRED RESID.

* BINARY OUTCOME: logistic regression.
* Exp(B) is the adjusted odds ratio.
LOGISTIC REGRESSION VARIABLES disability_6m
  /METHOD=ENTER med_review age_years sex lives_alone deprivation_score
    medication_count baseline_frailty baseline_disability
  /CATEGORICAL=med_review sex lives_alone baseline_disability
  /CONTRAST (med_review)=Indicator(1)
  /CONTRAST (sex)=Indicator(1)
  /CONTRAST (lives_alone)=Indicator(1)
  /CONTRAST (baseline_disability)=Indicator(1)
  /PRINT=CI(95) GOODFIT
  /CLASSPLOT
  /SAVE=PRED.

* ORDERED OUTCOME: proportional-odds ordered logistic regression.
* The Test of Parallel Lines is an important check of the proportional-odds
* assumption. Higher outcome values represent worse frailty.
* SPSS also warns about empty outcome-by-covariate cells because continuous
* covariates create many unique patterns; this is expected in this example.
PLUM frailty_cat_6m
  WITH med_review sex lives_alone baseline_disability age_years
    deprivation_score medication_count baseline_frailty
  /CRITERIA=CIN(95) DELTA(0) MXITER(100) MXSTEP(5) LCONVERGE(0)
    PCONVERGE(1.0E-6) SINGULAR(1.0E-8)
  /LINK=LOGIT
  /PRINT=FIT PARAMETER SUMMARY TPARALLEL.

* COUNT OUTCOME: Poisson regression.
* Exponentiated coefficients are incidence-rate ratios. Compare model fit and
* dispersion before deciding whether negative-binomial regression is needed.
GENLIN falls_count_6m
  WITH med_review sex lives_alone baseline_disability age_years
    deprivation_score medication_count baseline_frailty
  /MODEL med_review sex lives_alone baseline_disability age_years
    deprivation_score medication_count baseline_frailty
    INTERCEPT=YES DISTRIBUTION=POISSON LINK=LOG
  /CRITERIA METHOD=FISHER(1) SCALE=1 COVB=MODEL
  /PRINT CPS DESCRIPTIVES MODELINFO FIT SOLUTION(EXPONENTIATED).

* TIME-TO-EVENT OUTCOME: Cox proportional-hazards regression.
* A status of 1 means an admission occurred; other cases are censored.
COXREG followup_days
  /STATUS=hospital_admission_6m(1)
  /METHOD=ENTER med_review age_years sex lives_alone deprivation_score
    medication_count baseline_frailty baseline_disability
  /CONTRAST (med_review)=Indicator(1)
  /CONTRAST (sex)=Indicator(1)
  /CONTRAST (lives_alone)=Indicator(1)
  /CONTRAST (baseline_disability)=Indicator(1)
  /PRINT=CI(95).

* =============================================================================.
* 6. CONFOUNDING: COMPARE CRUDE AND ADJUSTED ESTIMATES.
* =============================================================================.

* Crude association between medication review and six-month disability.
LOGISTIC REGRESSION VARIABLES disability_6m
  /METHOD=ENTER med_review
  /CATEGORICAL=med_review
  /CONTRAST (med_review)=Indicator(1)
  /PRINT=CI(95).

* Adjust for the pre-exposure variables selected from the causal rationale.
LOGISTIC REGRESSION VARIABLES disability_6m
  /METHOD=ENTER med_review age_years sex lives_alone deprivation_score
    medication_count baseline_frailty baseline_disability
  /CATEGORICAL=med_review sex lives_alone baseline_disability
  /CONTRAST (med_review)=Indicator(1)
  /CONTRAST (sex)=Indicator(1)
  /CONTRAST (lives_alone)=Indicator(1)
  /CONTRAST (baseline_disability)=Indicator(1)
  /PRINT=CI(95).

* Repeat with the continuous outcome to compare the crude and adjusted mean
* differences for medication review.
REGRESSION
  /MISSING LISTWISE
  /STATISTICS COEFF CI(95) R ANOVA
  /DEPENDENT eq5d_6m
  /METHOD=ENTER med_review.

REGRESSION
  /MISSING LISTWISE
  /STATISTICS COEFF CI(95) R ANOVA
  /DEPENDENT eq5d_6m
  /METHOD=ENTER med_review age_years sex lives_alone deprivation_score
    medication_count baseline_frailty baseline_disability.

* =============================================================================.
* 7. FINISH WELL: SAVE AN ANALYSIS COPY.
* =============================================================================.

SAVE OUTFILE='gerostats_medication_review_cohort_labelled.sav'
  /COMPRESSED.

* =============================================================================.
* INTERPRETATION REMINDERS.
*
* - Report estimates with 95% confidence intervals, not p-values alone.
* - Choose the model from the outcome and study question, not from habit.
* - A medication review was not randomised in this synthetic cohort.
* - Adjustment can reduce measured confounding; it cannot prove causality.
* - Do not use this synthetic dataset for clinical decisions.
* =============================================================================.
