::libraries(
easypackages# Data i/o
"here", # relative file path
"rio", # file import-export
# Data manipulation
"janitor", # data cleaning fns
"haven", # stata, sas, spss data io
"labelled", # var labelling
"readxl", # excel sheets
# "scales", # to change formats and units
"skimr", # quick data summary
"broom", # view model results
# Data analysis
"DHS.rates", # demographic rates for dhs-like surveys
"GeneralOaxaca", # BO decomposition for non-linear
"survey", # apply survey weights
# Analysis output
"gt",
# "modelsummary", # output summary tables
"gtsummary", # output summary tables
"flextable", # creating tables from objects
"officer", # editing in office docs
# R graph related packages
"ggstats",
"RColorBrewer",
# "scales",
"patchwork",
# Misc packages
"tidyverse", # Data manipulation iron man
"tictoc" # Code timing
)
PKDHS data pooling pre-checks
Getting started
Here we show the pre-requisite code sections. Run these at the outset to avoid errors. First we load the required packages.
Next we turn off scientific notations.
options(scipen = 999)
Next we set the default gtsummary print engine for tables.
theme_gtsummary_printer(print_engine = "flextable")
Now we set the flextable output defaults.
set_flextable_defaults(
font.size = 11,
text.align = "left",
big.mark = "",
background.color = "white",
table.layout = "autofit",
theme_fun = theme_vanilla
)
Document introduction
Here we document the variable codes and labels of variables across all the Pakistan Demographic and Health Survey (DHS) datasets. We check the variable labels and codes before running the pooling code in “daprep-v01_pkdhs.R”. We pool the following Pakistan DHS surveys:
# Creating the table of surveys to be used for pooling
|>
pkbr1_tmp_intro mutate(n_births = prettyNum(n_births, big.mark = ",")) |>
select(c(ctr_name, svy_year, n_births)) |>
# Join vars from pkir_tmp_intro
left_join(
|>
pkir1_tmp_intro mutate(n_women = prettyNum(n_women, big.mark = ",")) |>
select(c(year, n_women)),
by = join_by(svy_year == year)
|>
) # Join vars from pkhr_tmp_intro
left_join(
|>
pkhr1_tmp_intro mutate(n_households = prettyNum(n_households, big.mark = ",")) |>
select(svy_year, n_households),
by = join_by(svy_year)
|>
) # Join vars from pkpr_tmp_intro
left_join(
|>
pkpr1_tmp_intro mutate(n_persons = prettyNum(n_persons, big.mark = ",")) |>
select(svy_year, n_persons),
by = join_by(svy_year)
|>
) # convert nested tibble to simple tibble
unnest(cols = c()) |>
mutate(
ccode = row_number(),
.before = ctr_name
|>
) # convert to flextable object
qflextable() |>
align(align = "left", part = "all") |>
autofit()
ccode | ctr_name | svy_year | n_births | n_women | n_households | n_persons |
---|---|---|---|---|---|---|
1 | Pakistan | 1990 | 27,369 | 6,611 | 7,193 | 52,358 |
2 | Pakistan | 2006 | 39,049 | 10,023 | 95,441 | 727,493 |
3 | Pakistan | 2012 | 50,238 | 13,558 | 12,943 | 94,169 |
4 | Pakistan | 2017 | 50,495 | 15,068 | 14,540 | 100,869 |
We use the following variables for the pooled data analysis:
- Dependent variable
- infantd = Index child died during infancy period (0-11 months)
- Main Independent variable
- sibsurv_nmv = Survival status of preceding child (Death scarring)
- binterval_3c_nmv_opp = Birth interval preceding to index child
- Independent variables [CHILD LEVEL]
- cyob10y_opp = Birth cohort of index child
- bord_c = Birth order of index child
- sex_fm = Gender of index child
- season = Season during birth
- Independent variables [MOTHER/PARENT LEVEL]
myob_opp = Birth cohort of mother- macb_c_opp = Mother’s age during birth of index child
- medu_opp = Mother’s Level of education
- fedu_opp = Father’s level of education
- Independent variables [HOUSEHOLD LEVEL]
- religion = Religion
- nat_lang = Native language of respondent
- wi_qt_opp = Household wealth quintile
hhgen_2c_opp = Generations in household- hhstruc_opp = Household structure
- head_sex_fm = Sex of HH head
- Independent variables [COMMUNITY LEVEL]
- por = Place of residence of the household
- ecoreg = Ecological region
Note: (a) Crossed names indicates variable not included.
Data import
We will directly import the nested tibble here. The code for dataset preparation is in the “daprep-v01_pkdhs.R” script file.
# Here we import the tibbles to be used for dataset checking
# Import the pkbr nested tibble
<- read_rds(file = here("website_data", "pkbr1_nest0.rds"))
pkbr1_pre_tmp0 # Import the pkhr nested tibble
<- read_rds(file = here("website_data", "pkhr1_nest0.rds"))
pkhr1_pre_tmp0 # Import the pkpr nested tibble
<- read_rds(file = here("website_data", "pkpr1_nest0.rds")) pkpr1_pre_tmp0
Pakistan BR dataset use for variable creation
Checking the Women’s weight variable before harmonization
We will check the formatting of the v005 women’s weight variable before creating the pooled survey weight. For this we will use the labelled::look_for().
# First we create the data dictionary of v005 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_v005 = map(
pkbr_data,
\(df) {|>
df select(v005) |>
look_for(details = "full") |>
# For correctly viewing the range column in data dictionary
convert_list_columns_to_character() |>
select(-c(levels:n_na))
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_v005)) |>
select(-pos)
# Convert and view the tibble as flextable
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | svy_year | variable | label | col_type | missing | unique_values | range |
---|---|---|---|---|---|---|---|
Pakistan | 1990 | v005 | sample weight | dbl | 0 | 407 | 13412 - 9562829 |
Pakistan | 2006 | v005 | sample weight | dbl | 0 | 970 | 21531 - 4605956 |
Pakistan | 2012 | v005 | Women's individual sample weight (6 decimals) | dbl | 0 | 491 | 10191 - 7939165 |
Pakistan | 2017 | v005 | women's individual sample weight (6 decimals) | dbl | 0 | 451 | 0 - 4095189 |
The women’s weight variables are in numeric class and have no missing values. However, in Pakistan DHS 2017 some observations have weight 0. Find out why?? Therefore, we need to reformat them. Before we directly use it for preparing the pooled survey weight.
TBD
Checking the ID variables before harmonization
Here we check the formatting of the variables using which we will prepare the ID variables for the pooled Pakistan birth history recode (br) dataset. We will use the following constituent variables for creating the ID variables for the pooled dataset:
# We check the var type of ID vars in all pkbr datasets.
# First we create a data dictionary of the pkbr datasets in nested tibble.
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_idvars = map(
pkbr_data,
\(df) {|>
df select(v001, v002, v003, bord, v021, v022, v023, v024) |>
lookfor(details = "full") |>
select(-c(levels:n_na)) |>
# For correctly viewing the range column in data dictionary
convert_list_columns_to_character()
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and output the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_idvars)) |>
arrange(pos)
# Convert and view the tibble as flextable
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | svy_year | pos | variable | label | col_type | missing | unique_values | range |
---|---|---|---|---|---|---|---|---|
Pakistan | 1990 | 1 | v001 | cluster number | dbl | 0 | 407 | 1101001 - 4204052 |
Pakistan | 2006 | 1 | v001 | cluster number | dbl | 0 | 970 | 1 - 980 |
Pakistan | 2012 | 1 | v001 | Cluster number | dbl | 0 | 498 | 1 - 500 |
Pakistan | 2017 | 1 | v001 | cluster number | dbl | 0 | 561 | 1 - 580 |
Pakistan | 1990 | 2 | v002 | household number | dbl | 0 | 25 | 1 - 25 |
Pakistan | 2006 | 2 | v002 | household number | dbl | 0 | 87 | 1 - 104 |
Pakistan | 2012 | 2 | v002 | Household number | dbl | 0 | 28 | 1 - 28 |
Pakistan | 2017 | 2 | v002 | household number | dbl | 0 | 29 | 1 - 29 |
Pakistan | 1990 | 3 | v003 | respondent's line number | dbl | 0 | 31 | 1 - 53 |
Pakistan | 2006 | 3 | v003 | respondent's line number | dbl | 0 | 35 | 1 - 43 |
Pakistan | 2012 | 3 | v003 | Respondent's line number | dbl | 0 | 39 | 1 - 47 |
Pakistan | 2017 | 3 | v003 | respondent's line number | dbl | 0 | 31 | 1 - 40 |
Pakistan | 1990 | 4 | bord | birth order number | dbl | 0 | 16 | 1 - 16 |
Pakistan | 2006 | 4 | bord | birth order number | dbl | 0 | 16 | 1 - 16 |
Pakistan | 2012 | 4 | bord | Birth order number | dbl | 0 | 19 | 1 - 19 |
Pakistan | 2017 | 4 | bord | birth order number | dbl | 0 | 15 | 1 - 15 |
Pakistan | 1990 | 5 | v021 | primary sampling unit | dbl | 0 | 407 | 1 - 407 |
Pakistan | 2006 | 5 | v021 | primary sampling unit | dbl | 0 | 970 | 1 - 980 |
Pakistan | 2012 | 5 | v021 | Primary sampling unit | dbl | 0 | 498 | 1 - 500 |
Pakistan | 2017 | 5 | v021 | primary sampling unit | dbl | 0 | 561 | 1 - 580 |
Pakistan | 1990 | 6 | v022 | sample stratum number | dbl | 0 | 180 | 1 - 183 |
Pakistan | 2006 | 6 | v022 | sample stratum number | dbl | 0 | 483 | 1 - 483 |
Pakistan | 2012 | 6 | v022 | Sample strata for sampling errors | dbl | 0 | 78 | 1 - 78 |
Pakistan | 2017 | 6 | v022 | sample strata for sampling errors | dbl+lbl | 0 | 16 | 1 - 16 |
Pakistan | 1990 | 7 | v023 | sample domain | dbl+lbl | 0 | 12 | 11 - 43 |
Pakistan | 2006 | 7 | v023 | sample domain | dbl+lbl | 0 | 4 | 1 - 4 |
Pakistan | 2012 | 7 | v023 | Stratification used in sample design | dbl+lbl | 0 | 10 | 1 - 10 |
Pakistan | 2017 | 7 | v023 | stratification used in sample design | dbl+lbl | 0 | 16 | 1 - 16 |
Pakistan | 1990 | 8 | v024 | region | dbl+lbl | 0 | 4 | 1 - 4 |
Pakistan | 2006 | 8 | v024 | region | dbl+lbl | 0 | 4 | 1 - 4 |
Pakistan | 2012 | 8 | v024 | Region | dbl+lbl | 0 | 6 | 1 - 6 |
Pakistan | 2017 | 8 | v024 | region | dbl+lbl | 0 | 8 | 1 - 8 |
From the above we can see that v023 and v024 are of labelled class, while the rest are in numeric class. Therefore, we will check the numeric and labelled variables in different ways. Note that although survey year is a constituent ID variable we have not checked it. It is imperative that survey year would be a 4-digit variable.
Numeric ID variables check
First, let’s find out the required length of the numeric ID variables by checking the maximum values of the constituent ID variable across the Pakistan DHS datasets. Here we estimate the summary stats of numeric constituent variables using skim_without_charts().
# Check the summary stats for ID vars using skimr in each pkbr dataset.
# First we estimate the summary stats using skim_without_charts().
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(
skim_id_num = map(
pkbr_data,function(df) {
|>
df select(v001, v002, v003, bord, v021, v022) |>
skim_without_charts() |>
as_tibble() |>
select(-c(skim_type, n_missing, complete_rate)) |>
rename(
variable = 1,
mean = 2,
sd = 3,
min = 4,
p25 = 5,
p50 = 6,
p75 = 7,
max = 8
)
}
)
) pkbr1_pre_tmp1
Next, we check the summary stats of numeric variables by variable name-wise.
# Now we unnest the nested tibble so that we can compare the variable length
# across the pkbr datasets.
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(skim_id_num)) |>
arrange(variable, svy_year) |>
# change the decimal places of selected variables
mutate(
mean = sprintf("%.1f", mean),
sd = sprintf("%.1f", sd),
p75 = sprintf("%.0f", p75)
)# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | svy_year | variable | mean | sd | min | p25 | p50 | p75 | max |
---|---|---|---|---|---|---|---|---|---|
Pakistan | 1990 | bord | 3.6 | 2.4 | 1 | 2 | 3 | 5 | 16 |
Pakistan | 2006 | bord | 3.5 | 2.3 | 1 | 2 | 3 | 5 | 16 |
Pakistan | 2012 | bord | 3.4 | 2.3 | 1 | 2 | 3 | 5 | 19 |
Pakistan | 2017 | bord | 3.1 | 2.1 | 1 | 1 | 3 | 4 | 15 |
Pakistan | 1990 | v001 | 2366771.9 | 1031851.2 | 1101001 | 1217015 | 2201003 | 3201024 | 4204052 |
Pakistan | 2006 | v001 | 510.9 | 284.3 | 1 | 272 | 514 | 759 | 980 |
Pakistan | 2012 | v001 | 251.6 | 138.6 | 1 | 134 | 259 | 370 | 500 |
Pakistan | 2017 | v001 | 283.9 | 165.2 | 1 | 141 | 279 | 414 | 580 |
Pakistan | 1990 | v002 | 10.3 | 6.0 | 1 | 5 | 10 | 15 | 25 |
Pakistan | 2006 | v002 | 51.7 | 29.1 | 1 | 27 | 49 | 77 | 104 |
Pakistan | 2012 | v002 | 14.4 | 8.1 | 1 | 7 | 14 | 21 | 28 |
Pakistan | 2017 | v002 | 14.3 | 8.1 | 1 | 7 | 14 | 21 | 29 |
Pakistan | 1990 | v003 | 2.9 | 2.7 | 1 | 2 | 2 | 2 | 53 |
Pakistan | 2006 | v003 | 3.3 | 3.4 | 1 | 2 | 2 | 2 | 43 |
Pakistan | 2012 | v003 | 3.2 | 3.3 | 1 | 2 | 2 | 2 | 47 |
Pakistan | 2017 | v003 | 3.0 | 2.7 | 1 | 2 | 2 | 3 | 40 |
Pakistan | 1990 | v021 | 215.0 | 113.9 | 1 | 120 | 226 | 312 | 407 |
Pakistan | 2006 | v021 | 510.9 | 284.3 | 1 | 272 | 514 | 759 | 980 |
Pakistan | 2012 | v021 | 251.6 | 138.6 | 1 | 134 | 259 | 370 | 500 |
Pakistan | 2017 | v021 | 283.9 | 165.2 | 1 | 141 | 279 | 414 | 580 |
Pakistan | 1990 | v022 | 98.8 | 50.8 | 1 | 57 | 106 | 141 | 183 |
Pakistan | 2006 | v022 | 253.8 | 140.4 | 1 | 136 | 256 | 377 | 483 |
Pakistan | 2012 | v022 | 43.5 | 22.9 | 1 | 26 | 44 | 64 | 78 |
Pakistan | 2017 | v022 | 6.8 | 4.6 | 1 | 3 | 6 | 10 | 16 |
Now we find out the required length of the numeric ID variables to be set, so that we can correctly concatenate them to create the ID variables. The required length of the numeric ID variables are given in max_digits column. Note that survey year is also a constituent ID variable of 4-digits.
# Processing the above nested tibble further
<- pkbr1_pre_tmp2 |>
pkbr1_pre_tmp3 group_by(variable) |>
# find the minimum and maximum values across surveys
summarize(
min_val = min(min),
max_val = max(max)
|>
) mutate(
# calculate the num of digits in the maximum values
max_digits = nchar(as.character(max_val)),
# convert char var to factor
variable = fct(
variable, levels = c("v001", "v002", "v003", "bord", "v021", "v022")
)|>
) # sort the rows by factor levels
arrange(variable) |>
# add variable labels and relocate it after variable name.
bind_cols(vlabel = c("cluster number", "household number",
"respondent's line number", "birth order",
"primary sampling unit", "sample strata for se")) |>
relocate(vlabel, .after = 1)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp3 qflextable() |>
align(align = "left", part = "all") |>
autofit()
variable | vlabel | min_val | max_val | max_digits |
---|---|---|---|---|
v001 | cluster number | 1 | 4204052 | 7 |
v002 | household number | 1 | 104 | 3 |
v003 | respondent's line number | 1 | 53 | 2 |
bord | birth order | 1 | 19 | 2 |
v021 | primary sampling unit | 1 | 980 | 3 |
v022 | sample strata for se | 1 | 483 | 3 |
Labelled ID variables check
First we check the labels in sub-national region variable coded as v024 across the pkbr datasets. Let’s create a nested tibble of v024’s value labels.
# Create the data dictionary for v024 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_v024 = map(
pkbr_data,
\(df) {|>
df select(v024) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkbr1_pre_tmp1
Now we view the value labels of v024 in the table below.
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_v024)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkbr_"
|>
) # Show the variable name in a col
mutate(var_name = "v024", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkbr_1990 | pkbr_2006 | pkbr_2012 | pkbr_2017 |
---|---|---|---|---|---|---|
Pakistan | v024 | 1 | [1] punjab | [1] punjab | [1] Punjab | [1] punjab |
Pakistan | v024 | 2 | [2] sindh | [2] sindh | [2] Sindh | [2] sindh |
Pakistan | v024 | 3 | [3] nw frontier | [3] nwfp | [3] Khyber Pakhtunkhwa | [3] kpk |
Pakistan | v024 | 4 | [4] balochistan | [4] balochistan | [4] Balochistan | [4] balochistan |
Pakistan | v024 | 5 | [5] Gilgit Baltistan | [5] gb | ||
Pakistan | v024 | 6 | [6] Islamabad (ICT) | [6] ict | ||
Pakistan | v024 | 7 | [7] ajk | |||
Pakistan | v024 | 8 | [8] fata |
NOTE: The sub-national region var, v024 has different label values in each survey year. It was same for pkbr 1996, 2001 and 2006. After that the label values are different for each survey round.
VERD: In this analysis, we do not use the region var in the ID var.
Secondly, we check the labels in v023 variable that denotes the stratifications used for sampling design. First we create a nested tibble of v023’s value labels.
# Create the data dictionary for v023 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_v023 = map(
pkbr_data,
\(df) {|>
df select(v023) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkbr1_pre_tmp1
Now we view the value labels of v023 in the table below.
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_v023)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkbr_"
|>
) # Show the variable name in a col
mutate(var_name = "v023", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkbr_1990 | pkbr_2006 | pkbr_2012 | pkbr_2017 |
---|---|---|---|---|---|---|
Pakistan | v023 | 1 | [1] punjab | [1] Punjab urban | [1] punjab rural | |
Pakistan | v023 | 2 | [2] sindh | [2] Punjab rural | [2] punjab urban | |
Pakistan | v023 | 3 | [3] nwfp | [3] Sindh urban | [3] sindh rural | |
Pakistan | v023 | 4 | [4] balochistan | [4] Sindh rural | [4] sindh urban | |
Pakistan | v023 | 5 | [5] KPK urban | [5] kpk rural | ||
Pakistan | v023 | 6 | [6] KPK rural | [6] kpk urban | ||
Pakistan | v023 | 7 | [7] Balochistan urban | [7] balochistan rural | ||
Pakistan | v023 | 8 | [8] Balochistan rural | [8] balochistan urban | ||
Pakistan | v023 | 9 | [9] Gilgit Baltistan | [9] gb rural | ||
Pakistan | v023 | 10 | [10] Islamabad (ICT) | [10] gb urban | ||
Pakistan | v023 | 11 | [11] punjab large city | [11] ict rural | ||
Pakistan | v023 | 12 | [12] punjab small city | [12] ict urban | ||
Pakistan | v023 | 13 | [13] punjab rural | [13] ajk rural | ||
Pakistan | v023 | 14 | [14] ajk urban | |||
Pakistan | v023 | 15 | [15] fata rural | |||
Pakistan | v023 | 16 | [16] fata urban | |||
Pakistan | v023 | 21 | [21] sindh large city | |||
Pakistan | v023 | 22 | [22] sindh small city | |||
Pakistan | v023 | 23 | [23] sindh rural | |||
Pakistan | v023 | 31 | [31] nw frontier lrg city | |||
Pakistan | v023 | 32 | [32] nw frontier sml city | |||
Pakistan | v023 | 33 | [33] nw frontier rural | |||
Pakistan | v023 | 41 | [41] balochistan lrg city | |||
Pakistan | v023 | 42 | [42] balochistan sml city | |||
Pakistan | v023 | 43 | [43] balochistan rural |
NOTE: The labels of v023 are different across the survey rounds.
VERD: Therefore we cannot use v023 in the ID variable preparation.
Altly, we can use the ecological region variable (secoreg) in the ID var. We will check for this in future.
Checking the Birth History variables before harmonization
Undoubtedly the birth history variables are important for this study objective. Therefore, we need to scrutinize all the birth history variables before using them to prepare harmonized variables for the pooled dataset.
# We check the birth history vars in all pkbr datasets.
# First we create a data dictionary in nested tibble.
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_bhvars = map(
pkbr_data,
\(df) {|>
df select(bidx, matches("^b[0-9]+")) |>
lookfor(details = "full") |>
select(-c(levels:n_na)) |>
# For correctly viewing the range column in data dictionary
convert_list_columns_to_character()
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_bhvars)) |>
arrange(pos)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | svy_year | pos | variable | label | col_type | missing | unique_values | range |
---|---|---|---|---|---|---|---|---|
Pakistan | 1990 | 1 | bidx | birth column number | dbl | 0 | 16 | 1 - 16 |
Pakistan | 2006 | 1 | bidx | birth column number | dbl | 0 | 16 | 1 - 16 |
Pakistan | 2012 | 1 | bidx | Birth column number | dbl | 0 | 19 | 1 - 19 |
Pakistan | 2017 | 1 | bidx | birth column number | dbl | 0 | 15 | 1 - 15 |
Pakistan | 1990 | 2 | b0 | child is twin | dbl+lbl | 0 | 4 | 0 - 3 |
Pakistan | 2006 | 2 | b0 | child is twin | dbl+lbl | 0 | 4 | 0 - 3 |
Pakistan | 2012 | 2 | b0 | Child is twin | dbl+lbl | 0 | 4 | 0 - 3 |
Pakistan | 2017 | 2 | b0 | child is twin | dbl+lbl | 0 | 4 | 0 - 3 |
Pakistan | 1990 | 3 | b1 | month of birth | dbl | 0 | 12 | 1 - 12 |
Pakistan | 2006 | 3 | b1 | month of birth | dbl | 0 | 12 | 1 - 12 |
Pakistan | 2012 | 3 | b1 | Month of birth | dbl | 0 | 12 | 1 - 12 |
Pakistan | 2017 | 3 | b1 | month of birth | dbl | 0 | 12 | 1 - 12 |
Pakistan | 1990 | 4 | b2 | year of birth | dbl | 0 | 39 | 52 - 91 |
Pakistan | 2006 | 4 | b2 | year of birth | dbl | 0 | 38 | 1970 - 2007 |
Pakistan | 2012 | 4 | b2 | Year of birth | dbl | 0 | 38 | 1976 - 2013 |
Pakistan | 2017 | 4 | b2 | year of birth | dbl | 0 | 37 | 1982 - 2018 |
Pakistan | 1990 | 5 | b3 | date of birth (cmc) | dbl | 0 | 415 | 635 - 1098 |
Pakistan | 2006 | 5 | b3 | date of birth (cmc) | dbl | 0 | 419 | 852 - 1286 |
Pakistan | 2012 | 5 | b3 | Date of birth (CMC) | dbl | 0 | 430 | 914 - 1359 |
Pakistan | 2017 | 5 | b3 | date of birth (cmc) | dbl | 0 | 413 | 988 - 1420 |
Pakistan | 1990 | 6 | b4 | sex of child | dbl+lbl | 0 | 2 | 1 - 2 |
Pakistan | 2006 | 6 | b4 | sex of child | dbl+lbl | 0 | 2 | 1 - 2 |
Pakistan | 2012 | 6 | b4 | Sex of child | dbl+lbl | 0 | 2 | 1 - 2 |
Pakistan | 2017 | 6 | b4 | sex of child | dbl+lbl | 0 | 2 | 1 - 2 |
Pakistan | 1990 | 7 | b5 | child is alive | dbl+lbl | 0 | 2 | 0 - 1 |
Pakistan | 2006 | 7 | b5 | child is alive | dbl+lbl | 0 | 2 | 0 - 1 |
Pakistan | 2012 | 7 | b5 | Child is alive | dbl+lbl | 0 | 2 | 0 - 1 |
Pakistan | 2017 | 7 | b5 | child is alive | dbl+lbl | 0 | 2 | 0 - 1 |
Pakistan | 1990 | 8 | b6 | age at death | dbl+lbl | 24210 | 83 | 100 - 397 |
Pakistan | 2006 | 8 | b6 | age at death | dbl+lbl | 34937 | 89 | 100 - 999 |
Pakistan | 2012 | 8 | b6 | Age at death | dbl+lbl | 45162 | 85 | 100 - 998 |
Pakistan | 2017 | 8 | b6 | age at death | dbl+lbl | 46660 | 80 | 100 - 330 |
Pakistan | 1990 | 9 | b7 | age at death (months-imputed) | dbl | 24194 | 48 | 0 - 300 |
Pakistan | 2006 | 9 | b7 | age at death (months-imputed) | dbl | 34937 | 57 | 0 - 396 |
Pakistan | 2012 | 9 | b7 | Age at death (months, imputed) | dbl | 45162 | 53 | 0 - 372 |
Pakistan | 2017 | 9 | b7 | age at death (months, imputed) | dbl | 46660 | 53 | 0 - 360 |
Pakistan | 1990 | 10 | b8 | current age of child | dbl | 3175 | 39 | 0 - 38 |
Pakistan | 2006 | 10 | b8 | current age of child | dbl | 4112 | 38 | 0 - 36 |
Pakistan | 2012 | 10 | b8 | Current age of child | dbl | 5076 | 38 | 0 - 36 |
Pakistan | 2017 | 10 | b8 | current age of child | dbl | 3835 | 37 | 0 - 35 |
Pakistan | 1990 | 11 | b9 | who child lives with | dbl+lbl | 3183 | 6 | 0 - 4 |
Pakistan | 2006 | 11 | b9 | child lives with whom | dbl+lbl | 4112 | 3 | 0 - 4 |
Pakistan | 2012 | 11 | b9 | Child lives with whom | dbl+lbl | 5076 | 3 | 0 - 4 |
Pakistan | 2017 | 11 | b9 | child lives with whom | dbl+lbl | 3835 | 3 | 0 - 4 |
Pakistan | 1990 | 12 | b10 | completeness of information | dbl+lbl | 0 | 8 | 1 - 8 |
Pakistan | 2006 | 12 | b10 | completeness of information | dbl+lbl | 0 | 8 | 1 - 8 |
Pakistan | 2012 | 12 | b10 | Completeness of information | dbl+lbl | 0 | 6 | 1 - 8 |
Pakistan | 2017 | 12 | b10 | completeness of information | dbl+lbl | 0 | 8 | 0 - 8 |
Pakistan | 1990 | 13 | b11 | preceding birth interval | dbl | 5926 | 146 | 7 - 221 |
Pakistan | 2006 | 13 | b11 | preceding birth interval | dbl | 8856 | 159 | 9 - 255 |
Pakistan | 2012 | 13 | b11 | Preceding birth interval (months) | dbl | 12050 | 171 | 9 - 241 |
Pakistan | 2017 | 13 | b11 | preceding birth interval (months) | dbl | 13235 | 166 | 7 - 236 |
Pakistan | 1990 | 14 | b12 | succeeding birth interval | dbl | 5972 | 146 | 7 - 221 |
Pakistan | 2006 | 14 | b12 | succeeding birth interval | dbl | 8911 | 159 | 9 - 255 |
Pakistan | 2012 | 14 | b12 | Succeeding birth interval (months) | dbl | 12127 | 171 | 9 - 241 |
Pakistan | 2017 | 14 | b12 | succeeding birth interval (months) | dbl | 13325 | 166 | 7 - 236 |
Pakistan | 1990 | 15 | b13 | flag for age at death | dbl+lbl | 24194 | 8 | 0 - 8 |
Pakistan | 2006 | 15 | b13 | flag for age at death | dbl+lbl | 34937 | 7 | 0 - 8 |
Pakistan | 2012 | 15 | b13 | Flag for age at death | dbl+lbl | 45162 | 4 | 0 - 8 |
Pakistan | 2017 | 15 | b13 | flag for age at death | dbl+lbl | 46660 | 3 | 0 - 1 |
Pakistan | 2006 | 16 | b15 | live birth between births | dbl+lbl | 0 | 3 | 0 - 9 |
Pakistan | 2012 | 16 | b15 | Live birth between births | dbl+lbl | 10726 | 4 | 0 - 9 |
Pakistan | 2017 | 16 | b15 | live birth between births | dbl+lbl | 11738 | 3 | 0 - 1 |
Pakistan | 2006 | 17 | b16 | child's line number in household | dbl+lbl | 4112 | 48 | 0 - 46 |
Pakistan | 2012 | 17 | b16 | Child's line number in household | dbl+lbl | 5076 | 50 | 0 - 48 |
Pakistan | 2017 | 17 | b16 | child's line number in household | dbl+lbl | 3835 | 43 | 0 - 43 |
Pakistan | 2017 | 18 | b17 | day of birth | dbl | 0 | 31 | 1 - 31 |
Pakistan | 2017 | 19 | b18 | century day code of birth (cdc) | dbl | 0 | 10013 | 30071 - 43195 |
Pakistan | 2017 | 20 | b19 | current age of child in months (months since birth for dead children) | dbl | 0 | 412 | 0 - 429 |
Pakistan | 2017 | 21 | b20 | na - duration of pregnancy | dbl | 50495 | 1 |
From the above table we get an overall snapshot of the birth history variables. We see that the variables b1-b13 are common in all the six pkbr datasets. Notably pkbr 2001 and 2006 have some extra variables that are not available in other rounds. Next, we look at the other labelled variables which are common across pkbr in more details. We would like to see if the value labels of the common birth history variables are similar across the pkbr datasets.
b0 - child is twin
We check the value labels of b0 variable that denotes whether the child is twin. First we create a nested tibble of b0’s value labels.
# Create the data dictionary for b0 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_b0 = map(
pkbr_data,
\(df) {|>
df select(b0) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_b0)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkbr_"
|>
) # Show the variable name in a col
mutate(var_name = "b0", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkbr_1990 | pkbr_2006 | pkbr_2012 | pkbr_2017 |
---|---|---|---|---|---|---|
Pakistan | b0 | 0 | [0] single birth | [0] single birth | [0] Single birth | [0] single birth |
Pakistan | b0 | 1 | [1] 1st of multiple | [1] 1st of multiple | [1] 1st of multiple | [1] 1st of multiple |
Pakistan | b0 | 2 | [2] 2nd of multiple | [2] 2nd of multiple | [2] 2nd of multiple | [2] 2nd of multiple |
Pakistan | b0 | 3 | [3] 3rd of multiple | [3] 3rd of multiple | [3] 3rd of multiple | [3] 3rd of multiple |
Pakistan | b0 | 4 | [4] 4th of multiple | [4] 4th of multiple | [4] 4th of multiple | [4] 4th of multiple |
Pakistan | b0 | 5 | [5] 5th of multiple | [5] 5th of multiple | [5] 5th of multiple | [5] 5th of multiple |
We can see the value labels of b0 in the above table. We see that the value labels are same across all the pkbr datasets.
b4 - sex of child
We check the value labels of b4 variable which gives the sex of the child. First we create a nested tibble of b4’s value labels.
# Create the data dictionary for b4 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_b4 = map(
pkbr_data,
\(df) {|>
df select(b4) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_b4)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkbr_"
|>
) # Show the variable name in a col
mutate(var_name = "b4", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkbr_1990 | pkbr_2006 | pkbr_2012 | pkbr_2017 |
---|---|---|---|---|---|---|
Pakistan | b4 | 1 | [1] male | [1] male | [1] Male | [1] male |
Pakistan | b4 | 2 | [2] female | [2] female | [2] Female | [2] female |
We can see the value labels of b4 in the above table. The value labels are same across all the pkbr datasets.
b5 - child is alive
We check the value labels of b5 variable which gives the survival status of the child. First we create a nested tibble of b5’s value labels.
# Create the data dictionary for b5 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_b5 = map(
pkbr_data,
\(df) {|>
df select(b5) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_b5)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkbr_"
|>
) # Show the variable name in a col
mutate(var_name = "b5", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkbr_1990 | pkbr_2006 | pkbr_2012 | pkbr_2017 |
---|---|---|---|---|---|---|
Pakistan | b5 | 0 | [0] no | [0] no | [0] No | [0] no |
Pakistan | b5 | 1 | [1] yes | [1] yes | [1] Yes | [1] yes |
The above table shows that the value labels of survival status of child are same across all the pkbr datasets.
b6 - age at death
We check the value labels of b6 variable which shows the age at death of children. Note that this variable has many missing values across all pkbr rounds as not all children experienced mortality throughout their lifetime. First we create a nested tibble of b6’s value labels.
# Create the data dictionary for b5 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_b6 = map(
pkbr_data,
\(df) {|>
df select(b6) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_b6)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkbr_"
|>
) # Show the variable name in a col
mutate(var_name = "b6", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkbr_1990 | pkbr_2006 | pkbr_2012 | pkbr_2017 |
---|---|---|---|---|---|---|
Pakistan | b6 | 100 | [100] 0 days | [100] 0 days | [100] Died on day of birth | [100] died on day of birth |
Pakistan | b6 | 101 | [101] Days: 1 | [101] days: 1 | ||
Pakistan | b6 | 199 | [199] days missing | [199] Days: number missing | [199] days: number missing | |
Pakistan | b6 | 201 | [201] one month | [201] 1 month | [201] Months: 1 | [201] months: 1 |
Pakistan | b6 | 299 | [299] months missing | [299] Months: number missing | [299] months: number missing | |
Pakistan | b6 | 301 | [301] one year | [301] 1 year | [301] Years: 1 | [301] years: 1 |
Pakistan | b6 | 397 | [397] years inconsistent | |||
Pakistan | b6 | 399 | [399] Years: number missing | [399] years: number missing | ||
Pakistan | b6 | 997 | [997] inconsistent | [997] inconsistent | [997] Inconsistent | [997] inconsistent |
Pakistan | b6 | 998 | [998] don't know | [998] don't know | [998] Don't know | [998] don't know |
The above table shows that the value labels of age at death of child are in two groups. First, they are same for pkbr 1996, 2001 and 2006 and and then for pkbr 2011, 2016 and 2022.
b9 - child lives with whom
We check the value labels of b9 variable which gives info on who the child lives with. First we create a nested tibble of b9’s value labels.
# Create the data dictionary for b9 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_b9 = map(
pkbr_data,
\(df) {|>
df select(b9) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_b9)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkbr_"
|>
) # Show the variable name in a col
mutate(var_name = "b9", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkbr_1990 | pkbr_2006 | pkbr_2012 | pkbr_2017 |
---|---|---|---|---|---|---|
Pakistan | b9 | 0 | [0] respondent | [0] respondent | [0] Respondent | [0] respondent |
Pakistan | b9 | 1 | [1] father | [1] father | [1] Father | [1] father |
Pakistan | b9 | 2 | [2] other relative | [2] other relative | [2] Other relative | [2] other relative |
Pakistan | b9 | 3 | [3] someone else | [3] someone else | [3] Someone else | [3] someone else |
Pakistan | b9 | 4 | [4] 15+ & live elsewhere | [4] lives elsewhere | [4] Lives elsewhere | [4] lives elsewhere |
We can see in the above table that the value labels of b9 are same across all the pkbr datasets.
b10 - completeness of information
We check the value labels of b10 variable which gives the completeness of birth history information. First we create a nested tibble of b10’s value labels.
# Create the data dictionary for b10 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_b10 = map(
pkbr_data,
\(df) {|>
df select(b10) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_b10)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkbr_"
|>
) # Show the variable name in a col
mutate(var_name = "b10", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkbr_1990 | pkbr_2006 | pkbr_2012 | pkbr_2017 |
---|---|---|---|---|---|---|
Pakistan | b10 | 0 | [0] month, year and day | |||
Pakistan | b10 | 1 | [1] month and year | [1] month and year | [1] Month and year - information complete | [1] month and year - information complete |
Pakistan | b10 | 2 | [2] month and age -y imp | [2] month and age -y imp | [2] Month and age - year imputed | [2] month and age - year imputed |
Pakistan | b10 | 3 | [3] year and age - m imp | [3] year and age - m imp | [3] Year and age - month imputed | [3] year and age - month imputed |
Pakistan | b10 | 4 | [4] y & age - y ignored | [4] y & age - y ignored | [4] Year and age - year ignored | [4] year and age - year ignored |
Pakistan | b10 | 5 | [5] year - a, m imp | [5] year - a, m imp | [5] Year - age/month imputed | [5] year - age/month imputed |
Pakistan | b10 | 6 | [6] age - y, m imp | [6] age - y, m imp | [6] Age - year/month imputed | [6] age - year/month imputed |
Pakistan | b10 | 7 | [7] month - a, y imp | [7] month - a, y imp | [7] Month - age/year imputed | [7] month - age/year imputed |
Pakistan | b10 | 8 | [8] none - all imp | [8] none - all imp | [8] None - all imputed | [8] none - all imputed |
We can see in the above table that the value labels of b10 are same across pkbr 1996, 2001, 2006 and 2011 datasets. Then they are same for pkbr 2016 and 2022.
Checking the Common independent variables before harmonization
Next we start documenting the common independent variables. First we will check the data dictionary of the common independent variables. Then we will check them variable wise.
# We check the common independent vars in all pkbr datasets.
# First we create the data dictionary in nested tibble.
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_comindvars = map(
pkbr_data,
\(df) {|>
df # select the common independent variables
select(v106, v011, v501, v701, v025, v151, v152) |>
lookfor(details = "full") |>
select(-c(levels:n_na)) |>
# For correctly viewing the range column in data dictionary
convert_list_columns_to_character()
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_comindvars)) |>
arrange(pos)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | svy_year | pos | variable | label | col_type | missing | unique_values | range |
---|---|---|---|---|---|---|---|---|
Pakistan | 1990 | 1 | v106 | highest educational level | dbl+lbl | 0 | 4 | 0 - 3 |
Pakistan | 2006 | 1 | v106 | highest educational level | dbl+lbl | 0 | 4 | 0 - 3 |
Pakistan | 2012 | 1 | v106 | Highest educational level | dbl+lbl | 0 | 4 | 0 - 3 |
Pakistan | 2017 | 1 | v106 | highest educational level | dbl+lbl | 0 | 4 | 0 - 3 |
Pakistan | 1990 | 2 | v011 | date of birth (cmc) | dbl | 0 | 409 | 493 - 912 |
Pakistan | 2006 | 2 | v011 | date of birth (cmc) | dbl | 0 | 409 | 683 - 1102 |
Pakistan | 2012 | 2 | v011 | Date of birth (CMC) | dbl | 0 | 402 | 755 - 1164 |
Pakistan | 2017 | 2 | v011 | date of birth (cmc) | dbl | 0 | 410 | 817 - 1233 |
Pakistan | 1990 | 3 | v501 | current marital status | dbl+lbl | 0 | 4 | 1 - 5 |
Pakistan | 2006 | 3 | v501 | current marital status | dbl+lbl | 0 | 4 | 1 - 5 |
Pakistan | 2012 | 3 | v501 | Current marital status | dbl+lbl | 0 | 4 | 1 - 5 |
Pakistan | 2017 | 3 | v501 | current marital status | dbl+lbl | 0 | 4 | 1 - 5 |
Pakistan | 1990 | 4 | v701 | partner's education level | dbl+lbl | 114 | 6 | 0 - 8 |
Pakistan | 2006 | 4 | v701 | partner's education level | dbl+lbl | 0 | 6 | 0 - 9 |
Pakistan | 2012 | 4 | v701 | Husband/partner's education level | dbl+lbl | 0 | 6 | 0 - 9 |
Pakistan | 2017 | 4 | v701 | husband/partner's education level | dbl+lbl | 1872 | 6 | 0 - 8 |
Pakistan | 1990 | 5 | v025 | type of place of residence | dbl+lbl | 0 | 2 | 1 - 2 |
Pakistan | 2006 | 5 | v025 | type of place of residence | dbl+lbl | 0 | 2 | 1 - 2 |
Pakistan | 2012 | 5 | v025 | Type of place of residence | dbl+lbl | 0 | 2 | 1 - 2 |
Pakistan | 2017 | 5 | v025 | type of place of residence | dbl+lbl | 0 | 2 | 1 - 2 |
Pakistan | 1990 | 6 | v151 | sex of household head | dbl+lbl | 0 | 2 | 1 - 2 |
Pakistan | 2006 | 6 | v151 | sex of household head | dbl+lbl | 0 | 2 | 1 - 2 |
Pakistan | 2012 | 6 | v151 | Sex of household head | dbl+lbl | 0 | 2 | 1 - 2 |
Pakistan | 2017 | 6 | v151 | sex of household head | dbl+lbl | 0 | 2 | 1 - 2 |
Pakistan | 1990 | 7 | v152 | age of household head | dbl+lbl | 3 | 79 | 12 - 98 |
Pakistan | 2006 | 7 | v152 | age of household head | dbl+lbl | 0 | 80 | 14 - 99 |
Pakistan | 2012 | 7 | v152 | Age of household head | dbl+lbl | 0 | 77 | 14 - 98 |
Pakistan | 2017 | 7 | v152 | age of household head | dbl+lbl | 0 | 79 | 15 - 95 |
From the above table we get an overall snapshot of the common independent variables. We see that majority of the have different number of value labels across the six pkbr datasets. Only v025 and v151 have the same number of value labels across pkbr rounds. Next, we look at the labelled variables among these common variables in more details. We would like to see if the value labels and codes of the common independent variables are similar across the pkbr datasets.
v106 - Mother’s education level
We check the value labels of v106 variable that denotes the highest education level of mother. First we create a nested tibble of v106’s value labels.
# Create the data dictionary for v106 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_v106 = map(
pkbr_data,
\(df) {|>
df select(v106) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_v106)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkbr_"
|>
) # Show the variable name in a col
mutate(var_name = "v106", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkbr_1990 | pkbr_2006 | pkbr_2012 | pkbr_2017 |
---|---|---|---|---|---|---|
Pakistan | v106 | 0 | [0] no education | [0] no education | [0] No education | [0] no education |
Pakistan | v106 | 1 | [1] primary | [1] primary | [1] Primary | [1] primary |
Pakistan | v106 | 2 | [2] secondary | [2] secondary | [2] Secondary | [2] secondary |
Pakistan | v106 | 3 | [3] higher | [3] higher | [3] Higher | [3] higher |
We can see the value labels of v106 are mostly similar except for pkbr 1996 and 2011 datasets.
v011 - Date of birth (in CMC)
The v011 variable, which has the dob of mothers in cmc, is a numeric variable. Let’s check the range of these values in further details such as checking for outliers. First let’s create a nested tibble of the summary statistics of v011 variable.
# Create the summary statistics for v011 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(skim_v011 = map(
pkbr_data,
\(df) {|>
df select(v011) |>
skim_without_charts() |>
as_tibble() |>
select(-c(skim_type, complete_rate)) |>
rename(
variable = 1,
n_miss = 2,
mean = 3,
sd = 4,
min = 5,
p25 = 6,
p50 = 7,
p75 = 8,
max = 9
)
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(skim_v011)) |>
# Make variable values have one decimal point
mutate(
mean = sprintf("%.1f", mean),
sd = sprintf("%.1f", sd)
)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | svy_year | variable | n_miss | mean | sd | min | p25 | p50 | p75 | max |
---|---|---|---|---|---|---|---|---|---|---|
Pakistan | 1990 | v011 | 0 | 666.1 | 90.8 | 493 | 596 | 665 | 732 | 912 |
Pakistan | 2006 | v011 | 0 | 840.1 | 92.6 | 683 | 763 | 836 | 915 | 1102 |
Pakistan | 2012 | v011 | 0 | 910.9 | 91.5 | 755 | 837 | 907 | 985 | 1164 |
Pakistan | 2017 | v011 | 0 | 979.2 | 89.9 | 817 | 907 | 978 | 1049 | 1233 |
v501 - Mother’s marital status
We check the value labels of v501 variable which gives the current marital status of mother. First we create a nested tibble of v501’s value labels.
# Create the data dictionary for v501 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_v501 = map(
pkbr_data,
\(df) {|>
df select(v501) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_v501)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkbr_"
|>
) # Show the variable name in a col
mutate(var_name = "v501", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkbr_1990 | pkbr_2006 | pkbr_2012 | pkbr_2017 |
---|---|---|---|---|---|---|
Pakistan | v501 | 0 | [0] never married | [0] never married | [0] Never in union | [0] never in union |
Pakistan | v501 | 1 | [1] married | [1] married | [1] Married | [1] married |
Pakistan | v501 | 2 | [2] living together | [2] living together | [2] Living with partner | [2] living with partner |
Pakistan | v501 | 3 | [3] widowed | [3] widowed | [3] Widowed | [3] widowed |
Pakistan | v501 | 4 | [4] divorced | [4] divorced | [4] Divorced | [4] divorced |
Pakistan | v501 | 5 | [5] not living together | [5] not living together | [5] No longer living together/separated | [5] no longer living together/separated |
All the pkbr rounds have 5 value labels. The pkbr 1996, 2001 and 2006 rounds have a set of similar value label texts. Then pkbr 2011, 2016 and 2022 have another set of similar value labels.
v701 - Husband/Partner’s education level
We check the value labels of v701 variable which gives the current marital status of mother. First we create a nested tibble of v701’s value labels.
# Create the data dictionary for v701 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_v701 = map(
pkbr_data,
\(df) {|>
df select(v701) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_v701)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkbr_"
|>
) # Show the variable name in a col
mutate(var_name = "v701", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkbr_1990 | pkbr_2006 | pkbr_2012 | pkbr_2017 |
---|---|---|---|---|---|---|
Pakistan | v701 | 0 | [0] no education | [0] no education | [0] No education | [0] no education |
Pakistan | v701 | 1 | [1] primary | [1] primary | [1] Primary | [1] primary |
Pakistan | v701 | 2 | [2] secondary | [2] secondary | [2] Secondary | [2] secondary |
Pakistan | v701 | 3 | [3] higher | [3] higher | [3] Higher | [3] higher |
Pakistan | v701 | 8 | [8] don't know | [8] don't know level | [8] Don't know | [8] don't know |
All the pkbr rounds have 5 value labels. The pkbr 1996, 2001 and 2006 rounds and pkbr 2011, 2016 and 2022 have a similar set of value labels with a difference in wording among them.
v025 - Type of place of residence
We check the value labels of v025 variable which shows if a household belongs to rural or urban psu. First we create a nested tibble of v025’s value labels.
# Create the data dictionary for v025 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_v025 = map(
pkbr_data,
\(df) {|>
df select(v025) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(c(ctr_name, svy_year, lookfor_v025)) |>
unnest(cols = c(lookfor_v025)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkbr_"
|>
) # Show the variable name in a col
mutate(var_name = "v025", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkbr_1990 | pkbr_2006 | pkbr_2012 | pkbr_2017 |
---|---|---|---|---|---|---|
Pakistan | v025 | 1 | [1] urban | [1] urban | [1] Urban | [1] urban |
Pakistan | v025 | 2 | [2] rural | [2] rural | [2] Rural | [2] rural |
The values labels and codes for v025 are same across all the pkbr rounds.
v151 - Sex of household head
We check the value labels of v151 variable which gives the gender of the household head. First we create a nested tibble of v151’s value labels.
# Create the data dictionary for v151 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 mutate(lookfor_v151 = map(
pkbr_data,
\(df) {|>
df select(v151) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_v151)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkbr_"
|>
) # Show the variable name in a col
mutate(var_name = "v151", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkbr_1990 | pkbr_2006 | pkbr_2012 | pkbr_2017 |
---|---|---|---|---|---|---|
Pakistan | v151 | 1 | [1] male | [1] male | [1] Male | [1] male |
Pakistan | v151 | 2 | [2] female | [2] female | [2] Female | [2] female |
The values labels and codes for v151 are same across all the pkbr rounds.
v152 - Age of household head
Interestingly, we see v152 (a continuous variable) has value labels for all rounds except pkbr 1996. Therefore, we check the value labels of v152 for those rounds. First we create a nested tibble of v152’s value labels.
# Create the data dictionary for v152 in nested tibble
<- pkbr1_pre_tmp0 |>
pkbr1_pre_tmp1 filter(svy_year != 1996) |>
mutate(lookfor_v152 = map(
pkbr_data,
\(df) {|>
df select(v152) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkbr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkbr1_pre_tmp1 |>
pkbr1_pre_tmp2 # First we select the required cols and unnest()
select(-c(unf, pkbr_data, n_births)) |>
unnest(cols = c(lookfor_v152)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkbr_"
|>
) # Show the variable name in a col
mutate(var_name = "v152", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkbr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkbr_1990 | pkbr_2006 | pkbr_2012 | pkbr_2017 |
---|---|---|---|---|---|---|
Pakistan | v152 | 95 | [95] 95+ | |||
Pakistan | v152 | 97 | [97] 97+ | [97] 97+ | [97] 97+ | |
Pakistan | v152 | 98 | [98] dk | [98] dk | [98] Don't know | [98] don't know |
We can see that the value labels of v152 are mostly for missing values. However, since v152 has no missing values across the pkbr rounds, we need not be concerned about them.
Pakistan HH dataset use for variable creation
Checking the ID variables before harmonization
Here we check the formatting of the constituent variables with which we will prepare the ID variables for the pooled Pakistan household recode (hr) dataset. We will use the following constituent variables for creating the ID variables for the pooled dataset:
# We check the var type of ID vars in all pkhr datasets.
# First we create a data dictionary of the pkhr datasets in nested tibble.
<- pkhr1_pre_tmp0 |>
pkhr1_pre_tmp1 mutate(lookfor_idvars = map(
pkhr_data,
\(df) {|>
df select(hv001, hv002) |>
lookfor(details = "full") |>
select(-c(levels:n_na)) |>
# For correctly viewing the range column in data dictionary
convert_list_columns_to_character()
}
)) pkhr1_pre_tmp1
# Now we unnest the tibble and output the pooled data dictionary
<- pkhr1_pre_tmp1 |>
pkhr1_pre_tmp2 select(c(ctr_name, svy_year, lookfor_idvars)) |>
unnest(cols = c(lookfor_idvars)) |>
arrange(pos)
# Convert and view the tibble as flextable
|>
pkhr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | svy_year | pos | variable | label | col_type | missing | unique_values | range |
---|---|---|---|---|---|---|---|---|
Pakistan | 1990 | 1 | hv001 | cluster number | dbl | 0 | 407 | 1101001 - 4204052 |
Pakistan | 2006 | 1 | hv001 | cluster number | dbl | 0 | 972 | 1 - 980 |
Pakistan | 2012 | 1 | hv001 | Cluster number | dbl | 0 | 498 | 1 - 500 |
Pakistan | 2017 | 1 | hv001 | cluster number | dbl | 0 | 561 | 1 - 580 |
Pakistan | 1990 | 2 | hv002 | household number | dbl | 0 | 25 | 1 - 25 |
Pakistan | 2006 | 2 | hv002 | household number | dbl | 0 | 105 | 1 - 105 |
Pakistan | 2012 | 2 | hv002 | Household number | dbl | 0 | 28 | 1 - 28 |
Pakistan | 2017 | 2 | hv002 | household number | dbl | 0 | 29 | 1 - 29 |
From the above we can see that both the hv001 and hv002 are of numeric class with no missing values. These variables can be used for preparing the ID variables after finding the maximum length of their largest value. Note that survey year is also a constituent ID variable of 4-digits and we need not check it.
# We thought to process the above nested tibble further by decomposing the
# "range" col into min and max values using separate_wider_regex().
# However, we hit a roadblock as pattern did not identify the max values in
# some pkhr rounds correctly
<- pkhr1_pre_tmp0 |>
pkhr1_pre_tmp3 # Generate the summary stats for id vars
mutate(skim_idvars = map(pkhr_data, \(df) {
|>
df select(hv001, hv002) |>
skim_without_charts()
|>
})) # Pool the summary stats for all pkhr rounds
select(c(ctr_name, svy_year, skim_idvars)) |>
unnest(cols = c(skim_idvars)) |>
arrange(skim_variable, svy_year) |>
# Group and generate the max and min values for each variable
group_by(variable = skim_variable) |>
summarize(
min_val = min(numeric.p0),
max_val = max(numeric.p100)
|>
) # calculate the num of digits in the maximum values
mutate(
max_digits = nchar(as.character(max_val))
|>
) # add variable labels and relocate it after variable name
bind_cols(vlabel = c("cluster number", "household number")) |>
relocate(vlabel, .after = 1)
# Convert the tibble to flextable for easy viewing
|>
pkhr1_pre_tmp3 qflextable() |>
align(align = "left", part = "all") |>
autofit()
variable | vlabel | min_val | max_val | max_digits |
---|---|---|---|---|
hv001 | cluster number | 1 | 4204052 | 7 |
hv002 | household number | 1 | 105 | 3 |
The above table gives the required length of the constituent ID variables to be set, so that we can correctly concatenate them to create the ID variables. The required length of the ID variables are given in max_digits column. Note that survey year is also a constituent ID variable of 4-digits.
Checking HH-level variables before harmonization
Here we check the wealth quintile variables before harmonizing them. Note in Pakistan 1990 the wealth quintile variables are provided in separate datasets. Therefore we join those variables to the hh file before proceeding with the checking.
Upon manually checking the full data dictionaries we find the variable names. Now we will check the data dictionary of these hh-level variables. Then we will check their value labels variable wise.
# We check the hh-level vars in all pkhr datasets.
# First we create the data dictionary in nested tibble.
<- pkhr1_pre_tmp0 |>
pkhr1_pre_tmp1 mutate(lookfor_hhvars = map(
pkhr_data,
\(df) {|>
df # select the common independent variables
select(matches("^wlthind5$|^hv270$")) |>
lookfor(details = "full") |>
select(-c(levels:n_na)) |>
# For correctly viewing the range column in data dictionary
convert_list_columns_to_character()
}
)) pkhr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkhr1_pre_tmp1 |>
pkhr1_pre_tmp2 select(c(svy_year, lookfor_hhvars)) |>
unnest(cols = c(lookfor_hhvars)) |>
arrange(pos, svy_year)
# Convert the tibble to flextable for easy viewing
|>
pkhr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
svy_year | pos | variable | label | col_type | missing | unique_values | range |
---|---|---|---|---|---|---|---|
1990 | 1 | wlthind5 | quintiles of wealth index | dbl+lbl | 0 | 5 | 1 - 5 |
2006 | 1 | hv270 | wealth index | dbl+lbl | 81597 | 6 | 1 - 5 |
2012 | 1 | hv270 | Wealth index | dbl+lbl | 0 | 5 | 1 - 5 |
2017 | 1 | hv270 | wealth index combined | dbl+lbl | 0 | 5 | 1 - 5 |
The above table gives an overall snapshot of the hh-level variables. All the variables are of labelled class and have the same number of value labels across all the pkhr datasets. Note that, the ecological region variable has a different value label code in the pkbr 1996 dataset. Next, we compare the value labels of the variables across the pkhr datasets.
Wealth index quintile variable
Next, we check the value labels of the household wealth quintile variable. The variable names of this variable differs across the pkbr datasets. First we create a nested tibble of the value labels.
# Create the data dictionary in nested tibble
<- pkhr1_pre_tmp0 |>
pkhr1_pre_tmp1 mutate(lookfor_wiqt = map(
pkhr_data,
\(df) {|>
df select(matches("^wlthind5$|^hv270$")) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
}
)) pkhr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkhr1_pre_tmp1 |>
pkhr1_pre_tmp2 # First we select the required cols and unnest()
select(c(ctr_name, svy_year, lookfor_wiqt)) |>
unnest(cols = c(lookfor_wiqt)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkhr_"
|>
) # Show the variable name in a col
mutate(var_name = "Wealth index quintiles", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkhr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkhr_1990 | pkhr_2006 | pkhr_2012 | pkhr_2017 |
---|---|---|---|---|---|---|
Pakistan | Wealth index quintiles | 1 | [1] lowest quintile | [1] poorest | [1] Poorest | [1] poorest |
Pakistan | Wealth index quintiles | 2 | [2] second quintile | [2] poorer | [2] Poorer | [2] poorer |
Pakistan | Wealth index quintiles | 3 | [3] middle quintile | [3] middle | [3] Middle | [3] middle |
Pakistan | Wealth index quintiles | 4 | [4] fourth quintile | [4] richer | [4] Richer | [4] richer |
Pakistan | Wealth index quintiles | 5 | [5] highest quintile | [5] richest | [5] Richest | [5] richest |
Clearly, the value label codes are same in all pkhr rounds. However, the value label texts are different in pkhr 1996 and 2001, compared to the pkhr 2006, 2011, 2016 and 2022 rounds. Therefore, we need to be mindful of this during harmonization.
Pakistan PR dataset use for family structure variables creation
Checking the ID variables before harmonization
Here we check the formatting of the constituent variables with which we will prepare the ID variables for the pooled Pakistan person recode (pr) dataset. We will use the following constituent variables for creating the ID variables for the pooled dataset:
# We check the var type of ID vars in all pkpr datasets.
# First we create a data dictionary of the pkpr datasets in nested tibble.
<- pkpr1_pre_tmp0 |>
pkpr1_pre_tmp1 mutate(lookfor_idvars = map(pkpr_data, \(df) {
|>
df select(hv001, hv002, hvidx) |>
lookfor(details = "full") |>
select(-c(levels:n_na)) |>
# For correctly viewing the range column in data dictionary
convert_list_columns_to_character()
})) pkpr1_pre_tmp1
# Now we unnest the tibble and output the pooled data dictionary
<- pkpr1_pre_tmp1 |>
pkpr1_pre_tmp2 select(c(ctr_name, svy_year, lookfor_idvars)) |>
unnest(cols = c(lookfor_idvars)) |>
arrange(pos)
# Convert and view the tibble as flextable
|>
pkpr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | svy_year | pos | variable | label | col_type | missing | unique_values | range |
---|---|---|---|---|---|---|---|---|
Pakistan | 1990 | 1 | hv001 | cluster number | dbl | 0 | 407 | 1101001 - 4204052 |
Pakistan | 2006 | 1 | hv001 | cluster number | dbl | 0 | 972 | 1 - 980 |
Pakistan | 2012 | 1 | hv001 | Cluster number | dbl | 0 | 498 | 1 - 500 |
Pakistan | 2017 | 1 | hv001 | cluster number | dbl | 0 | 561 | 1 - 580 |
Pakistan | 1990 | 2 | hv002 | household number | dbl | 0 | 25 | 1 - 25 |
Pakistan | 2006 | 2 | hv002 | household number | dbl | 0 | 105 | 1 - 105 |
Pakistan | 2012 | 2 | hv002 | Household number | dbl | 0 | 28 | 1 - 28 |
Pakistan | 2017 | 2 | hv002 | household number | dbl | 0 | 29 | 1 - 29 |
Pakistan | 1990 | 3 | hvidx | line number | dbl | 0 | 55 | 1 - 55 |
Pakistan | 2006 | 3 | hvidx | line number | dbl | 0 | 60 | 1 - 60 |
Pakistan | 2012 | 3 | hvidx | Line number | dbl | 0 | 48 | 1 - 48 |
Pakistan | 2017 | 3 | hvidx | line number | dbl | 0 | 44 | 1 - 44 |
From the above table we can see that all the three constituent ID variables are of numeric class with no missing values. These variables can directly be used for preparing the ID variables after finding the maximum length of their largest value. Note that survey year is also a constituent ID variable of 4-digits and we need not check it.
# We thought to process the above nested tibble further by decomposing the
# "range" col into min and max values using separate_wider_regex().
# However, we hit a roadblock as pattern did not identify the max values in
# some pkpr rounds correctly
<- pkpr1_pre_tmp0 |>
pkpr1_pre_tmp3 # Generate the summary stats for id vars
mutate(skim_idvars = map(pkpr_data, \(df) {
|>
df select(hv001, hv002, hvidx) |>
skim_without_charts()
|>
})) # Pool the summary stats for all pkpr rounds
select(c(ctr_name, svy_year, skim_idvars)) |>
unnest(cols = c(skim_idvars)) |>
arrange(skim_variable, svy_year) |>
# Group and generate the max and min values for each variable
group_by(variable = skim_variable) |>
summarize(
min_val = min(numeric.p0),
max_val = max(numeric.p100)
|>
) # calculate the num of digits in the maximum values
mutate(
max_digits = nchar(as.character(max_val))
|>
) # add variable labels and relocate it after variable name
bind_cols(vlabel = c("cluster number", "household number", "Persons line number")) |>
relocate(vlabel, .after = 1)
# Convert the tibble to flextable for easy viewing
|>
pkpr1_pre_tmp3 qflextable() |>
align(align = "left", part = "all") |>
autofit()
variable | vlabel | min_val | max_val | max_digits |
---|---|---|---|---|
hv001 | cluster number | 1 | 4204052 | 7 |
hv002 | household number | 1 | 105 | 3 |
hvidx | Persons line number | 1 | 60 | 2 |
The above table gives the required length of the constituent ID variables to be set, so that we can correctly concatenate them to create the ID variables. The required length of the ID variables are given in max_digits column. Note that survey year is also a constituent ID variable of 4-digits.
Checking Family structure variables before harmonization
Here we check the family structure related variables before harmonizing them. The variable names were collected by manually checking the full data dictionaries. Here we will check the data dictionary of these hh-level variables and focus on the variable types.
# We check the family structure vars in all pkpr datasets.
# First we create the data dictionary in nested tibble.
<- pkpr1_pre_tmp0 |>
pkpr1_pre_tmp1 mutate(lookfor_famstrvars = map(pkpr_data, \(df) {
|>
df # select the common independent variables
select(c(hv101, hv102, hv103, hv104, hv105)) |>
lookfor(details = "full") |>
select(-c(levels:n_na)) |>
# For correctly viewing the range column in data dictionary
convert_list_columns_to_character()
})) pkpr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkpr1_pre_tmp1 |>
pkpr1_pre_tmp2 select(c(svy_year, lookfor_famstrvars)) |>
unnest(cols = c(lookfor_famstrvars)) |>
arrange(pos, svy_year)
# Convert the tibble to flextable for easy viewing
|>
pkpr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
svy_year | pos | variable | label | col_type | missing | unique_values | range |
---|---|---|---|---|---|---|---|
1990 | 1 | hv101 | relationship to head | dbl+lbl | 11 | 13 | 1 - 98 |
2006 | 1 | hv101 | relationship to head | dbl+lbl | 0 | 13 | 1 - 99 |
2012 | 1 | hv101 | Relationship to head | dbl+lbl | 0 | 18 | 1 - 99 |
2017 | 1 | hv101 | relationship to head | dbl+lbl | 0 | 17 | 1 - 98 |
1990 | 2 | hv102 | usual resident | dbl+lbl | 2 | 3 | 0 - 1 |
2006 | 2 | hv102 | usual resident | dbl+lbl | 0 | 3 | 0 - 9 |
2012 | 2 | hv102 | Usual resident | dbl+lbl | 0 | 3 | 0 - 9 |
2017 | 2 | hv102 | usual resident | dbl+lbl | 1 | 3 | 0 - 1 |
1990 | 3 | hv103 | slept last night | dbl+lbl | 12 | 3 | 0 - 1 |
2006 | 3 | hv103 | slept last night | dbl+lbl | 0 | 3 | 0 - 9 |
2012 | 3 | hv103 | Slept last night | dbl+lbl | 0 | 3 | 0 - 9 |
2017 | 3 | hv103 | slept last night | dbl+lbl | 2 | 3 | 0 - 1 |
1990 | 4 | hv104 | sex of household member | dbl+lbl | 2 | 3 | 1 - 2 |
2006 | 4 | hv104 | sex of household member | dbl+lbl | 0 | 3 | 1 - 9 |
2012 | 4 | hv104 | Sex of household member | dbl+lbl | 0 | 2 | 1 - 2 |
2017 | 4 | hv104 | sex of household member | dbl+lbl | 0 | 2 | 1 - 2 |
1990 | 5 | hv105 | age of household members | dbl+lbl | 23 | 98 | 0 - 98 |
2006 | 5 | hv105 | age of household members | dbl+lbl | 0 | 99 | 0 - 99 |
2012 | 5 | hv105 | Age of household members | dbl+lbl | 0 | 98 | 0 - 99 |
2017 | 5 | hv105 | age of household members | dbl+lbl | 1 | 98 | 0 - 98 |
The above table gives an overall snapshot of the family structure related variables. Interestingly, all the variables including age of hh members (a continuous var) are of labelled class. The relation to head and de facto resident variables have few missing values in pkpr 1996. Note that, the three variables of interest hv101-hv102, two variables hv101 and hv103 have different number of value labels across the pkpr rounds. Next, we compare the value labels of the individual variables across the pkpr datasets.
hv101 - Relationship to head
Next, we check the value labels of the relationship to the household head variable. First we create a nested tibble of the value labels.
# Create the data dictionary in nested tibble
<- pkpr1_pre_tmp0 |>
pkpr1_pre_tmp1 mutate(lookfor_hv101 = map(pkpr_data, \(df) {
|>
df select(hv101) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
})) pkpr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkpr1_pre_tmp1 |>
pkpr1_pre_tmp2 # First we select the required cols and unnest()
select(c(ctr_name, svy_year, lookfor_hv101)) |>
unnest(cols = c(lookfor_hv101)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkpr_"
|>
) # Show the variable name in a col
mutate(var_name = "hv101", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkpr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkpr_1990 | pkpr_2006 | pkpr_2012 | pkpr_2017 |
---|---|---|---|---|---|---|
Pakistan | hv101 | 1 | [1] head | [1] head | [1] Head | [1] head |
Pakistan | hv101 | 2 | [2] wife or husband | [2] wife or husband | [2] Wife or husband | [2] wife or husband |
Pakistan | hv101 | 3 | [3] son/daughter | [3] son/daughter | [3] Son/daughter | [3] son/daughter |
Pakistan | hv101 | 4 | [4] son/daughter-in-law | [4] son/daughter-in-law | [4] Son/daughter-in-law | [4] son/daughter-in-law |
Pakistan | hv101 | 5 | [5] grandchild | [5] grandchild | [5] Grandchild | [5] grandchild |
Pakistan | hv101 | 6 | [6] parent | [6] parent | [6] Parent | [6] parent |
Pakistan | hv101 | 7 | [7] parent-in-law | [7] parent-in-law | [7] Parent-in-law | [7] parent-in-law |
Pakistan | hv101 | 8 | [8] brother/sister | [8] brother/sister | [8] Brother/sister | [8] brother/sister |
Pakistan | hv101 | 9 | [9] co-spouse | [9] co-spouse | [9] co-spouse | |
Pakistan | hv101 | 10 | [10] other relative | [10] other relative | [10] Other relative | [10] other relative |
Pakistan | hv101 | 11 | [11] adopted/foster child | [11] adopted/foster child | [11] Adopted/foster child | [11] adopted/foster child |
Pakistan | hv101 | 12 | [12] not related | [12] not related | [12] Not related | [12] not related |
Pakistan | hv101 | 13 | [13] niece/nehew by blood | [13] Niece/nephew by blood | [13] niece/nephew by blood | |
Pakistan | hv101 | 14 | [14] niece/nephew by marriage | [14] niece/nephew by marriage | ||
Pakistan | hv101 | 15 | [15] Brother/sister-in-law | [15] brother/sister in law | ||
Pakistan | hv101 | 16 | [16] Grand parents | [16] grand parents | ||
Pakistan | hv101 | 17 | [17] Aunts/uncle | [17] aunts/uncle | ||
Pakistan | hv101 | 18 | [18] Domestic servant | [18] domestic servant | ||
Pakistan | hv101 | 98 | [98] dk | [98] dk | [98] Don't know | [98] don't know |
The above table shows that the value label texts vary across the pkpr rounds. To harmonize the relationship to head variable we can use the following value labels -
- 1 head
- 2 spouse
- 3 child
- 4 child-in-law
- 5 grandchild
- 6 parent
- 7 parent-in-law
- 8 sibling
- 9 others
Here, we merge the “spouse” and “co-spouse” categories into “spouse” category, and the “son/daughter” and “adopted/foster child” categories into “child” category.
hv102 - de jure/usual resident
Next, we check the value labels of the de jure resident variable. This means if a household member is an usual resident of the household. First we create a nested tibble of the value labels.
# Create the data dictionary in nested tibble
<- pkpr1_pre_tmp0 |>
pkpr1_pre_tmp1 mutate(lookfor_hv102 = map(pkpr_data, \(df) {
|>
df select(hv102) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
})) pkpr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkpr1_pre_tmp1 |>
pkpr1_pre_tmp2 # First we select the required cols and unnest()
select(c(ctr_name, svy_year, lookfor_hv102)) |>
unnest(cols = c(lookfor_hv102)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkpr_"
|>
) # Show the variable name in a col
mutate(var_name = "hv102", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkpr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkpr_1990 | pkpr_2006 | pkpr_2012 | pkpr_2017 |
---|---|---|---|---|---|---|
Pakistan | hv102 | 0 | [0] no | [0] no | [0] No | [0] no |
Pakistan | hv102 | 1 | [1] yes | [1] yes | [1] Yes | [1] yes |
The above table shows that hv102 has the same value label texts and codes across the pkpr rounds. Therefore, we can use this variable directly after converting to factor type.
hv103 - de facto resident
Next, we check the value labels of the de facto resident variable. In DHS this means if a household member slept last night in the household. First we create a nested tibble of the value labels.
# Create the data dictionary in nested tibble
<- pkpr1_pre_tmp0 |>
pkpr1_pre_tmp1 mutate(lookfor_hv103 = map(pkpr_data, \(df) {
|>
df select(hv103) |>
look_for() |>
lookfor_to_long_format() |>
select(value_labels)
})) pkpr1_pre_tmp1
# Now we unnest the tibble and refine the pooled data dictionary
<- pkpr1_pre_tmp1 |>
pkpr1_pre_tmp2 # First we select the required cols and unnest()
select(c(ctr_name, svy_year, lookfor_hv103)) |>
unnest(cols = c(lookfor_hv103)) |>
# Next we make the num of value labels same across each round
mutate(label_num = parse_number(value_labels)) |>
complete(ctr_name, svy_year, label_num) |>
# Next we create col of value labels for each survey round
pivot_wider(
names_from = svy_year,
values_from = value_labels,
names_prefix = "pkpr_"
|>
) # Show the variable name in a col
mutate(var_name = "hv103", .before = 2)
# Convert the tibble to flextable for easy viewing
|>
pkpr1_pre_tmp2 qflextable() |>
align(align = "left", part = "all") |>
autofit()
ctr_name | var_name | label_num | pkpr_1990 | pkpr_2006 | pkpr_2012 | pkpr_2017 |
---|---|---|---|---|---|---|
Pakistan | hv103 | 0 | [0] no | [0] no | [0] No | [0] no |
Pakistan | hv103 | 1 | [1] yes | [1] yes | [1] Yes | [1] yes |
The above table shows that hv103 has the same value label texts and codes across the pkpr rounds. Therefore, we can use this variable directly after converting to factor type.
START FROM HERE
TASK:
- Handling multiple births in death scarring vars may not be necessary.
- Preceding birth interval construction has changed with DHS-7. We could re-construct it.
TO BE CONTINUED …