Markdown Editor

Variable Codebook Template (Statistics, Measurement Levels, R and Python)

Research question to variables, measurement levels, variable roles with a causal sketch, codebook table, Likert and reverse coding, R and Python codebook checks

学術フルStevens (1946) scales of measurement; Velleman and Wilkinson (1993); Likert (1932); DDI codebook practice (name); NIST/SEMATECH e-Handbookstatsvariablecodebookmath

使い方: Use before collecting or analysing data to define every variable: level, role, unit, allowed values, missing codes and derived formulas. Fill the codebook row by row and run the R or Python check on each data export. Main pitfall: treating numeric codes as numbers and reversing items before recoding missing codes.

プレビュー

Variable Codebook: [Your study question or course project]

A working codebook for your own project: it turns a research question into named variables, records the measurement level and role of each one, fixes the codes for answers and missing values, and checks a data file against those rules in R and Python. It is for students on a statistics or methods course, thesis writers preparing their data, and analysts who inherit a data set. It speeds up learning because every later choice (summary, chart, test, model) depends on the measurement level and role you record here, so you practise that decision once, carefully, and then reuse it. The worked examples use fictional data; replace them with your own. Source basis: Stevens (1946) on scales of measurement, the NIST/SEMATECH e-Handbook, and DDI codebook practice, written in original words.

Document control

FieldValue
Course or project[Course code and title, or thesis project name]
Learner or analyst[Your name]
Data set[Name of the data file and its export date, e.g. wellbeing_pilot_2026-03-14.csv]
Software and versionsR 4.5.1 (base and stats); Python 3.14 with pandas 3.1.0 and numpy 2.5.4
DateYYYY-MM-DD
Version[0.1]

What a codebook is for

A codebook is the dictionary of your data set. For every column it says what the column means, how it was measured, which values are allowed, how missing answers are coded, and where the column came from. Without one, two people reading the same file will make different assumptions: one will treat a code of 99 as a real age, another will treat "year of study" as a number to average, and a third will forget that question 3 of a scale was worded the other way round. Each of those slips changes results silently.

The codebook also forces two decisions that drive every later step of the analysis. The measurement level of a variable tells you which summaries and tests are meaningful (you cannot take the mean of faculty names). The role of a variable (outcome, predictor, covariate, confounder, mediator, moderator) tells you where it goes in the model. Students who record both decisions early find test selection much easier, because the test selector questions ("what type is the outcome? how many groups? are they paired?") are already answered on paper.

Use this template whenDo not rely on it alone when
You are designing a survey, experiment or data extractionThe data come with an official codebook you must not change (use it, and add a local notes column)
You receive a data file with unclear column names or codesVariables are free text that needs qualitative coding (use a coding frame for qualitative data)
You need to document a thesis data set for examiners or a replication packageYou need a full metadata standard for an archive (follow the archive's DDI or schema requirements)

From research question to variables

Start from one precise research question. A useful pattern is: "In [population], is [exposure or predictor] associated with [outcome], after accounting for [other factors]?" Then work in three steps.

  1. Concepts. Underline the abstract ideas in the question: "sleep", "stress", "academic performance".
  2. Operational definitions. For each concept, say exactly how you will measure it: "sleep = self-reported average hours per night over the past week", "stress = mean of four 5-point items", "performance = grade point average from the registry, 0 to 4".
  3. Variables. Give each measurement a short machine name (lowercase, no spaces, e.g. sleep_h), a human label, a type and a unit. Add the variables you need for design and control: identifiers, group, time point, and the factors that could confound the relation you care about.

Fill in your own version below.

StepMy answer
Research question (one sentence)[In ... is ... associated with ... after accounting for ...?]
Concepts[concept 1], [concept 2], [concept 3]
Operational definition of the outcome[How exactly is it measured, by whom, on what scale?]
Operational definition of the main predictor[ ]
Other factors to record (possible confounders, moderators)[ ]
Design variables (ID, group, time, site)[ ]
Example: research questionIn Lakemoor University undergraduates, is average sleep associated with perceived stress, after accounting for faculty and year of study?

Measurement levels and what each allows

Stevens (1946) proposed four levels of measurement. Each level keeps all the properties of the level below it and adds one more, so the list of meaningful operations grows as you go down the table.

LevelWhat the numbers or labels meanMeaningful operationsTypical summariesExamples (Lakemoor University)
NominalCategories with no orderEqual or not equal, countingCounts, proportions, modeFaculty (ARTS, SCI, BUS, ENG), residence hall
OrdinalCategories with an order, gaps not equalPlus greater or less thanMedian, percentiles, modeYear of study (1 to 4), a single Likert item, class rank
IntervalEqual gaps, arbitrary zeroPlus addition and subtractionMean, SD, differencesTemperature in °C, calendar year, many standardised test scales
RatioEqual gaps and a true zeroPlus multiplication and ratiosMean, SD, geometric mean, coefficient of variationSleep hours, age, library visits, income, reaction time

A quick check for ratio level: does "twice as much" make sense? Eight hours of sleep is twice four hours, so sleep is ratio. 20 °C is not "twice as warm" as 10 °C, because 0 °C is not "no temperature", so Celsius is interval. Kelvin, with a true zero, is ratio.

Two further distinctions help when you choose methods. A variable is discrete if it takes separate values (counts such as visits per week) and continuous if any value in a range is possible (time, weight). A nominal variable with exactly two categories is binary (dichotomous), and many methods treat binary variables specially (proportions, logistic regression).

The levels are a guide, not a law. Velleman and Wilkinson (1993) argued that applying the levels as strict rules can mislead: a sum of ten Likert items is often analysed as interval with good results, and some ordinal data carry more information than the label suggests. The practical rule is: record the level honestly in the codebook, and when you treat a variable as a higher level than it strictly is (for example, the mean of a multi-item scale), write down that you are doing so and why.

Variable roles in the analysis

The role of a variable is not a property of the variable; it depends on the question. Sleep can be an outcome in one study and a predictor in the next. For your main question, assign each variable one role.

RolePlain meaningWhat to do with itLakemoor example
Outcome (dependent variable, response)The thing you want to explain or predictLeft-hand side of the modelPerceived stress score
Predictor (exposure, independent variable, treatment)The variable whose effect or association you studyMain right-hand side termAverage sleep hours
CovariateAnother variable in the model, often to improve precisionInclude if it predicts the outcomeAge
ConfounderA common cause of predictor and outcome; it creates a false or distorted associationAdjust for it (in the design or the model)Faculty: heavy lab timetables shorten sleep and raise stress
MediatorA variable on the path from predictor to outcomeDo not adjust for it if you want the total effectDaytime tiredness (sleep lowers tiredness, tiredness raises stress)
Moderator (effect modifier)A variable that changes the size or direction of the predictor's effectAdd an interaction term or analyse subgroupsPaid work hours: the sleep and stress relation may be stronger for students who work

A causal sketch makes these roles visible. In a directed acyclic graph (DAG), each arrow means "is assumed to cause". The sketch below is not a result; it is an assumption you write down so readers can disagree with it.

How to read it: faculty points to both sleep and stress, so it opens a "back door" path between them and must be adjusted for. Tiredness lies on the path from sleep to stress, so adjusting for it would remove part of the effect you want to measure. Paid work hours is drawn with dotted lines because a moderator changes the strength of an arrow rather than causing a variable; in a model it becomes the interaction sleep_h:work_h. Age only points to the outcome, so including it can sharpen precision but does not remove bias. Strictly, a formal DAG has no "effect strength" node; the dotted part is a teaching shortcut for moderation.

Codebook table

NameLabelLevelRoleUnitAllowed valuesMissing codesSourceDerived from
Example: idRespondent identifierNominalDesign (ID)none1 to 9999, uniquenone allowedSurvey platform
Example: facultyFaculty of enrolmentNominalConfoundernoneARTS, SCI, BUS, ENGblank = not answeredRegistry
Example: yearYear of studyOrdinalCovariateyear1, 2, 3, 4blank = not answeredRegistry
Example: sleep_hAverage sleep per night, past 7 daysRatioPredictorhours0 to 12-9 = refusedSurvey Q5
Example: q1"I felt unable to control important things"OrdinalScale item1 to 51 = never ... 5 = very often-9 = refusedSurvey Q6a
Example: q3_rev"I felt on top of things" (positively worded)OrdinalScale item1 to 51 = never ... 5 = very often-9 = refusedSurvey Q6c
Example: q3q3_rev reverse codedOrdinalScale item1 to 51 to 5NAScript step 36 - q3_rev
Example: stressPerceived stress scoreInterval (treated)Outcomepoints, 1 to 51.00 to 5.00NA if any item missingScript step 4mean(q1, q2, q3, q4)
[name][label][level][role][unit][values or range][codes and meaning][source][formula or blank]
[name][label][level][role][unit][values or range][codes and meaning][source][formula or blank]

Rules that save time later:

  • Names. Lowercase letters, digits and underscores; start with a letter; keep them short but readable (sleep_h, not Q5_SleepHoursAvgPastWeek). Suffix reversed items (_rev) and derived scores clearly.
  • Codes for categories. Use stable short codes in the data and keep the wording in the codebook. Never reuse a code for a different meaning between survey waves.
  • Missing codes. Distinguish reasons when they matter: for example -9 refused, -8 don't know, -7 not applicable (skipped by routing). Choose codes that cannot be real values. Never use 0 or 99 for an age or a count.
  • Units. State the unit for every number, including time windows ("per week", "past 7 days").
  • Derived variables. Write the exact formula and the rule for missing items. A derived variable is never typed in by hand.

Coding Likert items and reverse coding

A Likert item is one statement with ordered answer options, such as 1 = never, 2 = almost never, 3 = sometimes, 4 = fairly often, 5 = very often (Likert 1932). Each single item is ordinal. A scale combines several items about the same concept into one score, usually the sum or the mean. Scale scores have more possible values and are often analysed as interval, which is a convention you should state, not a fact.

Questionnaires often include some positively worded items to stop people from ticking the same column every time. For "I felt on top of things", a high answer means low stress, so the item must be flipped before it is combined with the others. The plain rule: the lowest code becomes the highest and vice versa. As a formula, for an item with smallest code mm and largest code MM:

xreversed=(m+M)−xx_{\text{reversed}} = (m + M) - x

SymbolMeaning
xxthe original code given by the respondent
mm, MMthe smallest and largest possible codes of the item (not the observed ones)
xreversedx_{\text{reversed}}the code after reversing

For a 1 to 5 item, m+M=6m + M = 6, so 1 becomes 5, 2 becomes 4, 3 stays 3. For a 0 to 4 item, m+M=4m + M = 4, so 0 becomes 4. Using 6−x6 - x on a 0 to 4 item is a classic error: 0 would become 6, which is not a valid code.

Three habits make Likert coding safe. First, recode missing codes to NA before reversing, otherwise −9-9 becomes 1515 on a 1 to 5 item and looks like a valid extreme score. Second, keep the original column and create the reversed one under a new name, so the step is visible and can be checked. Third, after building a scale, check that all items correlate positively with each other; a negative correlation usually means an item that should have been reversed was not (see academic/stats-reliability-factor-analysis for Cronbach's alpha and item analysis).

The chart shows the counts of item q3 in the worked example before and after reversing. The shape is mirrored, which is exactly what reversing should do: the bars swap ends, and the middle category stays where it is.

Worked example A: checking a data file against the codebook

Setting. A pilot survey of ten Lakemoor University students (fictional) records faculty, year of study, average sleep hours and four stress items. Item q3 is positively worded and stored as q3_rev. The codebook allows faculty codes ARTS, SCI, BUS and ENG only, years 1 to 4, sleep 0 to 12 hours, item codes 1 to 5, and uses −9-9 for refused.

Step 1: make the codebook machine-readable. Put the name, level, minimum, maximum, allowed codes and missing code of each variable into a small table inside the script. This is the same information as the codebook table, in a form the computer can loop over.

Step 2: check every variable. For each variable, a value is a problem if it is not a missing code and it is either outside the allowed list (categorical variables) or outside the range (numeric variables).

# Lakemoor University wellbeing pilot (fictional)
d <- data.frame(
  id      = 1:10,
  faculty = c("ARTS","SCI","SCI","BUS","ARTS","ENG","SCI","BUS","ARTS","LAW"),
  year    = c(1, 2, 2, 3, 1, 4, 5, 2, 3, 1),
  sleep_h = c(7.5, 6.0, 8.0, 5.5, -9, 7.0, 6.5, 14.0, 7.0, 6.0),
  q1      = c(4, 2, 3, 5, 4, 1, 3, 4, 2, 3),
  q2      = c(4, 1, 3, 5, 5, 2, 3, 4, 2, 6),
  q3_rev  = c(2, 5, 3, 1, 1, 4, 3, 2, 4, 3),
  q4      = c(5, 2, 2, 4, 4, 1, 3, -9, 2, 3)
)
cb <- data.frame(
  name    = c("faculty","year","sleep_h","q1","q2","q3_rev","q4"),
  type    = c("nominal","ordinal","ratio","ordinal","ordinal","ordinal","ordinal"),
  min     = c(NA, 1, 0, 1, 1, 1, 1),
  max     = c(NA, 4, 12, 5, 5, 5, 5),
  allowed = c("ARTS,SCI,BUS,ENG", NA, NA, NA, NA, NA, NA),
  missing = c(NA, NA, -9, -9, -9, -9, -9)
)
problems <- data.frame()
for (i in seq_len(nrow(cb))) {
  v <- cb$name[i]; x <- d[[v]]
  miss <- !is.na(cb$missing[i]) & x %in% cb$missing[i]
  if (!is.na(cb$allowed[i])) {
    ok <- x %in% strsplit(cb$allowed[i], ",")[[1]]
  } else {
    ok <- x >= cb$min[i] & x <= cb$max[i]
  }
  bad <- which(!ok & !miss)
  if (length(bad)) problems <- rbind(problems,
    data.frame(variable = v, id = d$id[bad], value = x[bad]))
}
print(problems, row.names = FALSE)
# Recode missing codes to NA, then reverse-code q3 on a 1-5 scale
for (v in cb$name[!is.na(cb$missing)]) d[[v]][d[[v]] == -9] <- NA
d$q3 <- 6 - d$q3_rev
d$stress <- rowMeans(d[, c("q1","q2","q3","q4")])
print(d[1:4, c("id","q3_rev","q3","stress")], row.names = FALSE)
 variable id value
  faculty 10   LAW
     year  7     5
  sleep_h  8    14
       q2 10     6
 id q3_rev q3 stress
  1      2  4   4.25
  2      5  1   1.50
  3      3  3   2.75
  4      1  5   4.75
import numpy as np, pandas as pd
d = pd.DataFrame({
    "id": range(1, 11),
    "faculty": ["ARTS","SCI","SCI","BUS","ARTS","ENG","SCI","BUS","ARTS","LAW"],
    "year": [1, 2, 2, 3, 1, 4, 5, 2, 3, 1],
    "sleep_h": [7.5, 6.0, 8.0, 5.5, -9, 7.0, 6.5, 14.0, 7.0, 6.0],
    "q1": [4, 2, 3, 5, 4, 1, 3, 4, 2, 3],
    "q2": [4, 1, 3, 5, 5, 2, 3, 4, 2, 6],
    "q3_rev": [2, 5, 3, 1, 1, 4, 3, 2, 4, 3],
    "q4": [5, 2, 2, 4, 4, 1, 3, -9, 2, 3],
})
cb = pd.DataFrame({
    "name": ["faculty","year","sleep_h","q1","q2","q3_rev","q4"],
    "type": ["nominal","ordinal","ratio","ordinal","ordinal","ordinal","ordinal"],
    "min": [np.nan, 1, 0, 1, 1, 1, 1],
    "max": [np.nan, 4, 12, 5, 5, 5, 5],
    "allowed": ["ARTS,SCI,BUS,ENG", None, None, None, None, None, None],
    "missing": [np.nan, np.nan, -9, -9, -9, -9, -9],
})
rows = []
for r in cb.itertuples():
    x = d[r.name]
    miss = x.eq(r.missing) if not np.isnan(r.missing) else pd.Series(False, index=x.index)
    ok = x.isin(r.allowed.split(",")) if isinstance(r.allowed, str) else x.between(r.min, r.max)
    for i in d.index[~ok & ~miss]:
        rows.append((r.name, d.at[i, "id"], x[i]))
print(pd.DataFrame(rows, columns=["variable", "id", "value"]).to_string(index=False))
for v in cb.loc[cb["missing"].notna(), "name"]:
    d[v] = d[v].replace(-9, np.nan)
d["q3"] = 6 - d["q3_rev"]
d["stress"] = d[["q1","q2","q3","q4"]].mean(axis=1, skipna=False)
print(d.loc[:3, ["id","q3_rev","q3","stress"]].to_string(index=False))
variable  id value
 faculty  10   LAW
    year   7     5
 sleep_h   8  14.0
      q2  10     6
 id  q3_rev  q3  stress
  1       2   4    4.25
  2       5   1    1.50
  3       3   3    2.75
  4       1   5    4.75

Step 3: read the problem list. Both languages find the same four problems, and none of them is a missing code:

VariableIDValueDiagnosisAction (record it in the cleaning log)
faculty10LAWCode not in codebook: either a new faculty or a typoAsk the data owner; if LAW is real, add it to the codebook with a revision entry
year75Out of range 1 to 4Check registry; fifth-year students may exist (update codebook) or it is an entry error
sleep_h814Above the 12-hour maximumImplausible as a weekly average; set to NA with a logged reason, never silently
q2106Not a valid code on a 1 to 5 itemSet to NA; check the survey export for a shifted code

Note that the −9-9 values for id 5 (sleep) and id 8 (q4) are not listed, because the codebook says they are legitimate missing codes. That is the point of writing them down.

Step 4: check the derived variables by hand. For respondent 1, the raw items are q1 = 4, q2 = 4, q3_rev = 2, q4 = 5. Reversing gives q3 = 6 − 2 = 4. The stress score is (4+4+4+5)/4=17/4=4.25(4 + 4 + 4 + 5)/4 = 17/4 = 4.25, matching the output. For respondent 2: q3 = 6 − 5 = 1, score (2+1+1+2)/4=1.50(2 + 1 + 1 + 2)/4 = 1.50. A hand check of two rows catches most formula errors.

A difference between R and Python worth knowing. rowMeans() in R returns NA for a row with any missing item unless you add na.rm = TRUE. pandas mean() does the opposite: it skips missing values by default, so the code sets skipna=False on purpose. With the default, respondent 8 (q4 missing) would silently get a stress score from three items in Python but NA in R. The codebook's "missing rule" column ("NA if any item missing") is what decides which behaviour you want, and the code must say it explicitly.

Interpretation. The data file is not ready for analysis: four values break the codebook. The codebook did its job by turning a ten-row eyeball check into a four-line problem list. For a 2,000-row file the gain is far larger.

Worked example B: Brightwell Bakery quality survey (half solved)

Setting. Brightwell Bakery (fictional) records, for each batch of loaves: the oven used (Oven A, B or C), the oven temperature in °C, the loaf weight in grams, the number of loaves rejected, a taster's rating "poor, fair, good, excellent", and the item "The crust was too hard" on a 1 to 5 agreement scale, where all other taste items are positively worded. The question is: "Does oven temperature affect loaf weight, allowing for which oven is used?"

NameLabelLevelRoleAllowed valuesMissing codeNote
ovenOven usedNominalCovariate (or confounder)A, B, CblankLabels, no order
temp_cOven temperature[ ]Predictor150 to 260-9[Why not ratio?]
weight_gLoaf weightRatio[ ]300 to 1,200-9True zero; "twice as heavy" is meaningful
rejectsLoaves rejected per batch[ ]Secondary outcome0 to 50-9[Discrete or continuous?]
ratingTaster rating[ ]Secondary outcome1 = poor ... 4 = excellent-9Order but unequal gaps
crust_rev"The crust was too hard"OrdinalScale item1 to 5-9Reverse with [ ]

Gaps to complete: (1) level of temp_c and the reason; (2) role of weight_g; (3) level of rejects and whether it is discrete; (4) level of rating; (5) the reverse-coding formula for crust_rev; (6) a reverse-coded value of 2 becomes [ ].

Exercise C: Harbour City Library opening hours

Harbour City Library (fictional) extended opening hours at two of its four branches in March. The analyst wants to know: "Did longer opening hours increase daily visits, taking day of the week and rainfall into account?" The daily file has: branch (Central, North, East, West), date, day (Mon to Sun), open_h (hours open that day), visits (door counter), rain_mm (rainfall that day), extended (1 if the branch has the new hours, 0 if not), and counter_fault (1 if the door counter was broken for part of the day).

Tasks: (a) give the level and role of each variable; (b) write a full codebook row for visits including a missing code strategy for days when the counter was broken; (c) name one possible confounder that is not in the file and draw it into a causal sketch (arrows in words are fine).

Codebook quality checklist

  • Every column in the data file has exactly one codebook row, and every codebook row exists in the data.
  • Each row has a level, a role for the main question, a unit and allowed values.
  • Missing codes are listed, cannot be confused with real values, and distinguish reasons where it matters.
  • Reversed items are flagged from their wording, with the formula and the item range.
  • Every derived variable has a formula and a missing-item rule, and is created by script.
  • The causal sketch is drawn, and the adjustment set (confounders) is written next to it.
  • The checking script runs on the current data export and its output is saved in the cleaning log.
  • The codebook version and date match the analysis that uses it.

Common mistakes and misconceptions

Mistake or misconceptionWhy it is wrongCorrect practice
"Numbers in the column, so it is a numeric variable."Faculty coded 1 to 4 is still nominal; the mean faculty 2.4 has no meaning.Classify by what the codes mean, not by the storage type. Store such codes as factors or categories.
Averaging a single Likert item and calling it intervalOne item has five ordered labels with unknown gaps.Report the median and the distribution for a single item; reserve means for multi-item scales and say so.
Treating 99 or 0 as a valid answerA missing code that looks like a real value enters every mean.Use impossible codes (such as −9) and convert them to NA before any analysis.
Reversing before recoding missing codes−9 reversed on a 1 to 5 item becomes 15.Recode missing to NA first, then reverse.
Using 6−x6 - x for every scaleCorrect only for items coded 1 to 5.Use (m+M)−x(m + M) - x with the item's own minimum and maximum.
"Adjust for everything that is measured."Adjusting for a mediator removes part of the effect; adjusting for a collider (a common effect) can create bias.Choose the adjustment set from the causal sketch, not from the column list.
"Moderator and mediator are the same thing."A mediator carries the effect; a moderator changes its size.Mediator: on the arrow path. Moderator: an interaction term.
Editing values in the spreadsheet by handNo record of what changed and why; not reproducible.Change values only in a script and log each rule (see academic/stats-data-cleaning-log).

Self-test questions

  1. A survey records "household income band: under 20k, 20k to 40k, 40k to 60k, over 60k". What is the level, and is the mean band a sensible summary?
  2. Why is temperature in °C interval and not ratio? Give one statement that is meaningful and one that is not.
  3. A 7-point item runs from 1 to 7. Reverse-code the answer 2. Then do the same for a 0 to 6 item answered 2.
  4. In a study of exercise and exam scores, motivation causes both more exercise and higher scores. What role does motivation play, and what happens if you leave it out of the model?
  5. In the same study, exercise improves sleep, and sleep improves exam scores. Should sleep be adjusted for when the aim is the total effect of exercise? Why?
  6. In worked example A, why does respondent 5's sleep value of −9 not appear in the problem list?

My notes and next steps

ItemMy entry
Confidence with measurement levels (1 to 5)[ ]
Confidence with variable roles and causal sketches (1 to 5)[ ]
Questions still open[ ]
Mistakes to copy into my error log (academic/stats-error-log)[ ]
Next step[Run the checking script on my data, then start academic/stats-data-cleaning-log]
Review again onYYYY-MM-DD (about one week from today, then one month)

Sources and further reading

Structure aligned with common codebook practice (variable name, label, type, values, missing codes, provenance) as described by the Data Documentation Initiative, and based on the classic measurement-level framework.

  • Stevens, S. S. (1946). On the theory of scales of measurement. Science, 103(2684), 677–680.
  • Velleman, P. F., and Wilkinson, L. (1993). Nominal, ordinal, interval, and ratio typologies are misleading. The American Statistician, 47(1), 65–72.
  • Likert, R. (1932). A technique for the measurement of attitudes. Archives of Psychology, 140, 1–55.
  • Baron, R. M., and Kenny, D. A. (1986). The moderator-mediator variable distinction in social psychological research: conceptual, strategic, and statistical considerations. Journal of Personality and Social Psychology, 51(6), 1173–1182.
  • Hernán, M. A., and Robins, J. M. (2020). Causal Inference: What If. Chapman and Hall/CRC (causal diagrams, confounding, colliders).
  • Pearl, J. (2009). Causality (2nd ed.). Cambridge University Press.
  • NIST/SEMATECH e-Handbook of Statistical Methods, chapter 1 Exploratory Data Analysis, https://www.itl.nist.gov/div898/handbook/ (accessed 2026-10-25). Public domain.
  • Data Documentation Initiative (DDI Alliance): metadata standard for describing survey and research data (name only).
  • Further reading: de Smith, M. J., Statistical Analysis Handbook (2024 edition, statsref.com); Diez, Çetinkaya-Rundel and Barr, OpenIntro Statistics (chapter on data basics).

Answer key

Worked example B. (1) temp_c is interval: equal gaps, but 0 °C is not "no heat", so 200 °C is not twice as hot as 100 °C. (2) weight_g is the outcome. (3) rejects is ratio (a count with a true zero) and discrete. (4) rating is ordinal. (5) (1+5)−x=6−x(1 + 5) - x = 6 - x. (6) A value of 2 becomes 4.

Exercise C. (a) branch: nominal, design variable (and possible confounder, since the extended branches were chosen, not randomised). date: interval (time), design variable for trends. day: ordinal by calendar order but usually treated as nominal in models (weekday effects are not equally spaced); covariate. open_h: ratio, mechanism of the intervention. visits: ratio count, discrete, outcome. rain_mm: ratio, covariate. extended: nominal binary, main predictor. counter_fault: nominal binary, data-quality flag. (b) Example row: visits | Door-counter visits per branch per day | Ratio (count) | Outcome | visits per day | 0 to 5,000 | NA when counter_fault = 1 (counts are partial and not comparable) | Door counter export | none. (c) For example, branch size or neighbourhood footfall: busier branches may have been picked for extended hours and also have more visits. Sketch: footfall → extended; footfall → visits; extended → visits.

Self-test.

  1. Ordinal (ordered bands, unequal or open-ended widths). The mean band is not sensible; report the median band and the percentage in each band.
  2. 0 °C is an arbitrary zero. Meaningful: "20 °C is 10 degrees warmer than 10 °C". Not meaningful: "20 °C is twice as warm as 10 °C".
  3. 1 to 7: (1+7)−2=6(1 + 7) - 2 = 6. 0 to 6: (0+6)−2=4(0 + 6) - 2 = 4.
  4. Motivation is a confounder (common cause). Leaving it out biases the exercise coefficient, here probably upward, because part of the motivation effect is credited to exercise.
  5. No. Sleep is a mediator on the path exercise → sleep → scores; adjusting for it estimates only the direct effect and removes part of the total effect.
  6. Because −9 is listed as a missing code for sleep_h, the check treats it as a legitimate missing value, not as an out-of-range number. It becomes NA in the recoding step.

Revision history

VersionDateAuthorChange summary
0.1YYYY-MM-DD[Your name]First draft from the research question
0.2YYYY-MM-DD[Your name]Example: Added LAW to faculty codes after registry check; year range now 1 to 5
1.0YYYY-MM-DD[Your name]Frozen before main analysis

関連テンプレート