This is the rubric I grade from. Nothing here is a hint about the answers — it tells
you how the points for each question are divided, so you can see where your effort is actually being
measured and check your own work before you submit.
How your score is built
Code & output
60 pts
Does your code do what the question asked, and does the required output actually appear in
your rendered document? Marked against the What to do and What to report steps.
Interpretation
40 pts
Does your writing answer the specific questions under What to write? Each lettered
question carries its own marks. An unanswered question scores zero even if your code is perfect.
Forty percent of this exam is prose. That is deliberate: correct output that nobody explains is an
unfinished piece of work. Conversely, code that breaks but is accompanied by an honest comment on
what you tried and where it failed can still earn interpretation marks and partial code marks.
A blank chunk earns nothing; an attempt earns something.
Points by part
Part
Topic
Code
Interp.
Total
Split
1
Exploring the Data
21
15
36
2
Classification & Group Summaries
17
10
27
3
Resampling & Inference
22
15
37
4
Declaration & References
—
—
required
gate, not points
Total
60
40
100
Code & output
Interpretation · One point = one percent of the midterm grade.
Part 1 · Exploring the Data — 36 points
1.1Visual exploration16 pts
Code & output10
Figure A: thirteen panels, one per numeric variable, each panel titled with its variable name3
Figure A: free axis scales, so no panel is squashed by another variable's range2
Figure B: the ten measures converted to z-scores and reshaped to long format2
Figure B: boxplot of all ten on one axis, ordered by spread, no axis limits set2
Both figures carry a title, axis labels with units, and a legend where one is needed1
Interpretation6
A: names at least two roughly symmetric and two right-tailed distributions1.5
A: adds mean and median lines to one variable, says which is larger, explains it from the shape1.5
A: identifies a distribution shaped by a recording limit and states the limit1
B: answers whether standardising changes shape or only scale, citing one specific measure in your own plot2
Zero for the figure if it is pasted in as an image rather than drawn by a visible
code chunk. The worked examples in the question are watermarked and deliberately incomplete — one of
them is ordered the wrong way on purpose.
1.2A summary function, applied to every measure12 pts
Code & output7
Exact signature wellness_summary(df, var), column reached programmatically via df[[var]]2
Returns a named numeric vector with all seven elements, in the order given2
Each element computed correctly, including pct_above_mean as a percentage strictly exceeding the mean1
Applied to all ten measures and assembled into a 7 × 10 matrix with named rows and columns1.5
Matrix shown as a formatted table, and the seven statistics for "BMI" reported0.5
Interpretation5
(a) Says whether BMI's pct_above_mean is near 50%, and what that implies about shape — referring explicitly to both the mean and the median2
(a) Connects that answer back to the BMI panel in Figure A1
(b) Explains what stops the ten means from being comparable, and names one thing that would have to change first2
1.3The highest and lowest value of each measure8 pts
Code & output4
extremes has exactly the five required columns and one row per measure1.5
Positions from which.max() / which.min() used to look up both the value and the respondent's ID2
Displayed as a formatted table0.5
Interpretation4
Finds the value that no living adult could have, and names the measure it belongs to2
Counts the affected respondents in code — a guess or an estimate scores nothing here1
Gives a plausible account of what the value actually represents1
This is a data-checking exercise. Scanning the two columns and declaring them all
reasonable is the one answer guaranteed to score zero on the written half.
Part 2 · Classification & Group Summaries — 27 points
2.1A function that assigns a wellness profile14 pts
Code & output9
Exact signature classify_wellness(sbp, sleep), returning one string for one respondent2
The three rules implemented with the right thresholds2
Priority order respected — a respondent meeting both conditions returns "Elevated BP"3
Applied to every respondent and stored as the profile column1
All three required checks run, with their output shown1
Interpretation5
Explains why check 3 matters — what specifically would go wrong if the sleep rule were tested first3
States how many respondents would be mislabelled, taken from your own output rather than asserted2
The four test calls are given with their expected answers. If your function disagrees
with any of them, fix the function before applying it to 5,397 people — a wrong rule applied
faultlessly to everyone is still a wrong rule.
2.2Profile composition by age decade13 pts
Code & output8
Counts and percentages by profile, with rows aligned to profile_labels rather than alphabetical order2
decade_profile filled in and matching the table given in the question2
A comment stating how your method breaks ties1
100%-stacked bar chart: one bar per decade, each totalling 100%, three segments, percentage on the vertical axis2
The prescribed colour scheme used, and the figure carries a title, both axis labels and a legend1
Interpretation5
(a) Describes the pattern the figure reveals and the table conceals2
(b) Gives the "Elevated BP" percentage for the youngest and oldest decades, and the size of the change1.5
(c) Explains why reporting only the most common profile was a poor summary1.5
Part 3 · Resampling & Inference — 37 points
These three questions run in sequence on the same comparison — you test it, then find that the test
answered a narrower question than it looked like, then estimate the size of the effect.
Answer them in order. An answer to 3.3 that ignores what you found in 3.2 loses marks
in 3.3, not in 3.2.
3.1Permutation test: blood pressure by physical activity11 pts
Code & output7
Observed statistic computed in the stated direction, inactive minus active1
B = 2,000 permutations that shuffle the labels only, leaving blood-pressure values in place3
Two-sided p-value computed as specified, and reported using the convention the question gives for the case where no permutation is as extreme as the observed difference1
Histogram of perm_diffs with vertical lines at both the observed statistic and its negative1
t.test() run on the same comparison and its p-value reported alongside1
Interpretation4
(a) States a conclusion, worded as a claim about the respondents in this sample2
(b) Says whether the two tests agree, identifies which rests on stronger assumptions, and names those assumptions2
A conclusion generalised to Americans, or to any population beyond this extract, loses
the marks for (a) however sound the arithmetic behind it. The dataset note explains why.
3.2Is that difference what it appears to be?15 pts
Code & output8
Step 1 — mean age in each activity group, and the percentage inactive within every decade2
Step 2 — mean blood pressure within every decade, and cor(Age, BPSysAve)2
Step 3 — within-decade table with all five required columns, one row per decade2
Step 4 — differences recombined as a weighted average, weighted by decade size1
Step 5 — adjusted and unadjusted figures compared, with the percentage of the original difference that remains1
Interpretation7
(a) States both conditions a confounder must satisfy, and shows age meets each one using your own numbers from steps 1 and 22
(b) Gives the adjusted figure, the unadjusted figure, and the percentage change between them1
(c) Counts the decades in which the difference changes sign, and says what that does to the claim you might have made after 3.12
(d) Writes a conclusion you would now defend, precise about what the data do and do not support2
Part (d) is where a causal claim costs you. Comparing within decades holds
age fixed and nothing else; an answer asserting that activity causes a change in
blood pressure loses those marks regardless of how small the adjusted difference turned out to be.
3.3Bootstrap confidence interval for a difference in means11 pts
Code & output7
Observed difference computed in the same direction as 3.11
B = 2,000 replicates resampling whole rows with replacement, group means recomputed within each replicate3
Bootstrap standard error reported as the standard deviation of boot_diffs1
95% percentile interval from the 2.5th and 97.5th percentiles1
Histogram with vertical lines at the observed difference and at zero; the t.test() standard error extracted and shown beside yours1
Interpretation4
(a) Says whether the interval contains zero and draws the conclusion, worded about this sample1
(b) Compares that conclusion with the permutation p-value from 3.11
(c) Says how close the two standard errors are and what their agreement demonstrates about the bootstrap1
(d) States what a reader must be told alongside this interval, in light of 3.21
Resampling the two groups separately, at their observed sizes, is a different procedure
from the one asked for and costs the three marks in the second row.
Part 4 · Declaration & References — required
Worth no points, and your exam is not graded without it
Both sections must be present and filled in. A submission missing either one is returned to you
before any of the 100 points above are awarded.
Academic Integrity Declaration — the statement typed out in full, with your name
and the date. Not ticked, not pasted as a screenshot, not paraphrased.
References — every outside source, one entry each, with a URL where there is
one, the date you accessed it, and a line on what you used it for.
If you used nothing outside the course materials, write "No external sources were consulted."
That is a complete References section. An empty heading is not — it reads as an oversight.
No marks are ever deducted for citing a source. Searching the
internet is expected. The violation is failing to cite, never consulting.
What costs marks everywhere
These apply to every question above, and they are the most common way a well-prepared submission
loses points it did not need to lose.
A document that does not render. Restart R and render from scratch before
submitting. Anything that fails to run loses the marks for what it was supposed to produce.
A figure that is not yours. Every figure must be the output of a visible code
chunk in your own document. A pasted image earns zero for that part.
A figure with no caption and no takeaway. Title, axis labels with units, a legend
where one is needed, and at least one sentence saying what it shows — however pretty it is.
A figure that silently drops data. If you set axis limits or transform a scale,
check that nothing disappeared. R usually warns you; read the warnings.
Numbers that your code did not produce. Nothing hard-coded from a previous run,
a classmate, or anywhere else. Every figure in your prose must trace to a chunk.
Results nobody else can reproduce.set.seed(42) at the top and before
every randomised block.
Conclusions about the United States. NHANES oversamples deliberately; the sample's
makeup is not the country's. Write about the respondents in this dataset.
Hidden code.echo: true throughout — all code must be visible.
A silent surrender. If a question defeats you, leave a comment on what you tried
and where it broke. That comment earns partial credit; an empty chunk earns nothing.
Two things that are not graded on this scale at all
Generative AI use and discussing the exam with another person are not
deductions — they are academic integrity violations, scored zero and handled under the University's
policy rather than by me. If something has gone wrong, come and talk to me before you submit.
A conversation about what happened is recoverable; a false declaration is not.