Code
# Data Import and Wrangling Tools
library(tidyverse) # All things tidy
<- readxl::read_xls(
rawdf ::here("data/NFHS_5_Factsheets_Data.xls"),
herena = "*"
)
NFHS-5 Data, Insights and Analysis
Aditya Dahiya
August 9, 2024
The Raw Data from the National Family Health Survey (NFHS-5), 2019-21 is shown in Table 1
library(gt) # Beautiful HTML tables
library(gtExtras) # Customizing GT tables
sel_cols <- rawdf |>
names()
rawdf |>
mutate(across(-c(1:2), as.numeric)) |>
mutate(across(where(is.numeric), ~ round(., 1))) |>
mutate(`States/UTs` = if_else(
`States/UTs` == "Dadra and Nagar Haveli & Daman and Diu",
"Dadra and Nagar Haveli",
`States/UTs`
)) |>
pivot_longer(
cols = -c(`States/UTs`, Area),
names_to = "Indicator",
values_to = "values"
) |>
mutate(
name_col = paste0(`States/UTs`, " (", Area, ")"),
.keep = "unused"
) |>
pivot_wider(
id_cols = Indicator,
values_from = values,
names_from = name_col
) |>
gt() |>
tab_header(
title = md("**Raw Data from the NFHS-5**")
) |>
tab_source_note(
source_note = "Source: Open Government Data (OGD) Platform. | Released: May 2022. Ministry of Health and Family Welfare, Government of India. International Institute for Population Sciences, Mumbai"
) |>
sub_missing(missing_text = "") |>
gt_theme_espn() |>
opt_interactive(
use_search = TRUE,
use_resizers = TRUE,
use_compact_mode = TRUE,
use_pagination = TRUE,
page_size_default = 10
) |>
opt_table_font(
font = google_font("Saira Condensed")
) |>
fmt_number(
columns = everything(),
rows = c(1:3),
decimals = 0,
system = "ind"
) |>
opt_align_table_header(align = "center") |>
gt_highlight_cols(
columns = "Indicator",
fill = "grey95",
font_weight = "normal"
) |>
cols_width(
Indicator ~ px(300),
everything() ~ px(125)
)
An analysis of Institutional Deliveries in Public Facility - Rural vs. Urban India in Figure 1
library(sf) # Map of India
library(scales) # Nice Scales for ggplot2
library(fontawesome) # Icons display in ggplot2
library(ggtext) # Markdown text support for ggplot2
library(showtext) # Display fonts in ggplot2
library(colorspace) # Lighten and Darken colours
library(patchwork) # Combining plots
df_indicators <- tibble(
indicator = names(rawdf)
) |>
slice(3:n()) |>
mutate(
ind_id = row_number()
) |>
relocate(ind_id)
df <- rawdf |>
mutate(across(-c(1:2), as.numeric)) |>
pivot_longer(
cols = -c(`States/UTs`, Area),
names_to = "indicator",
values_to = "value"
) |>
rename(state = `States/UTs`, area = Area) |>
left_join(df_indicators) |>
# Remove obvious data entry errors (less than zero values)
filter(value > 0)
# Get State Map of India
india_state_map <- read_sf(here::here(
"data", "india_map", "India_State_Boundary.shp"
)) |>
# During interations, using lower resolution for quick plotting
st_simplify(dTolerance = 100) |>
st_transform(crs = 4326) |>
mutate(state = case_when(
State_Name == "Andaman & Nicobar" ~ "Andaman & Nicobar Islands",
State_Name == "Daman and Diu and Dadra and Nagar Haveli" ~ "Dadra and Nagar Haveli & Daman and Diu",
State_Name == "Jammu and Kashmir" ~ "Jammu & Kashmir",
State_Name == "Maharashtra" ~ "Maharastra",
State_Name == "Delhi" ~ "NCT of Delhi",
State_Name == "Telengana" ~ "Telangana",
State_Name == "Tamilnadu" ~ "Tamil Nadu",
State_Name == "Chhattishgarh" ~ "Chhattisgarh",
.default = State_Name
),
.keep = "unused"
) |>
# Remove empty geometries
filter(!st_is_empty(geometry)) |>
mutate(
area_state = as.numeric(st_area(geometry))
)
plot_title <- "The Rural vs. Urban divide in India - Births in Government facilities!"
plot_subtitle <- str_wrap("The percentage of births that take place in Institutional public (government) facilities, and not at private facilities. Rural areas depend far more on Government facilities, while urban Indians rely on the private sector.", 115)
str_view(plot_subtitle)
# Font for titles
font_add_google("Maiden Orange",
family = "body_font"
)
# Font for the caption
font_add_google("Stint Ultra Condensed",
family = "caption_font"
)
showtext_auto()
text_col <- "grey20"
text_hil <- "grey30"
# Caption stuff for the plot
sysfonts::font_add(
family = "Font Awesome 6 Brands",
regular = here::here("docs", "Font Awesome 6 Brands-Regular-400.otf")
)
github <- ""
github_username <- "aditya-dahiya"
xtwitter <- ""
xtwitter_username <- "@adityadahiyaias"
social_caption_1 <- glue::glue("<span style='font-family:\"Font Awesome 6 Brands\";'>{github};</span> <span style='color: {text_hil}'>{github_username} </span>")
social_caption_2 <- glue::glue("<span style='font-family:\"Font Awesome 6 Brands\";'>{xtwitter};</span> <span style='color: {text_hil}'>{xtwitter_username}</span>")
plot_caption <- paste0(
"**Data:** NFHS-5, OGD Open Government Database, Government of India",
" | **Code:** ",
social_caption_1,
" | **Graphics:** ",
social_caption_2
)
rm(github, github_username, xtwitter,
xtwitter_username, social_caption_1,
social_caption_2)
bts <- 80
df_indicators |>
filter(ind_id == 54) |>
pull(indicator)
g <- df |>
filter(ind_id == 54) |>
filter(area %in% c("Rural", "Urban")) |>
left_join(india_state_map) |>
ggplot(aes(fill = value, geometry = geometry)) +
geom_sf(
colour = "white"
) +
geom_sf_text(
mapping = aes(
label = round(value, 1),
size = area_state
),
family = "body_font",
colour = text_col
) +
facet_wrap(~ area) +
coord_sf(
clip = "off"
) +
paletteer::scale_fill_paletteer_c(
palette = "grDevices::Green-Orange",
direction = -1,
limits = c(50, 80),
oob = scales::squish
) +
guides(size = "none") +
scale_size_continuous(range = c(bts/5, bts/3)) +
labs(
title = plot_title,
subtitle = plot_subtitle,
caption = plot_caption,
x = NULL,
y = NULL,
fill = "Institutional births in public facility (in the 5 years before the survey) (%)"
) +
ggthemes::theme_map(
base_family = "body_font",
base_size = bts
) +
theme(
panel.spacing.x = unit(-10, "mm"),
panel.background = element_rect(
fill = "transparent", colour = "transparent"
),
legend.position.inside = c(0, -0.08),
legend.direction = "horizontal",
legend.key.height = unit(8, "mm"),
legend.key.width = unit(50, "mm"),
legend.title.position = "top",
legend.title = element_text(
margin = margin(0,0,5,0, "mm"),
colour = text_hil
),
legend.background = element_rect(
fill = "transparent",
colour = "transparent"
),
legend.text = element_text(
colour = text_hil,
margin = margin(2,0,0,0, "mm")
),
plot.title = element_text(
colour = text_hil,
hjust = 0.5,
face = "bold",
size = 2.5 * bts,
margin = margin(5,0,0,0, "mm")
),
plot.subtitle = element_text(
colour = text_hil,
lineheight = 0.35,
hjust = 0.5,
margin = margin(5,0,10,0, "mm"),
size = 1.2 * bts
),
plot.caption = element_textbox(
hjust = 1,
family = "caption_font",
margin = margin(5,20,0,0, "mm")
),
strip.background = element_rect(
fill = "transparent",
colour = "transparent"
),
strip.text = element_text(
size = bts * 3,
margin = margin(0,0,-40,0, "mm"),
hjust = 0.6,
colour = text_hil
),
plot.margin = margin(10,-10,10,-10, "mm")
)
bg_col = "white"
# QR Code for the plot
url_graphics <- paste0(
"https://aditya-dahiya.github.io/projects_presentations/projects/",
"nfhs_basic_analysis",
".html"
)
# remotes::install_github('coolbutuseless/ggqr')
# library(ggqr)
plot_qr <- ggplot(
data = NULL,
aes(x = 0, y = 0, label = url_graphics)
) +
ggqr::geom_qr(
colour = text_hil,
fill = bg_col,
size = 2
) +
# labs(caption = "Scan for the Interactive Version") +
coord_fixed() +
theme_void() +
theme(plot.background = element_rect(
fill = NA,
colour = NA
),
plot.caption = element_text(
hjust = 0.5,
margin = margin(0,0,0,0, "mm"),
family = "caption_font",
size = bts/1.8
)
)
data_viz <- ggplot() +
annotate(
geom = "text",
label = str_wrap("The National Family Health Survey (NFHS-5) 2019-21 provides comprehensive data on health, population, and nutrition across India. Conducted under the Ministry of Health and Family Welfare, the survey covers 707 districts.", 30),
x = 0, y = 0,
family = "caption_font",
colour = text_hil,
lineheight = 0.25,
size = bts / 4,
hjust = 1
) +
theme_void() +
theme(
plot.background = element_rect(fill = "transparent", colour = "transparent"),
panel.background = element_rect(fill = "transparent", colour = "transparent")
)
library(patchwork)
g_full <- g +
inset_element(
p = plot_qr,
left = 0.85, right = 1,
top = 0.92, bottom = 0.78,
align_to = "full"
) +
inset_element(
p = data_viz,
left = 0.8, right = 1.13,
top = 0.78, bottom = 0.63,
align_to = "full"
) +
plot_annotation(
theme = theme(
plot.background = element_rect(
fill = "transparent",
colour = "transparent"
),
panel.background = element_rect(
fill = "transparent",
colour = "transparent"
)
)
)
ggsave(
plot = g_full,
filename = here::here("docs", "nfhs_5_institutional_delievries.png"),
device = "png",
height = 210 * 2,
width = 297 * 2,
units = "mm",
bg = "white"
)
library(magick)
# Saving a thumbnail for the webpage
image_read(here::here("docs",
"nfhs_5_institutional_delievries.png")) |>
image_resize(geometry = "400") |>
image_write(here::here("docs",
"nfhs_thumbnail.png"))