What would you recommend for making the distinction between missing value types for dataset users who might not read the codebook carefully?
In this toy example, q2 is only asked to people who said "Yes" to q1. This means there is one missing value on q2 that is missing because the person did not respond, and two missing values on q2 that are missing because the question was not asked.
library(tidyverse)
df <- tibble(q1 = c("Yes", "Yes", "No", "No"),
q2 = c("Yes", NA, NA, NA))
df
# A tibble: 4 x 2
q1 q2
<chr> <chr>
1 Yes Yes
2 Yes NA
3 No NA
4 No NA
df %>% group_by(q1, q2) %>% count()
# A tibble: 3 x 3
# Groups: q1, q2 [3]
q1 q2 n
<chr> <chr> <int>
1 No NA 2
2 Yes Yes 1
3 Yes NA 1
When I summarize by q2 there is no way in the dataset to make a distinction between missingness from non-response vs structural missingness.
df %>% group_by(q2) %>% count()
# A tibble: 2 x 2
# Groups: q2 [2]
q2 n
<chr> <int>
1 Yes 1
2 NA 3