Skip to contents

This vignette demonstrates district-level choropleth mapping of food expenditure patterns from the HCES 2022-23 survey. The package maps NSS district codes to NFHS5 GeoJSON boundaries from bharatviz.org.

District coverage

ics_district_summary() |>
  knitr::kable(caption = "District data availability by survey round")
District data availability by survey round
round round_year n_districts n_states recommended_geojson
52nd 1996 479 32 India-2001-districts (594 districts)
53rd 1997 499 32 India-2001-districts (594 districts)
54th 1998 498 32 India-2001-districts (594 districts)
56th 2001 551 35 India-2001-districts (594 districts)
57th 2002 555 30 India-2011-districts (641 districts)
59th 2003 584 35 India-2011-districts (641 districts)
60th 2004 517 28 India-2011-districts (641 districts)
61st 2005 519 28 India-2011-districts (641 districts)
62nd 2006 518 28 India-2011-districts (641 districts)
HCES-2022-23 2023 692 36 NFHS5-districts (711 districts)
HCES-2023-24 2024 689 36 LGD-districts (785 districts)

State-level map: Food expenditure by state

con <- ics_connect("~/data/consumption_parquet")

state_exp <- ics_consumption_by_state(con, round = "HCES-2022-23", min_obs = 100)

if (nrow(state_exp) > 0 && requireNamespace("sf", quietly = TRUE)) {
  geo_state <- tryCatch(
    ics_attach_geometry(state_exp, "state"),
    error = function(e) {
      message("Geometry not available: ", e$message)
      NULL
    }
  )
  if (!is.null(geo_state)) {
    ggplot(geo_state) +
      geom_sf(aes(fill = mean_value), colour = "white", linewidth = 0.2) +
      scale_fill_viridis_c(option = "C", labels = scales::comma_format()) +
      labs(
        title = "Mean Food Expenditure by State (HCES 2022-23)",
        fill = "Mean value (Rs.)"
      ) +
      theme_void(base_size = 11) +
      theme(legend.position = "right")
  }
}

State-level: Edible oil share

Which states spend the highest fraction of their food budget on edible oils?

state_fg <- ics_consumption_by_state(
  con,
  round = "HCES-2022-23", by_food_group = TRUE, min_obs = 100
)

if (nrow(state_fg) > 0 && requireNamespace("sf", quietly = TRUE)) {
  oil_share <- state_fg |>
    group_by(state_name) |>
    mutate(share = total_value / sum(total_value)) |>
    ungroup() |>
    filter(food_group == "Edible Oil")

  geo_oil <- tryCatch(
    ics_attach_geometry(oil_share, "state"),
    error = function(e) NULL
  )
  if (!is.null(geo_oil)) {
    ggplot(geo_oil) +
      geom_sf(aes(fill = share), colour = "white", linewidth = 0.2) +
      scale_fill_distiller(
        palette = "YlOrRd", direction = 1,
        labels = scales::percent_format()
      ) +
      labs(
        title = "Edible Oil Expenditure Share by State (HCES 2022-23)",
        subtitle = "% of total food expenditure",
        fill = "Oil share"
      ) +
      theme_void(base_size = 11)
  }
}

State-level: Cereals share

if (nrow(state_fg) > 0 && requireNamespace("sf", quietly = TRUE)) {
  cereal_share <- state_fg |>
    group_by(state_name) |>
    mutate(share = total_value / sum(total_value)) |>
    ungroup() |>
    filter(food_group == "Cereals")

  geo_cereal <- tryCatch(
    ics_attach_geometry(cereal_share, "state"),
    error = function(e) NULL
  )
  if (!is.null(geo_cereal)) {
    ggplot(geo_cereal) +
      geom_sf(aes(fill = share), colour = "white", linewidth = 0.2) +
      scale_fill_distiller(
        palette = "YlGnBu", direction = 1,
        labels = scales::percent_format()
      ) +
      labs(
        title = "Cereals Expenditure Share by State (HCES 2022-23)",
        subtitle = "% of total food expenditure",
        fill = "Cereal share"
      ) +
      theme_void(base_size = 11)
  }
}

Item-level: Rice by state

rice_state <- ics_query_item(con, "rice", round = "HCES-2022-23", by = "state")

if (nrow(rice_state) > 0 && requireNamespace("sf", quietly = TRUE)) {
  rice_map <- rice_state |> filter(!is.na(state_name), n >= 50)
  geo_rice <- tryCatch(
    ics_attach_geometry(rice_map, "state"),
    error = function(e) NULL
  )
  if (!is.null(geo_rice)) {
    ggplot(geo_rice) +
      geom_sf(aes(fill = mean_value), colour = "white", linewidth = 0.2) +
      scale_fill_viridis_c(option = "D", labels = scales::comma_format()) +
      labs(
        title = "Rice Expenditure by State (HCES 2022-23)",
        subtitle = "Survey-weighted mean (Rs.)",
        fill = "Mean (Rs.)"
      ) +
      theme_void(base_size = 11)
  }
}

Cleanup

Notes

  • State-level maps use LGD boundaries from bharatviz.org
  • District-level maps require the NFHS5 district boundary set
  • NSS district codes are mapped to NFHS5 names via the district crosswalk built from DDI XML metadata + fuzzy matching + proliferation data