knitr::opts_chunk$set(message = FALSE, warning = FALSE)
options(knitr.table.format = "html")   # needed for the <br>/<small> cell markup

library(dplyr)
library(tidyr)
library(purrr)
library(tibble)
library(ggplot2)
library(ggrepel)
library(knitr)
library(kableExtra)
library(survey)
library(forcats)
library(ggiraph)

# All cleaning and categorisation happens in R/00_wvs_clean_harmonise.R
wvs_all <- readRDS("D:/Populism and Democrary/World value survey/data/clean/wvs_harmonised.rds")

# Comparison set: India vs Western Europe & Offshoots and Middle East & North Africa.
# Adults only: W7 India deliberately interviewed 16-17 year olds (321 of 1,692).
focus_regions <- c("India", "Western Europe & Offshoots", "Middle East & North Africa")
# W3 (1994-99, India 1995) is dropped from this report
wvs <- wvs_all |>
  filter(is.na(age) | age >= 18, macro_region %in% focus_regions, wave != "W3") |>
  mutate(macro_region = droplevels(macro_region))

india_years   <- c(W4 = "2001", W5 = "2006", W6 = "2012", W7 = "2023")
wave_labels   <- c(W4 = "W4 (1999–2004)", W5 = "W5 (2004–09)", W6 = "W6 (2010–16)", W7 = "W7 (2017–23)")
common_states <- c("Bihar", "Delhi", "Haryana", "Maharashtra", "Punjab", "Uttar Pradesh", "West Bengal")
styled <- function(k) kable_styling(k, bootstrap_options = c("striped", "condensed"), full_width = FALSE)

# ---- Chart style ------------------------------------------------------------------
# Colour follows the group, in a fixed order (validated for colour-blind separation):
# Western Europe = blue, India = orange, MENA = green.
region_cols <- c(`Western Europe & Offshoots` = "#2a78d6", India = "#eb6834",
                 `Middle East & North Africa` = "#1baf7a")
year_cols   <- c(`2001` = "#86b6ef", `2006` = "#5598e7",
                 `2012` = "#256abf", `2023` = "#0d366b")        # one-hue ramp: later = darker
india_year_num <- c(W4 = 2001, W5 = 2006, W6 = 2012, W7 = 2023)
ink <- "#0b0b0b"; ink2 <- "#52514e"; grid_col <- "#e6e5e1"

theme_wvs <- function(base = 11) {
  theme_minimal(base_size = base) +
    theme(panel.grid.minor = element_blank(),
          panel.grid.major = element_line(colour = grid_col, linewidth = 0.3),
          axis.text = element_text(colour = ink2), axis.title = element_text(colour = ink2),
          plot.title = element_text(face = "bold", size = base + 1, colour = ink),
          plot.subtitle = element_text(colour = ink2),
          plot.caption = element_text(colour = ink2, hjust = 0, size = base - 2),
          legend.position = "top", legend.title = element_blank(), legend.justification = "left",
          strip.text = element_text(face = "bold", hjust = 0, colour = ink))
}
knitr::opts_chunk$set(dpi = 110)

# Every chart is rendered with ggiraph: hover a dot, bar or point to see its value
# ggiraph tooltips / ids cannot contain a straight apostrophe
safe_txt <- function(x) gsub("'", "’", x, fixed = TRUE)

show_plot <- function(p, w = 9, h = 5) {
  if (isTRUE(getOption("wvs.static"))) return(p)   # for checking layout as images
  girafe(ggobj = p, width_svg = w, height_svg = h,
         options = list(
           opts_tooltip(css = paste0("background:#ffffff;color:#0b0b0b;border:1px solid #d9d8d4;",
                                     "border-radius:4px;padding:6px 8px;font-size:12px;")),
           opts_hover(css = "stroke:#0b0b0b;stroke-width:1.5px;"),
           opts_hover_inv(css = "opacity:0.4;"),
           opts_sizing(rescale = TRUE),
           opts_toolbar(saveaspng = TRUE)))
}
agree4 <- function(x) case_when(x %in% 1:2 ~ 1, x %in% 3:4 ~ 0)
agree5 <- function(x) case_when(x %in% 1:2 ~ 1, x %in% 3:5 ~ 0)
high10 <- function(x) case_when(x %in% 7:10 ~ 1, x %in% 1:6 ~ 0)   # top 4 points of a 1-10 scale
# mean of 0/1 items when at least `k` are answered
row_share <- function(d, vars, k) {
  n_ok <- rowSums(!is.na(d[vars]))
  ifelse(n_ok >= k, rowMeans(d[vars], na.rm = TRUE), NA_real_)
}

# Institutions that USE power (the state) vs institutions that CHECK power
state_inst <- c("conf_civilservice_hi", "conf_police_hi", "conf_army_hi", "conf_govt_hi")
check_inst <- c("conf_parliament_hi", "conf_parties_hi", "conf_press_hi", "conf_courts_hi")

conc_levels <- c("Liberal (maximalist)", "Minimalist (electoral)", "Illiberal")

add_recodes <- function(d) {
  d |>
    mutate(
      # 1. trust in the two sides of the state (share of 4 institutions trusted, 0-1)
      state_trust = row_share(pick(everything()), state_inst, 3),
      check_trust = row_share(pick(everything()), check_inst, 3),
      trust_gap   = state_trust - check_trust,

      # 2. demand for governance (delivery) and for accountability: yes/no on each question (combined below)
      # governance = what people want government to deliver (ranked aims: picked 1st or 2nd)
      gov_growth    = case_when(pm_aims1 == 1 | pm_aims2 == 1 ~ 1, pm_aims1 %in% 1:4 ~ 0),
      gov_prices    = case_when(pm_goals1 == 3 | pm_goals2 == 3 ~ 1, pm_goals1 %in% 1:4 ~ 0),
      gov_economy   = case_when(pm_society1 == 1 | pm_society2 == 1 ~ 1, pm_society1 %in% 1:4 ~ 0),
      gov_crime     = case_when(pm_society1 == 4 | pm_society2 == 4 ~ 1, pm_society1 %in% 1:4 ~ 0),
      acc_say_govt  = case_when(pm_goals1 == 2 | pm_goals2 == 2 ~ 1, pm_goals1 %in% 1:4 ~ 0),
      acc_say_work  = case_when(pm_aims1 == 3 | pm_aims2 == 3 ~ 1, pm_aims1 %in% 1:4 ~ 0),
      acc_petition  = case_when(act_petition %in% 1:2 ~ 1, act_petition == 3 ~ 0),
      acc_demo      = case_when(act_demonstration %in% 1:2 ~ 1, act_demonstration == 3 ~ 0),
      acc_boycott   = case_when(act_boycott %in% 1:2 ~ 1, act_boycott == 3 ~ 0),

      # 3. conception of democracy: yes/no on each liberal and each authoritarian question
      lib_elections = case_when(dess_elections %in% 7:10 ~ 1, dess_elections %in% 1:6 ~ 0),
      lib_civil     = case_when(dess_civilrights %in% 7:10 ~ 1, dess_civilrights %in% 1:6 ~ 0),
      lib_women     = case_when(dess_women %in% 7:10 ~ 1, dess_women %in% 1:6 ~ 0),
      lib_demgood   = case_when(reg_democracy %in% 1:2 ~ 1, reg_democracy %in% 3:4 ~ 0),
      lib_demimp    = case_when(dem_importance %in% 7:10 ~ 1, dem_importance %in% 1:6 ~ 0),
      aut_army_ess  = case_when(dess_army %in% 7:10 ~ 1, dess_army %in% 1:6 ~ 0),
      aut_relig_ess = case_when(dess_religious %in% 7:10 ~ 1, dess_religious %in% 1:6 ~ 0),
      aut_army_rule = case_when(reg_army %in% 1:2 ~ 1, reg_army %in% 3:4 ~ 0),
      aut_strong    = case_when(reg_strongleader %in% 1:2 ~ 1, reg_strongleader %in% 3:4 ~ 0),
      aut_experts   = case_when(reg_experts %in% 1:2 ~ 1, reg_experts %in% 3:4 ~ 0),
      aut_obey      = case_when(dess_obey %in% 7:10 ~ 1, dess_obey %in% 1:6 ~ 0),
      aut_authority = case_when(fut_authority == 1 ~ 1, fut_authority %in% 2:3 ~ 0),
      # liberal score and authoritarian score = share of answered questions with a "yes" (0-1);
      # democracy score = liberal score minus authoritarian score (-1 to +1)
      aut_share = rowMeans(pick(aut_army_ess, aut_relig_ess, aut_army_rule, aut_strong,
                                aut_experts, aut_obey, aut_authority), na.rm = TRUE),
      lib_share = rowMeans(pick(lib_elections, lib_civil, lib_women, lib_demgood, lib_demimp), na.rm = TRUE),
      dem_score = lib_share - aut_share,
      # Classified if free elections was answered (asked from 2006) and at least 3 questions in
      # each set were answered.
      aut_n = rowSums(!is.na(pick(aut_army_ess, aut_relig_ess, aut_army_rule, aut_strong,
                                  aut_experts, aut_obey, aut_authority))),
      lib_n = rowSums(!is.na(pick(lib_elections, lib_civil, lib_women, lib_demgood, lib_demimp))),
      ess_ok = !is.na(dess_elections) & aut_n >= 3 & lib_n >= 3,
      # Types are bands of the democracy score:
      #   Illiberal: score <= 0, or free elections rated 1-6
      #   Minimalist: free elections 7-10 and score above 0 but below 0.5
      #   Liberal: free elections 7-10 and score 0.5 or more
      conception = case_when(
        !ess_ok                                                       ~ NA_character_,
        lib_elections == 0 | dem_score <= 0                           ~ "Illiberal",
        lib_elections == 1 & dem_score >= 0.5                         ~ "Liberal (maximalist)",
        lib_elections == 1 & dem_score > 0 & dem_score < 0.5          ~ "Minimalist (electoral)"),
      conception = factor(conception, conc_levels),
      con_liberal   = as.numeric(conception == "Liberal (maximalist)"),
      con_minimal   = as.numeric(conception == "Minimalist (electoral)"),
      con_illiberal = as.numeric(conception == "Illiberal"),

      # state support (standalone dimension, section 4): yes on each item
      ss_govresp_yes  = case_when(econ_govresp %in% 1:4 ~ 1, econ_govresp %in% 5:10 ~ 0),
      ss_income_yes   = case_when(econ_income %in% 1:4 ~ 1, econ_income %in% 5:10 ~ 0),
      ss_taxrich_yes  = high10(dess_taxrich),
      ss_unemp_yes    = high10(dess_unemp),
      ss_incomeeq_yes = high10(dess_incomeequal),
      ss_policy_n     = ss_govresp_yes + ss_income_yes,
      ss_essential_n  = ss_taxrich_yes + ss_unemp_yes + if_else(wave == "W5", 0, ss_incomeeq_yes)
    )
}
wvs   <- add_recodes(wvs)

# State supporter = yes on at least 3 of the state-support items. Classified only where at least
# 4 of the 5 were asked in that country-wave (so from 2006) and the respondent answered all asked.
ss_items <- c("ss_govresp_yes", "ss_income_yes", "ss_taxrich_yes", "ss_unemp_yes", "ss_incomeeq_yes")
wvs <- wvs |>
  group_by(wave, country_code) |>
  mutate(ss_asked = sum(map_lgl(pick(all_of(ss_items)), ~ any(!is.na(.x))))) |>
  ungroup() |>
  mutate(ss_answered = rowSums(!is.na(pick(all_of(ss_items)))),
         ss_yes      = rowSums(pick(all_of(ss_items)), na.rm = TRUE),
         state_support = case_when(ss_asked < 4 | ss_answered < ss_asked ~ NA_real_,
                                   ss_yes >= 3 ~ 1, TRUE ~ 0))

# Demand for governance / accountability = yes on at least half of the questions asked in that
# country-wave. Classified if the respondent answered all but at most one of those asked.
gov_items <- c("gov_growth", "gov_prices", "gov_economy", "gov_crime")
acc_items <- c("acc_say_govt", "acc_say_work", "acc_petition", "acc_demo", "acc_boycott")
demand <- function(d, items) {
  asked <- d |>
    group_by(wave, country_code) |>
    summarise(k = sum(map_lgl(pick(all_of(items)), ~ any(!is.na(.x)))), .groups = "drop")
  k   <- left_join(select(d, wave, country_code), asked, by = c("wave", "country_code"))$k
  ans <- rowSums(!is.na(d[items]))
  yes <- rowSums(d[items], na.rm = TRUE)
  ifelse(k >= 2 & ans >= k - 1, as.numeric(yes / ans >= 0.5), NA_real_)
}
wvs <- wvs |>
  mutate(gov_demand = demand(wvs, gov_items),
         acc_demand = demand(wvs, acc_items),
         gtype = case_when(
           acc_demand == 1 & gov_demand == 0 ~ "Accountability-first",
           acc_demand == 1 & gov_demand == 1 ~ "Want both",
           acc_demand == 0 & gov_demand == 1 ~ "Governance-first",
           acc_demand == 0 & gov_demand == 0 ~ "Neither"),
         gtype = factor(gtype, c("Accountability-first", "Want both", "Governance-first", "Neither")),
         g_accfirst = as.numeric(gtype == "Accountability-first"),
         g_both     = as.numeric(gtype == "Want both"),
         g_govfirst = as.numeric(gtype == "Governance-first"),
         # robustness: accountability from stated preferences only (no demonstrations / boycotts)
         acc_demand_pref = demand(wvs, setdiff(acc_items, c("acc_demo", "acc_boycott"))),
         gtype_pref = case_when(
           acc_demand_pref == 1 & gov_demand == 0 ~ "Accountability-first",
           acc_demand_pref == 1 & gov_demand == 1 ~ "Want both",
           acc_demand_pref == 0 & gov_demand == 1 ~ "Governance-first",
           acc_demand_pref == 0 & gov_demand == 0 ~ "Neither"))
india <- wvs |> filter(is_india)
# ---- Weighted estimate with 95% CI ------------------------------------------
# SEs use the Kish effective sample size (weights only). The WVS does not release
# sampling clusters, so intervals are too narrow; do not over-read small gaps.
wstat <- function(x, w) {
  ok <- !is.na(x) & !is.na(w); x <- x[ok]; w <- w[ok]
  if (!length(x)) return(tibble(est = NA_real_, se = NA_real_, n = 0L))
  m    <- sum(w * x) / sum(w)
  neff <- sum(w)^2 / sum(w^2)
  tibble(est = m, se = sqrt(sum(w * (x - m)^2) / sum(w) / neff), n = length(x))
}
wdk <- function(x, w) if (all(is.na(x))) NA_real_ else 100 * sum(w[is.na(x)]) / sum(w)

# ---- India over time ------------------------------------------------------------
india_trend <- function(items, mult = 100, data = india) {
  imap_dfr(items, function(lab, v) {
    data |>
      group_by(wave) |>
      group_modify(~ bind_cols(wstat(.x[[v]], .x$weight), dk = wdk(.x[[v]], .x$weight))) |>
      ungroup() |>
      mutate(item = lab, var = v)
  }) |>
    mutate(lo = est - 1.96 * se, hi = est + 1.96 * se)
}

show_trend <- function(tr, mult = 100, caption = NULL, digits = 1) {
  f <- paste0("%.", digits, "f")
  tr |>
    mutate(cell = ifelse(is.na(est), "—",
                         sprintf(paste0(f, " [", f, ", ", f, "]<br><small>no answer %.0f%%</small>"),
                                 est * mult, lo * mult, hi * mult, dk)),
           year = india_years[wave]) |>
    select(Item = item, year, cell) |>
    pivot_wider(names_from = year, values_from = cell) |>
    (\(x) kable(x, escape = FALSE, caption = caption, align = c("l", rep("c", ncol(x) - 1))))() |>
    styled()
}

# ---- Country estimates and India vs regions -------------------------------------
# Region value = unweighted mean of country estimates (each country counts once)
country_est <- function(v, mult = 100, data = wvs) {
  data |>
    group_by(wave, country_code, country_name, macro_region) |>
    filter(any(!is.na(.data[[v]]))) |>
    summarise(est = weighted.mean(.data[[v]], weight, na.rm = TRUE) * mult, .groups = "drop")
}

region_compare <- function(v, mult = 100, caption = NULL, digits = 1) {
  ce  <- country_est(v, mult)
  f   <- paste0("%.", digits, "f")
  reg <- ce |>
    group_by(wave, macro_region) |>
    summarise(cell = sprintf(paste0(f, " <small>(%d)</small>"), mean(est), n()), .groups = "drop") |>
    mutate(macro_region = as.character(macro_region))
  rnk <- ce |>
    group_by(wave) |>
    mutate(r = rank(-est, ties.method = "min"), N = n()) |>
    filter(country_code == 356) |>
    transmute(wave, macro_region = "India's rank among countries shown (1 = highest)",
              cell = sprintf("%d of %d", r, N))
  bind_rows(reg, rnk) |>
    mutate(wave = wave_labels[wave]) |>
    pivot_wider(names_from = wave, values_from = cell, values_fill = "—") |>
    arrange(factor(macro_region, levels = c(focus_regions, "India's rank among countries shown (1 = highest)"))) |>
    rename(Region = macro_region) |>
    (\(x) kable(x, escape = FALSE, caption = caption, align = c("l", rep("c", ncol(x) - 1))))() |>
    styled() |>
    footnote(general = paste0("Cells: mean of country estimates (number of countries).",
                              if (grepl("trust|check", v)) " W4 has no courts item, so its checking-trust index uses 3 institutions." else ""),
             general_title = "")
}

# ---- Charts used across sections --------------------------------------------------
# India over time: one or more items, India only (orange), items told apart by line type + labels
plot_india_lines <- function(tr, title, ylab = "%", mult = 100, caption = NULL, w = 9, h = 4.6) {
  d <- tr |> filter(!is.na(est)) |> mutate(year = india_year_num[wave])
  p <- ggplot(d, aes(year, est * mult, group = item)) +
    geom_ribbon(aes(ymin = lo * mult, ymax = hi * mult), fill = region_cols["India"], alpha = 0.10) +
    geom_line(aes(linetype = item), colour = region_cols["India"], linewidth = 0.8) +
    geom_point_interactive(aes(tooltip = sprintf("%s<br>%d: %.1f (95%% CI %.1f to %.1f)", item, year,
                                                 est * mult, lo * mult, hi * mult),
                               data_id = paste(item, year)),
                           shape = 21, fill = region_cols["India"], colour = "white", size = 3, stroke = 0.8) +
    geom_text(data = d |> group_by(item) |> slice_max(year, n = 1),
              aes(label = item), hjust = -0.08, size = 3.1, colour = ink) +
    scale_x_continuous(breaks = unname(india_year_num), limits = c(2000, 2033)) +
    scale_linetype_manual(values = c("solid", "22", "42", "12")) +
    labs(title = title, x = NULL, y = ylab, caption = caption) +
    theme_wvs() + theme(legend.position = "none")
  show_plot(p, w, h)
}

# India vs the two regions over waves: region = mean of countries; India = its own estimate
plot_region_lines <- function(v, title, ylab = "%", mult = 100, caption = NULL, w = 9, h = 4.6) {
  d <- country_est(v, mult) |>
    group_by(wave, macro_region) |>
    summarise(est = mean(est), k = n(), .groups = "drop") |>
    mutate(wave_lab = factor(wave_labels[wave], wave_labels), macro_region = factor(macro_region, focus_regions))
  p <- ggplot(d, aes(wave_lab, est, colour = macro_region, group = macro_region)) +
    geom_line(linewidth = 0.8) +
    geom_point_interactive(aes(fill = macro_region, data_id = paste(macro_region, wave),
                               tooltip = sprintf("%s<br>%s: %.1f<br>%d %s", macro_region, wave_lab, est, k,
                                                 ifelse(k == 1, "country", "countries"))),
                           shape = 21, colour = "white", size = 3.2, stroke = 0.8) +
    geom_text(data = d |> group_by(macro_region) |> slice_max(as.integer(wave_lab), n = 1),
              aes(label = sprintf("%.0f", est)), hjust = -0.6, size = 3.1, colour = ink, show.legend = FALSE) +
    scale_colour_manual(values = region_cols, breaks = focus_regions) +
    scale_fill_manual(values = region_cols, guide = "none") +
    labs(title = title, x = NULL, y = ylab,
         caption = caption %||% "Regions: mean of country estimates. W. Europe in W4 is 4 countries.") +
    theme_wvs()
  show_plot(p, w, h)
}

# Every country as a dot, ranked within each wave (one panel per wave); India highlighted.
# Dashed lines = region averages (mean of countries).
plot_country_dots <- function(v, title, xlab, mult = 100, waves = NULL, caption = NULL, w = 11, h = NULL) {
  ce <- country_est(v, mult)
  if (!is.null(waves)) ce <- filter(ce, wave %in% waves)
  ce <- ce |>
    mutate(wave_lab = factor(wave_labels[wave], wave_labels),
           india = country_code == 356,
           name  = safe_txt(as.character(country_name)),
           key   = paste(name, wave, sep = "___")) |>
    arrange(wave, est) |>
    mutate(key = factor(key, unique(key)))
  rm <- ce |> filter(!india) |> group_by(wave_lab, macro_region) |> summarise(m = mean(est), .groups = "drop")
  n_max <- max(table(ce$wave))
  p <- ggplot(ce, aes(est, key)) +
    geom_vline(data = rm, aes(xintercept = m, colour = macro_region), linetype = "22", linewidth = 0.5) +
    geom_point_interactive(aes(colour = macro_region, size = india, data_id = paste(name, wave),
                               tooltip = sprintf("%s (%s)<br>%s: %.1f", name, macro_region, wave_lab, est))) +
    facet_wrap(~ wave_lab, nrow = 1, scales = "free_y") +
    scale_y_discrete(labels = function(x) sub("___.*", "", x)) +
    scale_colour_manual(values = region_cols, breaks = focus_regions) +
    scale_size_manual(values = c(`FALSE` = 2.2, `TRUE` = 3.8), guide = "none") +
    labs(title = title, x = xlab, y = NULL,
         caption = caption %||% "Countries ranked within each wave. Dashed lines: region averages (mean of countries).") +
    theme_wvs(10) + theme(panel.spacing = unit(1.4, "lines"), panel.grid.major.y = element_blank(),
                          axis.text.y = element_text(size = 7.5))
  show_plot(p, w, h %||% max(4.5, 1.8 + 0.18 * n_max))
}

# ---- Groups within India ------------------------------------------------------------
india_groups <- function(v, mult = 100, min_n = 50, caption = NULL, digits = 1,
                         groups = c(Sex = "sex_f", Age = "age_cat3", Education = "educ3",
                                    Party = "in_party_vote", Religion = "in_religion", Caste = "in_caste")) {
  keep_levels <- list(in_party_vote = c("BJP", "INC", "Left", "Other party"),
                      in_religion   = c("Hindu", "Muslim", "Christian", "Other (Sikh, Buddhist, Jain, ...)"))
  f <- paste0("%.", digits, "f")
  long <- imap_dfr(groups, function(g, gl) {
    d <- india |> filter(!is.na(.data[[g]]))
    if (g %in% names(keep_levels)) d <- d |> filter(.data[[g]] %in% keep_levels[[g]])
    d |>
      mutate(level = factor(as.character(.data[[g]]), levels = levels(droplevels(factor(.data[[g]]))))) |>
      group_by(wave, level) |>
      group_modify(~ wstat(.x[[v]], .x$weight)) |>
      ungroup() |>
      mutate(group = factor(gl, levels = names(groups)))
  }) |>
    filter(n > 0)
  wide <- long |>
    mutate(cell = ifelse(n < min_n, sprintf("<small>n=%d</small>", n),
                         sprintf(paste0(f, " <small>(%d)</small>"), est * mult, n)),
           year = factor(india_years[wave], levels = india_years)) |>
    arrange(group, level, year) |>
    select(group, level, year, cell) |>
    pivot_wider(names_from = year, values_from = cell, values_fill = "—")
  wide |>
    select(-group) |>
    rename(` ` = level) |>
    kable(escape = FALSE, caption = caption, align = c("l", rep("c", ncol(wide) - 2))) |>
    styled() |>
    pack_rows(index = table(droplevels(wide$group))) |>
    footnote(general = sprintf("Cells: estimate (unweighted n). Cells with n < %d are not estimated.", min_n),
             general_title = "")
}

# Hindu vs Muslim over time, one panel per item
relig_cols <- c(Hindu = "#4a3aa7", Muslim = "#eda100")
plot_relig_lines <- function(items, title, ylab = "%", ncol = 2, w = 10, h = 6.5, caption = NULL) {
  d <- imap_dfr(items, function(lab, v) {
    india |>
      filter(in_religion %in% names(relig_cols)) |>
      group_by(wave, in_religion) |>
      group_modify(~ wstat(.x[[v]], .x$weight)) |>
      ungroup() |>
      filter(n >= 50) |>
      mutate(item = lab)
  }) |>
    mutate(year = india_year_num[wave], item = factor(item, items),
           in_religion = factor(as.character(in_religion), names(relig_cols)))
  p <- ggplot(d, aes(year, est * 100, colour = in_religion, group = in_religion)) +
    geom_line(linewidth = 0.8) +
    geom_point_interactive(aes(fill = in_religion, data_id = safe_txt(paste(item, in_religion, year)),
                               tooltip = safe_txt(sprintf("%s<br>%s, %d: %.1f%%<br>n = %d", item, in_religion, year, est * 100, n))),
                           shape = 21, colour = "white", size = 2.8, stroke = 0.7) +
    geom_text_repel(data = d |> group_by(item, in_religion) |> slice_max(year, n = 1),
                    aes(label = in_religion), size = 2.9, colour = ink, show.legend = FALSE,
                    direction = "y", hjust = 0, nudge_x = 1.2, segment.colour = NA, seed = 1) +
    facet_wrap(~ item, ncol = ncol) +
    scale_colour_manual(values = relig_cols) +
    scale_fill_manual(values = relig_cols, guide = "none") +
    scale_x_continuous(breaks = unname(india_year_num), limits = c(2000, 2028)) +
    scale_y_continuous(limits = c(0, 100)) +
    labs(title = title, x = NULL, y = ylab,
         caption = caption %||% "India only. Groups with fewer than 50 respondents are not shown.") +
    theme_wvs(10) + theme(panel.spacing = unit(1.2, "lines"))
  show_plot(p, w, h)
}

# Several items in one wave: India and the two regions side by side (Cleveland dot plot)
plot_items_regions <- function(items, wave_sel, title, xlab = "%", w = 9.5, h = NULL, caption = NULL) {
  d <- imap_dfr(items, function(lab, v) {
    country_est(v) |>
      filter(wave == wave_sel) |>
      group_by(macro_region) |>
      summarise(est = mean(est), k = n(), .groups = "drop") |>
      mutate(item = lab)
  }) |>
    mutate(item = factor(item, rev(items)), macro_region = factor(macro_region, focus_regions))
  p <- ggplot(d, aes(est, item)) +
    geom_line(aes(group = item), colour = "#c3c2b7", linewidth = 0.9) +
    geom_point_interactive(aes(colour = macro_region, data_id = safe_txt(paste(item, macro_region)),
                               tooltip = safe_txt(sprintf("%s<br>%s: %.0f%%<br>%d %s", item, macro_region, est, k,
                                                 ifelse(k == 1, "country", "countries")))),
                           size = 3.6) +
    scale_colour_manual(values = region_cols, breaks = focus_regions) +
    scale_x_continuous(limits = c(0, 100)) +
    labs(title = title, x = xlab, y = NULL,
         caption = caption %||% paste0(wave_labels[wave_sel], ". Regions: mean of countries.")) +
    theme_wvs()
  show_plot(p, w, h %||% (1.6 + 0.55 * length(items)))
}

# long version of the group estimates, for charts
group_long <- function(v, groups = c(Sex = "sex_f", Age = "age_cat3", Education = "educ3",
                                     Party = "in_party_vote", Religion = "in_religion", Caste = "in_caste")) {
  keep_levels <- list(in_party_vote = c("BJP", "INC", "Left", "Other party"),
                      in_religion   = c("Hindu", "Muslim", "Christian", "Other (Sikh, Buddhist, Jain, ...)"))
  imap_dfr(groups, function(g, gl) {
    d <- india |> filter(!is.na(.data[[g]]))
    if (g %in% names(keep_levels)) d <- d |> filter(.data[[g]] %in% keep_levels[[g]])
    d |>
      mutate(level = factor(as.character(.data[[g]]), levels = levels(droplevels(factor(.data[[g]]))))) |>
      group_by(wave, level) |>
      group_modify(~ wstat(.x[[v]], .x$weight)) |>
      ungroup() |>
      mutate(group = factor(gl, levels = names(groups)))
  })
}

# ---- Question table at the start of each section ------------------------------------
fmt_conf <- "4-point: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all"
fmt_reg  <- "4-point: 1 very good, 2 fairly good, 3 fairly bad, 4 very bad"
fmt_ess  <- "10-point: 1 not an essential characteristic of democracy ... 10 an essential characteristic"
fmt_agr4 <- "4-point: 1 strongly agree, 2 agree, 3 disagree, 4 strongly disagree"
fmt_agr5 <- "5-point: 1 agree strongly ... 3 neither ... 5 disagree strongly"
fmt_just <- "10-point: 1 never justifiable ... 10 always justifiable"
fmt_surv <- "4-point: 1 definitely should ... 4 definitely should not"
fmt_nb   <- "Yes/no: mentioned or not mentioned on a list"
codebook_vars <- readr::read_csv("D:/Populism and Democrary/World value survey/data/clean/wvs_codebook.csv",
                                 show_col_types = FALSE) |>
  select(var, W4, W5, W6, W7)
# rows: var (several joined with "+", e.g. "pm_aims1+pm_aims2"), question, format, mapped,
# and optionally `side` to group rows under sub-headings
q_table <- function(rows, caption = "Questions used in this section") {
  first <- sub("\\+.*", "", rows$var)
  in_india <- vapply(first, function(v) {
    yrs <- india |> filter(!is.na(.data[[v]])) |> distinct(wave) |> pull(wave) |> sort()
    if (length(yrs)) paste(india_years[yrs], collapse = ", ") else "—"
  }, character(1))
  wave_ids <- function(v, w) {
    ids <- strsplit(v, "+", fixed = TRUE)[[1]]
    x <- codebook_vars[[w]][match(ids, codebook_vars$var)]
    x <- x[!is.na(x) & x != ""]
    if (length(x)) paste(x, collapse = " & ") else "—"
  }
  tab <- rows |> mutate(india_yrs = unname(in_india))
  for (w in c("W4", "W5", "W6", "W7")) tab[[w]] <- vapply(rows$var, wave_ids, character(1), w = w)
  k <- tab |>
    select(Question = question, `Response format` = format, `How it is counted / what it maps to` = mapped,
           `Asked in India` = india_yrs, W4, W5, W6, W7) |>
    kable(caption = caption) |>
    styled() |>
    add_header_above(c(" " = 4, "Question number in the WVS file" = 4)) |>
    column_spec(1, width = "17em") |>
    column_spec(3, width = "15em")
  if ("side" %in% names(rows)) k <- pack_rows(k, index = table(factor(rows$side, unique(rows$side))))
  k
}

# India over time, one number per cell (no intervals)
simple_trend <- function(tr, caption, mult = 100, digits = 0, footnote_text = NULL) {
  k <- tr |>
    mutate(cell = ifelse(is.na(est), "—", formatC(est * mult, format = "f", digits = digits)),
           year = india_years[wave]) |>
    select(item, year, cell) |>
    pivot_wider(names_from = year, values_from = cell) |>
    rename(` ` = item) |>
    (\(x) kable(x, caption = caption, align = c("l", rep("c", ncol(x) - 1))))() |>
    styled()
  if (!is.null(footnote_text)) k <- footnote(k, general = footnote_text, general_title = "")
  k
}

# change within India by group: one dot per survey year, joined by a line
plot_dumbbell <- function(v, waves, title, xlab, min_n = 50, mult = 100, w = 9, h = 7.5) {
  gl <- group_long(v) |>
    filter(wave %in% waves, n >= min_n) |>
    mutate(year = factor(india_years[wave], india_years[waves]), level = fct_rev(level))
  p <- ggplot(gl, aes(est * mult, level)) +
    geom_line(aes(group = level), colour = "#c3c2b7", linewidth = 0.9) +
    geom_point_interactive(aes(fill = year, data_id = paste(group, level, year),
                               tooltip = sprintf("%s: %s<br>%s: %.1f%% (n = %d)", group, level, year, est * mult, n)),
                           shape = 21, colour = "white", size = 3.6, stroke = 0.8) +
    facet_grid(group ~ ., scales = "free_y", space = "free_y", switch = "y") +
    scale_fill_manual(values = year_cols) +
    labs(title = title, x = xlab, y = NULL, caption = sprintf("Groups with fewer than %d respondents are not shown.", min_n)) +
    theme_wvs() +
    theme(strip.placement = "outside", strip.text.y.left = element_text(angle = 0, face = "bold"))
  show_plot(p, w, h)
}

What this report does

Part I sets out the data: which countries and waves, how India was sampled, who was interviewed, and how region averages are formed.

Part II asks one question from several angles: do Indians separate governance (a state that gets things done) from democratic accountability (checks on that state), and do they trade one for the other? The distinction between institutions that use power and institutions that check it comes from Fukuyama (2013, What Is Governance?). It is used here as a set of dimensions, not as the framework.

# Question What is calculated
1 How much do people trust the state, and the institutions that check it? Confidence in 8 institutions; a trust gap between the state and the institutions that check it
2 Do people want a state that delivers, a state that answers to them, or both? Two yes/no demands (delivery; accountability, including willingness to act) crossed into four groups
3 Do people hold a liberal, a minimalist or an illiberal idea of democracy? Three conception types; willingness to protest by type
4 Do people want the state to support the less well-off? A yes/no state-support category from five questions
5 Does it differ across Indian states? The main measures of sections 1 to 3 by state

Comparison set: India against Western Europe & Offshoots and the Middle East & North Africa (MENA), for the four waves from W4 (India 2001) to W7 (India 2023). The earlier 1995 wave is not used. Western Europe has only 4 countries in W4 (Canada, Spain, Sweden, USA).

Two caveats on India’s samples, set out in Part I:

  1. The 2001, 2006 and 2012 samples carry no weights: they are male-skewed and, in 2006 and 2012, mostly rural.
  2. The 2023 sample is a quota sample in 8 states.

Part I. Data, samples and coverage

knitr::opts_chunk$set(message = FALSE, warning = FALSE)
options(knitr.table.format = "html")

library(dplyr)
library(tidyr)
library(purrr)
library(tibble)
library(knitr)
library(kableExtra)

# All cleaning and categorisation happens in R/00_wvs_clean_harmonise.R
wvs_all <- readRDS("D:/Populism and Democrary/World value survey/data/clean/wvs_harmonised.rds")

# Comparison set for this project: India vs two regions
focus_regions <- c("India", "Western Europe & Offshoots", "Middle East & North Africa")
# W3 (1994-99, India 1995) is dropped from this report
wvs <- wvs_all |>
  filter(macro_region %in% focus_regions, wave != "W3") |>
  mutate(macro_region = droplevels(macro_region))

wave_labels <- c(W4 = "W4", W5 = "W5", W6 = "W6", W7 = "W7")
india_years <- c(W4 = "2001", W5 = "2006", W6 = "2012", W7 = "2023")
regions     <- levels(wvs$macro_region)

wmean <- function(x, w) {
  ok <- !is.na(x) & !is.na(w)
  if (!any(ok)) NA_real_ else sum(x[ok] * w[ok]) / sum(w[ok])
}
styled <- function(k) kable_styling(k, bootstrap_options = c("striped", "condensed"), full_width = FALSE)

The comparison set is India against two regions: Western Europe & Offshoots and the Middle East & North Africa (MENA). Every table in this part is restricted to these three groups.

Before testing any claim, this part sets out:

  • what each wave covers
  • how countries are grouped into regions, and how region averages are weighted
  • the demographic make-up of each region and of India
  • how the India samples were drawn and weighted
  • how often people give no answer

Part II uses the same data (data/clean/wvs_harmonised.rds) and the same region scheme.

The four waves

per_country <- wvs |> count(wave, country_code)

wvs |>
  group_by(wave) |>
  summarise(Fieldwork   = paste(min(survey_year, na.rm = TRUE), max(survey_year, na.rm = TRUE), sep = "–"),
            Countries   = n_distinct(country_code),
            Respondents = n(),
            `Under 18`  = sum(age < 18, na.rm = TRUE),
            .groups = "drop") |>
  left_join(per_country |> group_by(wave) |>
              summarise(`Median N per country` = median(n), `Smallest` = min(n), `Largest` = max(n)),
            by = "wave") |>
  mutate(`India survey` = india_years[wave]) |>
  rename(Wave = wave) |>
  kable(caption = "Coverage of the four waves (India, Western Europe & Offshoots, MENA)", format.args = list(big.mark = ",")) |>
  styled() |>
  footnote(general = "W3 (1994–99) is not used. 'Under 18': respondents aged 15–17 (a few countries sample from 15 or 16); Part II uses adults only.",
           general_title = "")
Coverage of the four waves (India, Western Europe & Offshoots, MENA)
Wave Fieldwork Countries Respondents Under 18 Median N per country Smallest Largest India survey
W4 1999–2004 13 23,873 299 1,502.0 1,015 3,401 2001
W5 2004–2008 23 33,658 107 1,200.0 954 3,051 2006
W6 2010–2014 22 32,798 5 1,202.5 841 4,078 2012
W7 2017–2023 21 33,430 323 1,203.0 447 4,018 2023
W3 (1994–99) is not used. ‘Under 18’: respondents aged 15–17 (a few countries sample from 15 or 16); Part II uses adults only.

Countries and regions

Region scheme

One region scheme covers every wave:

  • India is its own group.
  • Western Europe & Offshoots: Western European countries plus Australia, Canada, New Zealand and the USA. Cyprus and Greece are included.
  • Middle East & North Africa: the Arab states, Iran and Turkey.
  • Post-communist Central and Eastern Europe (Hungary, Poland and so on) is not in Western Europe. It sits in a separate region that is outside this comparison.
reg_n <- wvs |>
  distinct(wave, macro_region, country_code) |>
  count(macro_region, wave) |>
  pivot_wider(names_from = wave, values_from = n, values_fill = 0)

presence <- wvs |>
  distinct(country_code, macro_region, wave) |>
  group_by(country_code, macro_region) |>
  summarise(all4 = all(c("W4", "W5", "W6", "W7") %in% wave),
            w567 = all(c("W5", "W6", "W7") %in% wave), .groups = "drop") |>
  group_by(macro_region) |>
  summarise(`In all 4 waves` = sum(all4), `In W5, W6 and W7` = sum(w567), `Ever surveyed` = n())

tab <- reg_n |>
  left_join(presence, by = "macro_region") |>
  mutate(macro_region = as.character(macro_region))
tab <- bind_rows(tab, tab |> summarise(across(where(is.numeric), sum)) |> mutate(macro_region = "Total"))

tab |>
  rename(Region = macro_region) |>
  kable(caption = "Number of countries per region and wave") |>
  styled() |>
  row_spec(nrow(tab), bold = TRUE)
Number of countries per region and wave
Region W4 W5 W6 W7 In all 4 waves In W5, W6 and W7 Ever surveyed
India 1 1 1 1 1 1 1
Middle East & North Africa 8 6 13 9 5 5 15
Western Europe & Offshoots 4 16 8 11 1 6 18
Total 13 23 22 21 7 12 34

How to read this: the countries in each region change from wave to wave, so a change in a region’s average can reflect which countries were surveyed, not only changing attitudes. The section on region averages below shows how much this matters. Two cases need care:

  • The report starts with W4 (India 2001). The earlier wave W3 (India 1995) is dropped: its only MENA country was Turkey. W4 has 8 MENA countries (Algeria, Egypt, Iran, Iraq, Jordan, Morocco, Saudi Arabia, Turkey).
  • Western Europe is thin in W4 (4 countries: Canada, Spain, Sweden, USA) because the rest of Europe was surveyed that round by the separate European Values Study. It is also thin in W6 (8 countries).
  • Israel (surveyed in W4 only) is removed from the data altogether.
cl <- wvs |>
  count(macro_region, country_name, wave) |>
  mutate(n = format(n, big.mark = ",")) |>
  pivot_wider(names_from = wave, values_from = n, values_fill = "—") |>
  select(macro_region, Country = country_name, any_of(c("W4", "W5", "W6", "W7"))) |>
  arrange(macro_region, Country)

cl |>
  select(-macro_region) |>
  kable(caption = "Every country in the comparison, with respondents per wave", align = c("l", rep("r", 4))) |>
  styled() |>
  pack_rows(index = table(cl$macro_region)) |>
  scroll_box(height = "500px")
Every country in the comparison, with respondents per wave
Country W4 W5 W6 W7
India
India 2,002 2,001 4,078 1,692
Middle East & North Africa
Algeria 1,282 — 1,200 —
Egypt 3,000 3,051 1,523 1,200
Iran 2,532 2,667 — 1,499
Iraq 2,325 2,701 1,200 1,200
Jordan 1,223 1,200 1,200 1,203
Kuwait — — 1,303 —
Lebanon — — 1,200 1,200
Libya — — 2,131 1,196
Morocco 1,251 1,200 1,200 1,200
Palestine — — 1,000 —
Qatar — — 1,060 —
Saudi Arabia 1,502 — — —
Tunisia — — 1,205 1,208
Turkey 3,401 1,346 1,605 2,415
Yemen — — 1,000 —
Western Europe & Offshoots
Andorra — 1,003 — 1,004
Australia — 1,421 1,477 1,813
Canada 1,931 2,164 — 4,018
Cyprus — 1,050 1,000 1,000
Finland — 1,014 — —
France — 1,001 — —
Germany — 2,064 2,046 1,528
Greece — — — 1,200
Italy — 1,012 — —
Netherlands — 1,050 1,902 2,145
New Zealand — 954 841 1,057
Northern Ireland — — — 447
Norway — 1,025 — —
Spain 1,209 1,200 1,189 —
Sweden 1,015 1,003 1,206 —
Switzerland — 1,241 — —
United Kingdom — 1,041 — 2,609
United States 1,200 1,249 2,232 2,596

How region averages are weighted

Within a country: every estimate uses that country’s own survey weight (W4 V245, W5 V259, W6 V258, W7 W_WEIGHT). These weights correct each national sample towards the national population, mainly on sex, age and education.

Across countries (a region): the region value is the simple mean of its country estimates. Every country counts once, whatever its population or sample size:

  • The USA counts the same as New Zealand in Western Europe & Offshoots.
  • Egypt counts the same as Qatar in MENA.

This equals pooling respondents with the WVS equilibrated weight (S018), which rescales every country to N = 1,000.

India vs a region: India is always shown on its own. The comparison is therefore India vs the average country in each region, not India vs the region’s population. That is why every comparison table also gives India’s rank among the countries in the comparison (India plus the Western European and MENA countries surveyed in that wave). The rank does not depend on averaging.

Why not weight by population? Population-weighting would let the USA dominate Western Europe & Offshoots, and Egypt, Iran and Turkey dominate MENA. The WVS samples national publics, so the unit of comparison is the country.

The table below checks how much region averages move when only the countries surveyed in W5, W6 and W7 are kept (a balanced panel). The example indicator is “a strong leader who does not bother with parliament and elections is good”.

country_est <- wvs |>
  filter(is.na(age) | age >= 18) |>
  group_by(wave, country_code, macro_region) |>
  filter(any(!is.na(reg_strongleader_good))) |>
  summarise(est = 100 * wmean(reg_strongleader_good, weight), .groups = "drop")

panel_ids <- wvs |>
  distinct(country_code, wave) |>
  group_by(country_code) |>
  filter(all(c("W5", "W6", "W7") %in% wave)) |>
  distinct(country_code) |>
  pull()

bind_rows(
  country_est |> mutate(sample = "All countries"),
  country_est |> filter(country_code %in% panel_ids) |> mutate(sample = "Balanced panel (W5–W7)")
) |>
  filter(wave %in% c("W5", "W6", "W7")) |>
  group_by(macro_region, sample, wave) |>
  summarise(cell = sprintf("%.1f <small>(%d)</small>", mean(est), n()), .groups = "drop") |>
  pivot_wider(names_from = wave, values_from = cell, values_fill = "—") |>
  rename(Region = macro_region, Sample = sample) |>
  kable(escape = FALSE, caption = "Strong leader is good (%): all countries vs balanced panel") |>
  styled() |>
  collapse_rows(columns = 1, valign = "top") |>
  footnote(general = "Cells: mean of country estimates (number of countries). Adults only.",
           general_title = "")
Strong leader is good (%): all countries vs balanced panel
Region Sample W5 W6 W7
India All countries 63.9 (1) 64.9 (1) 69.1 (1)
Balanced panel (W5–W7) 63.9 (1) 64.9 (1) 69.1 (1)
Middle East & North Africa All countries 35.9 (6) 44.4 (12) 48.3 (9)
Balanced panel (W5–W7) 28.2 (5) 50.2 (5) 53.7 (5)
Western Europe & Offshoots All countries 24.2 (16) 31.1 (8) 28.2 (11)
Balanced panel (W5–W7) 29.3 (6) 29.1 (6) 33.3 (6)
Cells: mean of country estimates (number of countries). Adults only.

Demographic profile by region

Each cell is the mean of country-level weighted values, so it describes the average country in the region, as in Part II. All respondents are included.

Profile by wave

demo_country <- wvs |>
  group_by(wave, country_code, macro_region) |>
  summarise(
    `Female %`          = 100 * wmean(sex == 2, weight),
    `Mean age`          = wmean(age, weight),
    `18–34 %`           = 100 * wmean(age_cat3 == "18-34", weight),
    `55+ %`             = 100 * wmean(age_cat3 == "55+", weight),
    `Lower education %` = 100 * wmean(educ3 == "Lower", weight),
    `Higher education %`= 100 * wmean(educ3 == "Higher", weight),
    `Upper / upper-middle class %` = 100 * wmean(class3 == "Upper / upper middle", weight),
    `Lower class %`     = 100 * wmean(class3 == "Lower", weight),
    .groups = "drop")

for (w in c("W4", "W5", "W6", "W7")) {
  cat("\n\n#### ", w, " (India ", india_years[w], ")\n\n", sep = "")
  tab <- demo_country |>
    filter(wave == w) |>
    group_by(macro_region) |>
    summarise(Countries = n(), across(`Female %`:`Lower class %`, ~ mean(.x, na.rm = TRUE))) |>
    rename(Region = macro_region)
  print(tab |>
          kable(digits = 1, caption = paste("Demographic profile by region,", w)) |>
          styled() |>
          row_spec(which(tab$Region == "India"), bold = TRUE, background = "#FFF3D6"))
}

W4 (India 2001)

Demographic profile by region, W4
Region Countries Female % Mean age 18–34 % 55+ % Lower education % Higher education % Upper / upper-middle class % Lower class %
India 1 43.2 40.2 41.5 18.1 52.2 23.4 20.0 19.8
Middle East & North Africa 8 49.6 35.8 52.4 11.8 40.8 20.2 25.1 14.7
Western Europe & Offshoots 4 50.7 44.4 33.2 28.9 23.4 31.0 30.6 4.9

W5 (India 2006)

Demographic profile by region, W5
Region Countries Female % Mean age 18–34 % 55+ % Lower education % Higher education % Upper / upper-middle class % Lower class %
India 1 43.1 41.4 36.7 19.9 50.4 22.0 20.1 27.2
Middle East & North Africa 6 50.2 37.1 49.8 13.5 47.0 17.1 21.3 12.2
Western Europe & Offshoots 16 51.9 46.5 27.4 33.6 17.1 31.2 30.4 3.8

W6 (India 2012)

Demographic profile by region, W6
Region Countries Female % Mean age 18–34 % 55+ % Lower education % Higher education % Upper / upper-middle class % Lower class %
India 1 43.8 41.2 38.1 19.0 46.1 13.3 18.8 14.2
Middle East & North Africa 13 48.8 37.5 48.4 14.6 35.9 26.2 26.8 11.3
Western Europe & Offshoots 8 51.8 47.9 27.4 36.8 17.3 34.5 28.2 4.1

W7 (India 2023)

Demographic profile by region, W7
Region Countries Female % Mean age 18–34 % 55+ % Lower education % Higher education % Upper / upper-middle class % Lower class %
India 1 48.9 37.8 46.2 18.8 33.9 27.2 25.7 10.1
Middle East & North Africa 9 49.8 39.9 40.1 18.3 39.1 28.3 20.1 11.3
Western Europe & Offshoots 11 52.5 49.4 25.1 40.7 18.3 38.6 31.0 5.1

Religion by region

rel_country <- wvs |>
  filter(!is.na(religion_major)) |>
  group_by(wave, country_code, macro_region, religion_major) |>
  summarise(w = sum(weight), .groups = "drop_last") |>
  mutate(pct = 100 * w / sum(w)) |>
  ungroup() |>
  complete(nesting(wave, country_code, macro_region), religion_major, fill = list(pct = 0))

rel_country |>
  filter(wave == "W7") |>
  group_by(macro_region, religion_major) |>
  summarise(pct = mean(pct), .groups = "drop") |>
  pivot_wider(names_from = religion_major, values_from = pct) |>
  rename(Region = macro_region) |>
  kable(digits = 1, caption = "Religious denomination by region, W7 (% of respondents, mean of countries)") |>
  styled() |>
  scroll_box(width = "100%")
Religious denomination by region, W7 (% of respondents, mean of countries)
Region None Catholic Protestant Orthodox Jewish Muslim Hindu Buddhist Other Christian Other
India 0.0 1.2 0 0.0 0.0 9.5 83.0 1.4 0.0 4.8
Middle East & North Africa 0.7 3.4 0 1.0 0.0 94.4 0.0 0.0 0.5 0.1
Western Europe & Offshoots 36.8 21.3 12 15.6 0.6 4.3 0.8 0.7 6.6 1.4

The India samples

How each sample was drawn

tribble(
  ~` `,              ~`2001 (W4)`, ~`2006 (W5)`, ~`2012 (W6)`, ~`2023 (W7)`,
  "Fieldwork",       "2001", "Dec 2006 – Jan 2007", "2012", "5 Jun – 2 Jul 2023",
  "Organisation",    "Not documented in docs/", "Lokniti Network (PI Sandeep Shastri)", "Sandeep Shastri (Jain University CERRSE); W7 report credits Lokniti-CSDS", "Lokniti-CSDS",
  "Design",          "Not documented in docs/", "Multistage stratified random sample from electoral rolls: 40 Lok Sabha seats → 80 assembly seats → 160 polling stations → voters", "Four-stage stratified random sample from electoral rolls (Lok Sabha seats → assembly seats → polling stations → voters). Plan: 320 seats, 19,444 target", "8 states chosen purposively; 15 assembly seats (PPS); 60 polling stations; random-walk households; age and gender quotas",
  "States",          "18", "18 of 28 (97% of population)", "17", "8: Bihar, Delhi, Haryana, Maharashtra, Punjab, Telangana, UP, West Bengal",
  "Achieved N",      "2,002", "2,001", "4,078", "1,692 (1,371 aged 18+)",
  "Age range",       "18+", "18+", "18+", "16+ (321 aged 16–17 by design)",
  "Languages",       "—", "10", "—", "5",
  "Comparable as a national trend point?", "Yes", "Yes", "Yes", "Partly: 8 states, quota, 60 clusters"
) |>
  kable(caption = "India sample designs (from docs/ in each wave folder)") |>
  styled() |>
  column_spec(1, bold = TRUE) |>
  footnote(general = "Sources: W5 study description; W6 India sample design proposal; W7 India technical report (Lokniti-CSDS, July 2023). No India methodology document for W4 is in the project folder.",
           general_title = "")
India sample designs (from docs/ in each wave folder)
2001 (W4) 2006 (W5) 2012 (W6) 2023 (W7)
Fieldwork 2001 Dec 2006 – Jan 2007 2012 5 Jun – 2 Jul 2023
Organisation Not documented in docs/ Lokniti Network (PI Sandeep Shastri) Sandeep Shastri (Jain University CERRSE); W7 report credits Lokniti-CSDS Lokniti-CSDS
Design Not documented in docs/ Multistage stratified random sample from electoral rolls: 40 Lok Sabha seats → 80 assembly seats → 160 polling stations → voters Four-stage stratified random sample from electoral rolls (Lok Sabha seats → assembly seats → polling stations → voters). Plan: 320 seats, 19,444 target 8 states chosen purposively; 15 assembly seats (PPS); 60 polling stations; random-walk households; age and gender quotas
States 18 18 of 28 (97% of population) 17 8: Bihar, Delhi, Haryana, Maharashtra, Punjab, Telangana, UP, West Bengal
Achieved N 2,002 2,001 4,078 1,692 (1,371 aged 18+)
Age range 18+ 18+ 18+ 16+ (321 aged 16–17 by design)
Languages — 10 — 5
Comparable as a national trend point? Yes Yes Yes Partly: 8 states, quota, 60 clusters
Sources: W5 study description; W6 India sample design proposal; W7 India technical report (Lokniti-CSDS, July 2023). No India methodology document for W4 is in the project folder.

Where the interviews were done

wvs |>
  filter(is_india) |>
  count(in_state = tidyr::replace_na(in_state, "Not recorded"), wave) |>
  mutate(n = as.character(n)) |>
  pivot_wider(names_from = wave, values_from = n, values_fill = "—") |>
  rename(State = in_state, `2001` = W4, `2006` = W5, `2012` = W6, `2023` = W7) |>
  arrange(State) |>
  kable(caption = "India: interviews per state", align = c("l", rep("r", 4))) |>
  styled() |>
  footnote(general = "Bihar, Delhi, Haryana, Maharashtra, Punjab, Uttar Pradesh and West Bengal are the only states in all four waves.",
           general_title = "")
India: interviews per state
State 2001 2006 2012 2023
Andhra Pradesh 152 143 307 —
Assam 61 52 — —
Bihar 147 197 332 241
Chhattisgarh 46 44 99 —
Delhi 43 38 94 229
Gujarat 96 102 259 —
Haryana 50 44 122 115
Jharkhand 65 52 160 —
Karnataka 112 103 239 —
Kerala 71 59 192 —
Madhya Pradesh 115 104 256 —
Maharashtra 194 201 280 202
Not recorded — 1 — —
Odisha 68 75 355 —
Punjab 49 53 151 122
Rajasthan 102 112 278 —
Tamil Nadu 129 165 — —
Telangana — — — 210
Unlabelled (W6 code 356019) — — 64 —
Uttar Pradesh 328 301 596 360
West Bengal 174 155 294 213
Bihar, Delhi, Haryana, Maharashtra, Punjab, Uttar Pradesh and West Bengal are the only states in all four waves.

Who was interviewed: unweighted and weighted

Comparing the raw sample with the weighted one shows what the weight corrects.

india <- wvs |>
  filter(is_india) |>
  mutate(age_band = ifelse(!is.na(age) & age < 18, "16–17", as.character(age_cat3)))

profile_vars <- c(Sex = "sex_f", Age = "age_band", Education = "educ3", Religion = "in_religion",
                  Caste = "in_caste", `Subjective class` = "class3", `Town size` = "urban_size",
                  `Party would vote for` = "in_party_vote")

prof <- imap_dfr(profile_vars, function(v, lab) {
  india |>
    filter(!is.na(.data[[v]])) |>
    group_by(wave, level = as.character(.data[[v]])) |>
    summarise(n = n(), w = sum(weight), .groups = "drop_last") |>
    mutate(Unweighted = 100 * n / sum(n), Weighted = 100 * w / sum(w)) |>
    ungroup() |>
    mutate(group = lab)
})

prof_wide <- prof |>
  mutate(cell = sprintf("%.1f / %.1f", Unweighted, Weighted),
         group = factor(group, names(profile_vars)),
         year = india_years[wave]) |>
  select(group, level, year, cell) |>
  pivot_wider(names_from = year, values_from = cell, values_fill = "—") |>
  arrange(group) |>
  select(group, level, any_of(unname(india_years)))

prof_wide |>
  select(-group) |>
  rename(` ` = level) |>
  kable(caption = "India sample profile: unweighted % / weighted %", align = c("l", rep("c", 4))) |>
  styled() |>
  pack_rows(index = table(prof_wide$group)) |>
  footnote(general = "Percentages are among respondents with a valid answer on that variable. Caste was not asked in 2006.",
           general_title = "")
India sample profile: unweighted % / weighted %
2001 2006 2012 2023
Sex
Female 43.2 / 43.2 43.1 / 43.1 43.8 / 43.8 43.4 / 48.9
Male 56.8 / 56.8 56.9 / 56.9 56.2 / 56.2 56.6 / 51.1
Age
18-34 41.5 / 41.5 36.7 / 36.7 38.1 / 38.1 32.6 / 43.6
35-54 40.4 / 40.4 43.5 / 43.5 42.9 / 42.9 33.0 / 33.0
55+ 18.1 / 18.1 19.9 / 19.9 19.0 / 19.0 15.5 / 17.7
16–17 — — — 19.0 / 5.7
Education
Higher 23.4 / 23.4 22.0 / 22.0 13.3 / 13.3 23.1 / 27.2
Lower 52.2 / 52.2 50.4 / 50.4 46.1 / 46.1 32.2 / 33.9
Middle 24.4 / 24.4 27.6 / 27.6 40.6 / 40.6 44.6 / 38.9
Religion
Christian 3.0 / 3.0 3.2 / 3.2 1.6 / 1.6 1.0 / 1.2
Hindu 73.3 / 73.3 77.8 / 77.8 81.9 / 81.9 82.0 / 83.0
Muslim 11.0 / 11.0 8.3 / 8.3 11.0 / 11.0 10.4 / 9.5
None 6.7 / 6.7 3.0 / 3.0 0.4 / 0.4 —
Other (Sikh, Buddhist, Jain, …) 6.1 / 6.1 7.6 / 7.6 5.1 / 5.1 6.6 / 6.2
Caste
General / other 43.5 / 43.5 — 32.6 / 32.6 31.6 / 32.0
OBC 38.5 / 38.5 — 40.6 / 40.6 44.3 / 44.0
SC 12.9 / 12.9 — 20.1 / 20.1 19.1 / 19.2
ST 5.2 / 5.2 — 6.7 / 6.7 5.0 / 4.8
Subjective class
Lower 19.8 / 19.8 27.2 / 27.2 14.2 / 14.2 10.1 / 10.1
Lower middle / working 60.2 / 60.2 52.7 / 52.7 67.0 / 67.0 63.9 / 64.1
Upper / upper middle 20.0 / 20.0 20.1 / 20.1 18.8 / 18.8 26.0 / 25.7
Town size
100k+ 11.2 / 11.2 7.9 / 7.9 3.1 / 3.1 5.9 / 5.7
20k-100k 19.0 / 19.0 2.8 / 2.8 6.4 / 6.4 10.5 / 9.9
Under 20k 69.8 / 69.8 89.3 / 89.3 90.6 / 90.6 83.6 / 84.3
Party would vote for
BJP 28.1 / 28.1 21.5 / 21.5 28.2 / 28.2 46.0 / 45.1
INC 33.1 / 33.1 32.4 / 32.4 28.0 / 28.0 21.4 / 21.9
Left 7.1 / 7.1 8.9 / 8.9 5.5 / 5.5 3.9 / 4.0
No party / blank / other 0.3 / 0.3 8.2 / 8.2 2.2 / 2.2 9.2 / 9.3
Other party 31.5 / 31.5 28.9 / 28.9 36.2 / 36.2 19.6 / 19.7
Percentages are among respondents with a valid answer on that variable. Caste was not asked in 2006.

The India weights

india |>
  group_by(wave) |>
  summarise(N = n(),
            Min = min(weight), Max = max(weight), Mean = mean(weight),
            `CV of weights` = sd(weight) / mean(weight),
            `Design effect (1 + CV²)` = 1 + (sd(weight) / mean(weight))^2,
            `Effective N` = sum(weight)^2 / sum(weight^2),
            .groups = "drop") |>
  mutate(wave = india_years[wave]) |>
  rename(`Survey year` = wave) |>
  kable(digits = 2, caption = "India: survey weights", format.args = list(big.mark = ",")) |>
  styled() |>
  footnote(general = "Design effect here is from weighting only. Clustering (e.g. 60 polling stations in 2023) adds more, which the public data do not let us estimate.",
           general_title = "")
India: survey weights
Survey year N Min Max Mean CV of weights Design effect (1 + CV²) Effective N
2001 2,002 1.00 1.00 1 0.00 1.00 2,002.0
2006 2,001 1.00 1.00 1 0.00 1.00 2,001.0
2012 4,078 1.00 1.00 1 0.00 1.00 4,078.0
2023 1,692 0.19 1.94 1 0.44 1.19 1,419.8
Design effect here is from weighting only. Clustering (e.g. 60 polling stations in 2023) adds more, which the public data do not let us estimate.

The 2001, 2006 and 2012 India samples are unweighted. Every weight is 1, so “weighted” India estimates for those years are raw sample percentages. The profile table above shows what that means:

  • Men are 55–57% of respondents.
  • In 2006 and 2012 about 90% live in places under 20,000 people. The 2011 Census puts India’s urban share at about 31%.
  • Only 13% have higher education in 2012, against 22–23% in 2001 and 2006.

Only 2023 is weighted: 16–17 year olds are brought down from 19% to 6% of the sample, and the sex split is balanced. For India trends this means:

  1. Changes between 2012 and 2023 partly reflect a change from unweighted to weighted samples.
  2. Group breakdowns (by sex, education or town size) are more trustworthy than India totals, because they do not depend on the sample’s overall mix.
  3. A useful robustness check is to reweight 2001–2012 to Census sex × education × urban margins. This needs Census tables that are not in the project yet.

How often people give no answer

Share of respondents with no substantive answer (don’t know, refused, missing). Only countries where the item was asked are counted. The regional figures are the median country.

nr_items <- c(reg_democracy = "Democratic system good/bad",
              reg_strongleader = "Strong leader good/bad",
              reg_army = "Army rule good/bad",
              conf_parliament = "Confidence in parliament",
              lr_scale = "Left–right self-placement",
              econ_income = "Income equality scale",
              dem_importance = "Importance of democracy",
              income10 = "Income decile")

nr <- imap_dfr(nr_items, function(lab, v) {
  wvs |>
    group_by(wave, country_code, macro_region) |>
    filter(any(!is.na(.data[[v]]))) |>
    summarise(nr = 100 * wmean(is.na(.data[[v]]), weight), .groups = "drop") |>
    group_by(wave, macro_region) |>
    summarise(nr = median(nr), .groups = "drop") |>
    mutate(item = lab)
})

nr_wide <- nr |>
  mutate(macro_region = factor(macro_region, focus_regions),
         year = paste0(wave, " / ", india_years[wave]),
         cell = sprintf("%.0f", nr)) |>
  select(item, macro_region, year, cell) |>
  pivot_wider(names_from = year, values_from = cell, values_fill = "—") |>
  arrange(match(item, nr_items), macro_region)

nr_wide |>
  select(-item) |>
  rename(` ` = macro_region) |>
  kable(caption = "No answer (%): India and the median country in each region", align = c("l", rep("c", 4))) |>
  styled() |>
  pack_rows(index = table(factor(nr_wide$item, levels = unique(nr_wide$item))))
No answer (%): India and the median country in each region
W4 / 2001 W5 / 2006 W6 / 2012 W7 / 2023
Democratic system good/bad
India 27 24 12 8
Western Europe & Offshoots 6 3 3 4
Middle East & North Africa 13 8 7 3
Strong leader good/bad
India 28 29 13 9
Western Europe & Offshoots 4 4 6 4
Middle East & North Africa 12 11 9 4
Army rule good/bad
India 29 31 16 14
Western Europe & Offshoots 4 3 4 3
Middle East & North Africa 13 14 10 3
Confidence in parliament
India 25 25 12 8
Western Europe & Offshoots 3 4 3 2
Middle East & North Africa 11 6 7 3
Left–right self-placement
India 46 51 11 28
Western Europe & Offshoots 10 10 11 9
Middle East & North Africa 54 36 32 5
Income equality scale
India 19 18 7 3
Western Europe & Offshoots 1 1 2 1
Middle East & North Africa 2 2 3 0
Importance of democracy
India — 20 1 5
Western Europe & Offshoots — 1 2 2
Middle East & North Africa — 2 3 1
Income decile
India 1 0 1 1
Western Europe & Offshoots 9 9 5 4
Middle East & North Africa 10 1 1 1

Implication for Part II: India’s non-response on regime questions was around 24–31% in 2001 and 2006, well above the median Western European or MENA country. Percentages among those who answer therefore describe a more opinionated subset of Indians. That is why the analysis reports show the no-answer share next to every estimate.

Questions used in this report

Each question below is listed under the report heading where it is used. The table gives how the answer was recorded in the survey, how this report codes it, and the variable name in each wave’s data file (“—” = not asked in that wave).

codebook <- readr::read_csv("D:/Populism and Democrary/World value survey/data/clean/wvs_codebook.csv",
                            show_col_types = FALSE)

fmt_conf  <- "4-point Likert: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all"
fmt_reg   <- "4-point Likert: 1 very good, 2 fairly good, 3 fairly bad, 4 very bad"
fmt_ess   <- "10-point scale: 1 not an essential characteristic ... 10 an essential characteristic"
fmt_agr4  <- "4-point Likert: 1 strongly agree, 2 agree, 3 disagree, 4 strongly disagree"
fmt_agr5  <- "5-point Likert: 1 agree strongly ... 3 neither ... 5 strongly disagree"
fmt_freq  <- "4-point frequency: 1 often, 2 sometimes, 3 rarely, 4 never"

qtab <- tribble(
  ~heading, ~var, ~question, ~format, ~coding,
  # 1 trust
  "Trust in institutions (§1, §5)", "conf_civilservice", "Confidence in the civil service", fmt_conf, "1–2 = trusts. Institution that uses power",
  "Trust in institutions (§1, §5)", "conf_police", "Confidence in the police", fmt_conf, "1–2 = trusts. Uses power",
  "Trust in institutions (§1, §5)", "conf_army", "Confidence in the armed forces", fmt_conf, "1–2 = trusts. Uses power",
  "Trust in institutions (§1, §5)", "conf_govt", "Confidence in the government", fmt_conf, "1–2 = trusts. Uses power",
  "Trust in institutions (§1, §5)", "conf_parliament", "Confidence in parliament", fmt_conf, "1–2 = trusts. Institution that checks power",
  "Trust in institutions (§1, §5)", "conf_parties", "Confidence in political parties", fmt_conf, "1–2 = trusts. Checks power",
  "Trust in institutions (§1, §5)", "conf_press", "Confidence in the press", fmt_conf, "1–2 = trusts. Checks power",
  "Trust in institutions (§1, §5)", "conf_courts", "Confidence in the courts / justice system", fmt_conf, "1–2 = trusts. Checks power (not asked in W4)",
  # 2 governance and accountability
  "Governance and accountability (§2, §5)", "pm_aims1", "Aims of the country (1st choice): economic growth / strong defence / more say at work and in communities / beautiful cities", "Ranked: 1st choice of 4", "Growth 1st or 2nd = delivery yes; more say 1st or 2nd = accountability yes",
  "Governance and accountability (§2, §5)", "pm_aims2", "Aims of the country (2nd choice)", "Ranked: 2nd choice of 4", "As above",
  "Governance and accountability (§2, §5)", "pm_goals1", "Most important (1st choice): maintaining order / more say in government / fighting rising prices / free speech", "Ranked: 1st choice of 4", "Prices 1st or 2nd = delivery yes; more say 1st or 2nd = accountability yes",
  "Governance and accountability (§2, §5)", "pm_goals2", "Most important (2nd choice)", "Ranked: 2nd choice of 4", "As above",
  "Governance and accountability (§2, §5)", "pm_society1", "Most important (1st choice): stable economy / more humane society / ideas over money / fight against crime", "Ranked: 1st choice of 4", "Stable economy or fight against crime 1st or 2nd = delivery yes",
  "Governance and accountability (§2, §5)", "pm_society2", "Most important (2nd choice)", "Ranked: 2nd choice of 4", "As above",
  "Governance and accountability (§2, §5)", "act_petition", "Signing a petition", "3-point: 1 have done, 2 might do, 3 would never do", "1–2 = accountability yes",
  "Governance and accountability (§2, §5)", "act_demonstration", "Attending peaceful demonstrations", "3-point: 1 have done, 2 might do, 3 would never do", "1–2 = accountability yes; also shown by type (§3)",
  "Governance and accountability (§2, §5)", "act_boycott", "Joining in boycotts", "3-point: 1 have done, 2 might do, 3 would never do", "1–2 = accountability yes; also shown by type (§3)",
  # 3 conceptions
  "Conceptions of democracy (§3)", "dess_elections", "Essential to democracy: people choose their leaders in free elections", fmt_ess, "Liberal question: 7–10 = yes. 1–6 = Illiberal",
  "Conceptions of democracy (§3)", "dess_civilrights", "Essential to democracy: civil rights protect people from state oppression", fmt_ess, "Liberal question: 7–10 = yes",
  "Conceptions of democracy (§3)", "dess_women", "Essential to democracy: women have the same rights as men", fmt_ess, "Liberal question: 7–10 = yes",
  "Conceptions of democracy (§3)", "reg_democracy", "Having a democratic political system", fmt_reg, "Liberal question: 1–2 (good) = yes",
  "Conceptions of democracy (§3)", "dem_importance", "Importance of living in a democratically governed country", "10-point: 1 not at all ... 10 absolutely important", "Liberal question: 7–10 = yes",
  "Conceptions of democracy (§3)", "dess_army", "Essential to democracy: the army takes over when government is incompetent", fmt_ess, "Authoritarian question: 7–10 = yes",
  "Conceptions of democracy (§3)", "dess_religious", "Essential to democracy: religious authorities interpret the laws", fmt_ess, "Authoritarian question: 7–10 = yes",
  "Conceptions of democracy (§3)", "dess_obey", "Essential to democracy: people obey their rulers", fmt_ess, "Authoritarian question: 7–10 = yes",
  "Conceptions of democracy (§3)", "reg_army", "Having the army rule", fmt_reg, "Authoritarian question: 1–2 (good) = yes",
  "Conceptions of democracy (§3)", "reg_strongleader", "Having a strong leader who does not have to bother with parliament and elections", fmt_reg, "Authoritarian question: 1–2 (good) = yes",
  "Conceptions of democracy (§3)", "reg_experts", "Having experts, not government, make decisions", fmt_reg, "Authoritarian question: 1–2 (good) = yes",
  "Conceptions of democracy (§3)", "fut_authority", "In the near future: greater respect for authority", "3-point: 1 good thing, 2 don't mind, 3 bad thing", "Authoritarian question: 1 (good thing) = yes",
  # 4 state support
  "State support (§4)", "econ_govresp", "Government should take more responsibility to ensure everyone is provided for ... people should take more responsibility", "10-point scale between the two statements", "1–4 = yes",
  "State support (§4)", "econ_income", "Incomes should be made more equal ... we need larger income differences as incentives", "10-point scale between the two statements", "1–4 = yes",
  "State support (§4)", "dess_taxrich", "Essential to democracy: governments tax the rich and subsidise the poor", fmt_ess, "7–10 = yes",
  "State support (§4)", "dess_unemp", "Essential to democracy: people receive state aid for unemployment", fmt_ess, "7–10 = yes",
  "State support (§4)", "dess_incomeequal", "Essential to democracy: the state makes people's incomes equal", fmt_ess, "7–10 = yes. State supporter = yes to 3 or more of these 5",
  # background
  "Background: groups", "sex", "Respondent's sex", "Binary: 1 male, 2 female", "Male / female",
  "Background: groups", "age", "Age in years", "Numeric (years)", "18–34 / 35–54 / 55+",
  "Background: groups", "educ_level", "Highest education attained", "Categorical: 9 levels (W4–W6); ISCED 0–8 (W7)", "Lower / middle / higher (WVS standard cut)",
  "Background: groups", "party_vote_code", "Party would vote for if election tomorrow", "Categorical: country party list", "India: BJP / INC / Left / other party",
  "Background: groups", "religion_raw", "Religious denomination", "Categorical: denomination list", "India: Hindu / Muslim / Christian / other / none",
  "Background: groups", "in_caste_code", "Caste / community (India)", "Categorical: Lokniti caste list (W4); SC/ST/OBC/other (W6, W7)", "SC / ST / OBC / general & other"
)

src <- codebook |> select(var, W4, W5, W6, W7)
src <- bind_rows(src, tibble(var = "in_caste_code", W4 = "V242", W5 = NA, W6 = "V254", W7 = "Q290"))

qt <- qtab |>
  left_join(src, by = "var") |>
  mutate(across(W4:W7, ~ ifelse(is.na(.x) | .x == "", "—", .x)),
         heading = factor(heading, unique(qtab$heading))) |>
  arrange(heading)

qt |>
  select(Question = question, `How the answer was recorded` = format, `How this report codes it` = coding,
         W4, W5, W6, W7) |>
  kable(caption = "Questions used, response format and coding") |>
  styled() |>
  add_header_above(c(" " = 3, "Variable name in the data file" = 4)) |>
  pack_rows(index = table(qt$heading)) |>
  column_spec(1, width = "18em") |>
  scroll_box(height = "600px")
Questions used, response format and coding
Variable name in the data file
Question How the answer was recorded How this report codes it W4 W5 W6 W7
Trust in institutions (§1, §5)
Confidence in the civil service 4-point Likert: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. Institution that uses power V156 V141 V118 Q74
Confidence in the police 4-point Likert: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. Uses power V152 V136 V113 Q69
Confidence in the armed forces 4-point Likert: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. Uses power V148 V132 V109 Q65
Confidence in the government 4-point Likert: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. Uses power V153 V138 V115 Q71
Confidence in parliament 4-point Likert: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. Institution that checks power V155 V140 V117 Q73
Confidence in political parties 4-point Likert: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. Checks power V154 V139 V116 Q72
Confidence in the press 4-point Likert: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. Checks power V149 V133 V110 Q66
Confidence in the courts / justice system 4-point Likert: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. Checks power (not asked in W4) — V137 V114 Q70
Governance and accountability (§2, §5)
Aims of the country (1st choice): economic growth / strong defence / more say at work and in communities / beautiful cities Ranked: 1st choice of 4 Growth 1st or 2nd = delivery yes; more say 1st or 2nd = accountability yes V120 V69 V60 Q152
Aims of the country (2nd choice) Ranked: 2nd choice of 4 As above V121 V70 V61 Q153
Most important (1st choice): maintaining order / more say in government / fighting rising prices / free speech Ranked: 1st choice of 4 Prices 1st or 2nd = delivery yes; more say 1st or 2nd = accountability yes V122 V71 V62 Q154
Most important (2nd choice) Ranked: 2nd choice of 4 As above V123 V72 V63 Q155
Most important (1st choice): stable economy / more humane society / ideas over money / fight against crime Ranked: 1st choice of 4 Stable economy or fight against crime 1st or 2nd = delivery yes V124 V73 V64 Q156
Most important (2nd choice) Ranked: 2nd choice of 4 As above V125 V74 V65 Q157
Signing a petition 3-point: 1 have done, 2 might do, 3 would never do 1–2 = accountability yes V134 V96 V85 Q209
Attending peaceful demonstrations 3-point: 1 have done, 2 might do, 3 would never do 1–2 = accountability yes; also shown by type (§3) V136 V98 V87 Q211
Joining in boycotts 3-point: 1 have done, 2 might do, 3 would never do 1–2 = accountability yes; also shown by type (§3) V135 V97 V86 Q210
Conceptions of democracy (§3)
Essential to democracy: people choose their leaders in free elections 10-point scale: 1 not an essential characteristic … 10 an essential characteristic Liberal question: 7–10 = yes. 1–6 = Illiberal — V154 V133 Q243
Essential to democracy: civil rights protect people from state oppression 10-point scale: 1 not an essential characteristic … 10 an essential characteristic Liberal question: 7–10 = yes — V157 V136 Q246
Essential to democracy: women have the same rights as men 10-point scale: 1 not an essential characteristic … 10 an essential characteristic Liberal question: 7–10 = yes — V161 V139 Q249
Having a democratic political system 4-point Likert: 1 very good, 2 fairly good, 3 fairly bad, 4 very bad Liberal question: 1–2 (good) = yes V167 V151 V130 Q238
Importance of living in a democratically governed country 10-point: 1 not at all … 10 absolutely important Liberal question: 7–10 = yes — V162 V140 Q250
Essential to democracy: the army takes over when government is incompetent 10-point scale: 1 not an essential characteristic … 10 an essential characteristic Authoritarian question: 7–10 = yes — V156 V135 Q245
Essential to democracy: religious authorities interpret the laws 10-point scale: 1 not an essential characteristic … 10 an essential characteristic Authoritarian question: 7–10 = yes — V153 V132 Q242
Essential to democracy: people obey their rulers 10-point scale: 1 not an essential characteristic … 10 an essential characteristic Authoritarian question: 7–10 = yes — — V138 Q248
Having the army rule 4-point Likert: 1 very good, 2 fairly good, 3 fairly bad, 4 very bad Authoritarian question: 1–2 (good) = yes V166 V150 V129 Q237
Having a strong leader who does not have to bother with parliament and elections 4-point Likert: 1 very good, 2 fairly good, 3 fairly bad, 4 very bad Authoritarian question: 1–2 (good) = yes V164 V148 V127 Q235
Having experts, not government, make decisions 4-point Likert: 1 very good, 2 fairly good, 3 fairly bad, 4 very bad Authoritarian question: 1–2 (good) = yes V165 V149 V128 Q236
In the near future: greater respect for authority 3-point: 1 good thing, 2 don’t mind, 3 bad thing Authoritarian question: 1 (good thing) = yes V130 V78 V69 Q45
State support (§4)
Government should take more responsibility to ensure everyone is provided for … people should take more responsibility 10-point scale between the two statements 1–4 = yes V143 V118 V98 Q108
Incomes should be made more equal … we need larger income differences as incentives 10-point scale between the two statements 1–4 = yes V141 V116 V96 Q106
Essential to democracy: governments tax the rich and subsidise the poor 10-point scale: 1 not an essential characteristic … 10 an essential characteristic 7–10 = yes — V152 V131 Q241
Essential to democracy: people receive state aid for unemployment 10-point scale: 1 not an essential characteristic … 10 an essential characteristic 7–10 = yes — V155 V134 Q244
Essential to democracy: the state makes people’s incomes equal 10-point scale: 1 not an essential characteristic … 10 an essential characteristic 7–10 = yes. State supporter = yes to 3 or more of these 5 — — V137 Q247
Background: groups
Respondent’s sex Binary: 1 male, 2 female Male / female V223 V235 V240 Q260
Age in years Numeric (years) 18–34 / 35–54 / 55+ V225 V237 V242 Q262
Highest education attained Categorical: 9 levels (W4–W6); ISCED 0–8 (W7) Lower / middle / higher (WVS standard cut) V226 V238 V248 Q275
Party would vote for if election tomorrow Categorical: country party list India: BJP / INC / Left / other party V220 V231 V228 Q223
Religious denomination Categorical: denomination list India: Hindu / Muslim / Christian / other / none V184G V185 V144G Q289
Caste / community (India) Categorical: Lokniti caste list (W4); SC/ST/OBC/other (W6, W7) SC / ST / OBC / general & other V242 — V254 Q290

How the questions build the §3 conception types

Each question is scored yes or no. The liberal score and the authoritarian score are the shares of each set answered yes; the democracy score is the liberal score minus the authoritarian score (−1 to +1). The types are bands of the democracy score.

tribble(
  ~Question, ~`Counted as yes`, ~Set,
  "Free elections essential to democracy", "7–10", "Liberal",
  "Civil rights essential to democracy", "7–10", "Liberal",
  "Women's equal rights essential to democracy", "7–10", "Liberal",
  "Having a democratic political system", "Good (1–2)", "Liberal",
  "Importance of living in a democracy", "7–10", "Liberal",
  "Army takeover essential to democracy", "7–10", "Authoritarian",
  "Religious authorities interpret the laws, essential to democracy", "7–10", "Authoritarian",
  "People obey their rulers, essential to democracy (from 2012)", "7–10", "Authoritarian",
  "Having the army rule", "Good (1–2)", "Authoritarian",
  "Having a strong leader who does not bother with parliament and elections", "Good (1–2)", "Authoritarian",
  "Having experts, not government, make decisions", "Good (1–2)", "Authoritarian",
  "Greater respect for authority", "Good thing (1)", "Authoritarian"
) |>
  kable(caption = "Questions used to build the three conception types") |>
  styled() |>
  column_spec(1, width = "24em") |>
  footnote(general = c("Liberal (maximalist) = democracy score 0.5 or more, with free elections 7–10.",
                       "Minimalist (electoral) = democracy score above 0 and below 0.5, with free elections 7–10.",
                       "Illiberal = democracy score 0 or less, or free elections 1–6.",
                       "Classified if free elections (asked from 2006) and at least three questions in each set were answered.",
                       "State support is a separate yes/no dimension built from five other questions (§4); it cuts across these types."),
           general_title = "")
Questions used to build the three conception types
Question Counted as yes Set
Free elections essential to democracy 7–10 Liberal
Civil rights essential to democracy 7–10 Liberal
Women’s equal rights essential to democracy 7–10 Liberal
Having a democratic political system Good (1–2) Liberal
Importance of living in a democracy 7–10 Liberal
Army takeover essential to democracy 7–10 Authoritarian
Religious authorities interpret the laws, essential to democracy 7–10 Authoritarian
People obey their rulers, essential to democracy (from 2012) 7–10 Authoritarian
Having the army rule Good (1–2) Authoritarian
Having a strong leader who does not bother with parliament and elections Good (1–2) Authoritarian
Having experts, not government, make decisions Good (1–2) Authoritarian
Greater respect for authority Good thing (1) Authoritarian
Liberal (maximalist) = democracy score 0.5 or more, with free elections 7–10.
Minimalist (electoral) = democracy score above 0 and below 0.5, with free elections 7–10.
Illiberal = democracy score 0 or less, or free elections 1–6.
Classified if free elections (asked from 2006) and at least three questions in each set were answered.
State support is a separate yes/no dimension built from five other questions (§4); it cuts across these types.

Part II. Governance and accountability

1. How much do people trust the state, and the institutions that check it?

The question. Some institutions exercise state power: the civil service, police, army and government. Others check it: parliament, parties, the press and courts. How much do people trust each one, and do they trust the state more than the institutions that check it?

What is calculated.

  • Each institution separately: % with a great deal or quite a lot of confidence.
  • Trust gap. For each respondent: share of the 4 state institutions trusted minus share of the 4 checking institutions trusted, in percentage points. Positive means more trust in the state than in the institutions that check it.
q_table(tribble(
  ~var, ~question, ~format, ~mapped,
  "conf_civilservice", "Confidence in the civil service", fmt_conf, "1–2 = trusts. State (uses power)",
  "conf_police", "Confidence in the police", fmt_conf, "1–2 = trusts. State (uses power)",
  "conf_army", "Confidence in the armed forces", fmt_conf, "1–2 = trusts. State (uses power)",
  "conf_govt", "Confidence in the government", fmt_conf, "1–2 = trusts. State (uses power)",
  "conf_parliament", "Confidence in parliament", fmt_conf, "1–2 = trusts. Checks power",
  "conf_parties", "Confidence in political parties", fmt_conf, "1–2 = trusts. Checks power",
  "conf_press", "Confidence in the press", fmt_conf, "1–2 = trusts. Checks power",
  "conf_courts", "Confidence in the courts", fmt_conf, "1–2 = trusts. Checks power"))
Questions used in this section
Question number in the WVS file
Question Response format How it is counted / what it maps to Asked in India W4 W5 W6 W7
Confidence in the civil service 4-point: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. State (uses power) 2001, 2006, 2012, 2023 V156 V141 V118 Q74
Confidence in the police 4-point: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. State (uses power) 2001, 2006, 2012, 2023 V152 V136 V113 Q69
Confidence in the armed forces 4-point: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. State (uses power) 2001, 2006, 2012, 2023 V148 V132 V109 Q65
Confidence in the government 4-point: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. State (uses power) 2001, 2006, 2012, 2023 V153 V138 V115 Q71
Confidence in parliament 4-point: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. Checks power 2001, 2006, 2012, 2023 V155 V140 V117 Q73
Confidence in political parties 4-point: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. Checks power 2001, 2006, 2012, 2023 V154 V139 V116 Q72
Confidence in the press 4-point: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. Checks power 2001, 2006, 2012, 2023 V149 V133 V110 Q66
Confidence in the courts 4-point: 1 a great deal, 2 quite a lot, 3 not very much, 4 none at all 1–2 = trusts. Checks power 2006, 2012, 2023 — V137 V114 Q70

Each institution

inst8 <- c(conf_civilservice_hi = "Civil service", conf_police_hi = "Police",
           conf_army_hi = "Armed forces", conf_govt_hi = "Government",
           conf_parliament_hi = "Parliament", conf_parties_hi = "Political parties",
           conf_press_hi = "Press", conf_courts_hi = "Courts")
simple_trend(india_trend(inst8), caption = "India: % with a great deal or quite a lot of confidence") |>
  pack_rows("Institutions that use power (the state)", 1, 4) |>
  pack_rows("Institutions that check power", 5, 8)
India: % with a great deal or quite a lot of confidence
2001 2006 2012 2023
Institutions that use power (the state)
Civil service 49 54 61 81
Police 38 64 51 67
Armed forces 92 83 87 87
Government 56 55 50 65
Institutions that check power
Parliament 55 62 58 74
Political parties 34 46 37 43
Press 70 76 72 66
Courts — 69 64 74
trust8 <- imap_dfr(inst8, function(lab, v) {
  country_est(v) |>
    group_by(wave, macro_region) |>
    summarise(est = mean(est), k = n(), .groups = "drop") |>
    mutate(inst = lab)
}) |>
  mutate(inst = factor(inst, inst8),
         macro_region = factor(macro_region, focus_regions),
         wave_short = factor(sub(" .*", "", wave_labels[wave]), c("W4", "W5", "W6", "W7")))

p <- ggplot(trust8, aes(wave_short, est, colour = macro_region, group = macro_region)) +
  geom_line(linewidth = 0.8) +
  geom_point_interactive(aes(fill = macro_region, data_id = paste(inst, macro_region, wave),
                             tooltip = sprintf("%s<br>%s, %s: %.0f%%<br>%d %s", inst, macro_region,
                                               wave_labels[wave], est, k, ifelse(k == 1, "country", "countries"))),
                         shape = 21, colour = "white", size = 2.6, stroke = 0.7) +
  facet_wrap(~ inst, ncol = 4) +
  scale_colour_manual(values = region_cols, breaks = focus_regions) +
  scale_fill_manual(values = region_cols, guide = "none") +
  scale_y_continuous(limits = c(0, 100), breaks = c(0, 25, 50, 75, 100)) +
  labs(title = "Confidence in each institution: India vs the two regions",
       x = NULL, y = "% a great deal or quite a lot",
       caption = paste0("Top row: institutions that use power (state). Bottom row: institutions that check it.
",
                        "Courts not asked in W4. Regions: mean of countries. India: W4 2001, W5 2006, W6 2012, W7 2023.")) +
  theme_wvs(10) + theme(panel.spacing = unit(1.2, "lines"))
show_plot(p, 11, 6.5)

The trust gap

simple_trend(india_trend(c(state_trust = "Trust in the state (% of 4 institutions trusted)",
                           check_trust = "Trust in checking institutions (% of 4 trusted)",
                           trust_gap   = "Gap (points)")),
             caption = "India: trust in the two sides of the state",
             footnote_text = "2001: no question on the courts, so the checking figure uses 3 institutions.")
India: trust in the two sides of the state
2001 2006 2012 2023
Trust in the state (% of 4 institutions trusted) 59 65 62 75
Trust in checking institutions (% of 4 trusted) 54 64 58 64
Gap (points) 5 1 4 11
2001: no question on the courts, so the checking figure uses 3 institutions.
plot_india_lines(india_trend(c(state_trust = "Trust in the state", check_trust = "Trust in checking institutions")),
                 title = "India: trust in the state vs trust in the institutions that check it",
                 ylab = "% of institutions trusted",
                 caption = "Shaded bands: 95% CI. 2001 checking index excludes courts (not asked in W4), so 2001 is not comparable.")
region_compare("trust_gap", caption = "Trust gap (state minus checking, percentage points), by region")
Trust gap (state minus checking, percentage points), by region
Region W4 (1999–2004) W5 (2004–09) W6 (2010–16) W7 (2017–23)
India 4.7 (1) 0.7 (1) 4.2 (1) 10.7 (1)
Western Europe & Offshoots 21.6 (3) 19.0 (16) 18.2 (8) 23.5 (11)
Middle East & North Africa 22.0 (6) 15.5 (4) 15.1 (13) 19.9 (8)
India’s rank among countries shown (1 = highest) 9 of 10 21 of 21 21 of 22 20 of 20
Cells: mean of country estimates (number of countries). W4 has no courts item, so its checking-trust index uses 3 institutions.
plot_country_dots("trust_gap", title = "Trust gap by country: India is at or near the bottom in every wave",
                  xlab = "Trust in state minus trust in checking institutions (percentage points)")
india_groups("trust_gap", caption = "India: trust gap (percentage points), by group")
India: trust gap (percentage points), by group
2001 2006 2012 2023
Sex
Male 3.5 (917) 0.8 (962) 4.3 (2145) 10.1 (754)
Female 7.0 (507) 0.6 (571) 4.1 (1506) 11.4 (555)
Age
18-34 4.2 (622) 0.9 (585) 3.5 (1436) 11.7 (531)
35-54 5.4 (575) 0.9 (662) 4.9 (1546) 9.3 (537)
55+ 4.6 (225) -0.1 (287) 4.2 (651) 11.1 (241)
Education
Lower 4.5 (564) 0.5 (687) 4.9 (1551) 9.6 (452)
Middle 6.2 (410) 0.2 (454) 3.7 (1575) 10.5 (487)
Higher 3.6 (446) 1.9 (390) 3.9 (521) 12.3 (368)
Party
BJP 4.1 (362) 2.5 (353) 5.0 (950) 12.1 (513)
INC 4.5 (349) -1.1 (488) 4.6 (904) 11.2 (240)
Left 4.7 (99) -4.0 (132) -2.7 (199) n=44
Other party 1.8 (352) 3.0 (453) 3.8 (1216) 10.2 (213)
Religion
Hindu 3.5 (1005) 0.0 (1142) 4.6 (2989) 11.3 (1080)
Muslim 6.1 (137) -1.4 (125) -0.5 (419) 6.4 (130)
Christian 11.7 (57) n=42 0.3 (60) n=13
Other (Sikh, Buddhist, Jain, …) -0.2 (105) 5.4 (124) 11.8 (169) 10.2 (83)
Caste
SC -1.9 (155) — 4.8 (704) 11.2 (253)
ST 11.9 (66) — 1.5 (226) 2.9 (64)
OBC 4.1 (510) — 4.3 (1476) 10.6 (562)
General / other 5.6 (645) — 4.1 (1183) 11.8 (430)
Cells: estimate (unweighted n). Cells with n < 50 are not estimated.

What this shows.

  • India has the smallest trust gap of all countries shown in 2006, 2012 and 2023 (9th of 10 in 2001). In Western Europe and MENA people trust the state institutions (above all police and army) 15–24 points more than the institutions that check them. In India the two were level in 2006. The 2001 figure (4.7) is not comparable: W4 has no question on the courts, one of the most trusted institutions, so the checking index uses only parliament, parties and press. In the six common states the 2001 gap is 0.7.
  • The gap is opening. It was 4 points in 2012 and 11 in 2023. It still opens when only the seven states surveyed every wave are used (9.6 points in 2023; see the robustness table in section 5). Trust in the state jumped in 2023 while trust in checking institutions did not.
  • The gap is widespread within India. In 2023 it is 9–12 points in almost every group: sex, age, education, BJP and INC voters, all castes except ST. The shift is not driven by one constituency. Muslims have the smallest gap.

2. Governance, accountability, or both?

The question. The passage argued that Indians want both democracy and a strong, effective government. Do people want a state that delivers, a state that answers to them, or both? And are the two demands held by the same people?

What is calculated. Two yes/no measures for each respondent:

  • Demand for governance (delivery), four questions: picks economic growth, fighting rising prices, a stable economy and the fight against crime among the top two aims (each counts as a separate yes). All four were asked in every survey from 2001.
  • Demand for accountability, including willingness to act, five questions: picks more say in government decisions, and more say at work and in communities, among the top two aims; has signed or would sign a petition, has attended or would attend a peaceful demonstration, has joined or would join a boycott. All five were asked in every survey from 2001. Petition, demonstration and boycott record willingness to take part, so this side measures participation as well as preference. A robustness check below shows the groups without demonstrations and boycotts. (Free elections and civil rights as essentials of democracy belong to the conception types in section 3.)

A respondent demands governance (or accountability) if they say yes to at least half of the questions they answered (2 of 4 for delivery, 3 of 5 for accountability). Those who skipped more than one of the questions asked in their survey are not classified; that share is shown separately. Crossing the two demands gives four groups: Accountability-first (accountability only), Want both, Governance-first (governance only) and Neither.

How to read it. “Want both” is the group the passage describes. Governance-first is the group that cares about results more than about holding government to account. Three questions on each side come from “pick your top two” lists, so choosing more delivery aims leaves less room for accountability aims; the groups partly reflect that trade-off.

fmt_rank <- function(list) paste0("Ranked: 1st and 2nd choice from 4 options (", list, ")")
aims_list    <- "economic growth / strong defence / more say at work and in communities / beautiful cities"
goals_list   <- "maintaining order / more say in government / fighting rising prices / free speech"
society_list <- "stable economy / more humane society / ideas over money / fight against crime"
fmt_act <- "3-point: 1 have done, 2 might do, 3 would never do"
gov_side <- "Governance (delivery): yes on at least half of 4"
acc_side <- "Accountability, including willingness to act: yes on at least half of 5"
q_table(tribble(
  ~side, ~var, ~question, ~format, ~mapped,
  gov_side, "pm_aims1+pm_aims2", "Aims of the country: a high level of economic growth", fmt_rank(aims_list), "Picked 1st or 2nd = yes",
  gov_side, "pm_goals1+pm_goals2", "Most important for the country: fighting rising prices", fmt_rank(goals_list), "Picked 1st or 2nd = yes",
  gov_side, "pm_society1+pm_society2", "Most important: a stable economy", fmt_rank(society_list), "Picked 1st or 2nd = yes",
  gov_side, "pm_society1+pm_society2", "Most important: the fight against crime", fmt_rank(society_list), "Picked 1st or 2nd = yes",
  acc_side, "pm_goals1+pm_goals2", "Most important for the country: giving people more say in important government decisions", fmt_rank(goals_list), "Picked 1st or 2nd = yes",
  acc_side, "pm_aims1+pm_aims2", "Aims of the country: people have more say about how things are done at their jobs and in their communities", fmt_rank(aims_list), "Picked 1st or 2nd = yes",
  acc_side, "act_petition", "Signing a petition", fmt_act, "1–2 (done or might do) = yes",
  acc_side, "act_demonstration", "Attending peaceful demonstrations", fmt_act, "1–2 (done or might do) = yes",
  acc_side, "act_boycott", "Joining in boycotts", fmt_act, "1–2 (done or might do) = yes"),
  caption = "Questions used in this section")
Questions used in this section
Question number in the WVS file
Question Response format How it is counted / what it maps to Asked in India W4 W5 W6 W7
Governance (delivery): yes on at least half of 4
Aims of the country: a high level of economic growth Ranked: 1st and 2nd choice from 4 options (economic growth / strong defence / more say at work and in communities / beautiful cities) Picked 1st or 2nd = yes 2001, 2006, 2012, 2023 V120 & V121 V69 & V70 V60 & V61 Q152 & Q153
Most important for the country: fighting rising prices Ranked: 1st and 2nd choice from 4 options (maintaining order / more say in government / fighting rising prices / free speech) Picked 1st or 2nd = yes 2001, 2006, 2012, 2023 V122 & V123 V71 & V72 V62 & V63 Q154 & Q155
Most important: a stable economy Ranked: 1st and 2nd choice from 4 options (stable economy / more humane society / ideas over money / fight against crime) Picked 1st or 2nd = yes 2001, 2006, 2012, 2023 V124 & V125 V73 & V74 V64 & V65 Q156 & Q157
Most important: the fight against crime Ranked: 1st and 2nd choice from 4 options (stable economy / more humane society / ideas over money / fight against crime) Picked 1st or 2nd = yes 2001, 2006, 2012, 2023 V124 & V125 V73 & V74 V64 & V65 Q156 & Q157
Accountability, including willingness to act: yes on at least half of 5
Most important for the country: giving people more say in important government decisions Ranked: 1st and 2nd choice from 4 options (maintaining order / more say in government / fighting rising prices / free speech) Picked 1st or 2nd = yes 2001, 2006, 2012, 2023 V122 & V123 V71 & V72 V62 & V63 Q154 & Q155
Aims of the country: people have more say about how things are done at their jobs and in their communities Ranked: 1st and 2nd choice from 4 options (economic growth / strong defence / more say at work and in communities / beautiful cities) Picked 1st or 2nd = yes 2001, 2006, 2012, 2023 V120 & V121 V69 & V70 V60 & V61 Q152 & Q153
Signing a petition 3-point: 1 have done, 2 might do, 3 would never do 1–2 (done or might do) = yes 2001, 2006, 2012, 2023 V134 V96 V85 Q209
Attending peaceful demonstrations 3-point: 1 have done, 2 might do, 3 would never do 1–2 (done or might do) = yes 2001, 2006, 2012, 2023 V136 V98 V87 Q211
Joining in boycotts 3-point: 1 have done, 2 might do, 3 would never do 1–2 (done or might do) = yes 2001, 2006, 2012, 2023 V135 V97 V86 Q210
gt_share <- function(d) {
  d |>
    group_by(wave) |>
    summarise(across(c(g_accfirst, g_both, g_govfirst),
                     ~ 100 * weighted.mean(.x, weight, na.rm = TRUE)),
              g_neither = 100 - g_accfirst - g_both - g_govfirst,
              unclassified = 100 * sum(weight[is.na(gtype)]) / sum(weight),
              .groups = "drop")
}
gt_labels <- c(g_accfirst = "Accountability-first", g_both = "Want both",
               g_govfirst = "Governance-first", g_neither = "Neither",
               unclassified = "Could not be classified (% of all adults)")

india |>
  filter(wave %in% c("W4", "W5", "W6", "W7")) |>
  gt_share() |>
  pivot_longer(-wave) |>
  mutate(name = factor(gt_labels[name], gt_labels), year = india_years[wave]) |>
  select(Group = name, year, value) |>
  pivot_wider(names_from = year, values_from = value) |>
  kable(digits = 1, caption = "India: governance and accountability groups (% of those classified)") |>
  styled() |>
  row_spec(5, italic = TRUE)
India: governance and accountability groups (% of those classified)
Group 2001 2006 2012 2023
Accountability-first 4.8 6.1 6.0 14.3
Want both 43.0 43.7 35.0 32.7
Governance-first 47.3 44.7 53.4 44.0
Neither 4.9 5.5 5.6 9.0
Could not be classified (% of all adults) 25.8 29.2 17.3 13.9
gt_country <- wvs |>
  filter(wave %in% c("W4", "W5", "W6", "W7")) |>
  group_by(wave, country_code, macro_region) |>
  filter(sum(!is.na(gtype)) > 100) |>
  summarise(across(c(g_accfirst, g_both, g_govfirst),
                   ~ 100 * weighted.mean(.x, weight, na.rm = TRUE)), .groups = "drop") |>
  mutate(g_neither = 100 - g_accfirst - g_both - g_govfirst)

gt_country |>
  group_by(wave, macro_region) |>
  summarise(across(g_accfirst:g_neither, mean), k = n(), .groups = "drop") |>
  pivot_longer(g_accfirst:g_neither) |>
  mutate(cell = sprintf("%.1f", value), Group = factor(gt_labels[name], gt_labels),
         col = paste(wave_labels[wave])) |>
  select(Group, macro_region, col, cell) |>
  pivot_wider(names_from = col, values_from = cell, values_fill = "—") |>
  arrange(Group, factor(macro_region, focus_regions)) |>
  select(-Group) |>
  rename(Region = macro_region) |>
  kable(caption = "Governance and accountability groups by region (%, mean of countries)") |>
  styled() |>
  pack_rows(index = table(factor(rep(gt_labels[1:4], each = 3), gt_labels[1:4])))
Governance and accountability groups by region (%, mean of countries)
Region W4 (1999–2004) W5 (2004–09) W6 (2010–16) W7 (2017–23)
Accountability-first
India 4.8 6.1 6.0 14.3
Western Europe & Offshoots 17.2 17.3 11.0 16.7
Middle East & North Africa 9.7 4.6 5.0 6.7
Want both
India 43.0 43.7 35.0 32.7
Western Europe & Offshoots 62.2 58.0 60.1 57.3
Middle East & North Africa 32.5 29.3 24.3 23.6
Governance-first
India 47.3 44.7 53.4 44.0
Western Europe & Offshoots 18.9 22.1 27.1 23.9
Middle East & North Africa 52.6 62.1 65.0 61.7
Neither
India 4.9 5.5 5.6 9.0
Western Europe & Offshoots 1.7 2.6 1.7 2.1
Middle East & North Africa 5.2 4.1 5.6 8.0
gt_cols <- c(`Accountability-first` = "#256abf", `Want both` = "#9ec5f4",
             `Governance-first` = "#e34948", Neither = "#bdbcb6")
gt_plot <- bind_rows(
  india |> filter(wave %in% c("W4", "W5", "W6", "W7")) |> gt_share() |> select(-unclassified) |>
    mutate(macro_region = "India"),
  gt_country |> filter(macro_region != "India") |>
    group_by(wave, macro_region) |> summarise(across(g_accfirst:g_neither, mean), .groups = "drop") |>
    mutate(macro_region = as.character(macro_region))
) |>
  pivot_longer(g_accfirst:g_neither, names_to = "type", values_to = "pct") |>
  mutate(type = factor(gt_labels[type], gt_labels[1:4]),
         macro_region = factor(macro_region, rev(focus_regions)),
         wave_lab = factor(wave_labels[wave], wave_labels))

p <- ggplot(gt_plot, aes(pct, macro_region, fill = type)) +
  geom_col(width = 0.62, colour = "white", linewidth = 0.6, position = position_stack(reverse = TRUE)) +
  geom_text(aes(label = ifelse(pct >= 7, sprintf("%.0f", pct), ""), group = type,
                colour = type %in% c("Accountability-first", "Governance-first")),
            position = position_stack(vjust = 0.5, reverse = TRUE), size = 3, show.legend = FALSE) +
  facet_wrap(~ wave_lab, ncol = 1) +
  scale_fill_manual(values = gt_cols) +
  scale_colour_manual(values = c(`TRUE` = "white", `FALSE` = ink), guide = "none") +
  scale_x_continuous(expand = expansion(mult = c(0, 0.03)), labels = function(x) paste0(x, "%")) +
  labs(title = "Governance and accountability groups", x = NULL, y = NULL,
       caption = "% of those classified. Regions: mean of countries.") +
  theme_wvs() + theme(panel.grid.major.y = element_blank())
p   # static: interactive bars need a newer ggiraph than is available for R 4.3

india_groups("g_both", caption = "India: 'Want both' (% of those classified), by group")
India: ‘Want both’ (% of those classified), by group
2001 2006 2012 2023
Sex
Male 51.3 (932) 50.3 (892) 41.7 (1966) 37.5 (693)
Female 29.1 (554) 32.3 (524) 25.8 (1405) 27.1 (496)
Age
18-34 43.6 (640) 44.1 (564) 37.6 (1307) 33.4 (485)
35-54 43.5 (614) 43.1 (610) 33.8 (1451) 34.0 (488)
55+ 40.0 (230) 43.8 (242) 32.7 (599) 27.9 (216)
Education
Lower 37.0 (625) 33.9 (578) 24.2 (1449) 25.1 (380)
Middle 41.4 (413) 44.8 (440) 43.6 (1426) 32.1 (456)
Higher 53.0 (443) 56.9 (394) 42.1 (494) 41.0 (351)
Party
BJP 41.4 (370) 50.2 (311) 41.2 (876) 34.0 (471)
INC 48.2 (394) 42.4 (465) 34.4 (864) 32.6 (224)
Left 35.8 (95) 31.6 (152) 26.8 (198) n=42
Other party 46.0 (359) 48.4 (401) 32.4 (1155) 30.9 (195)
Religion
Hindu 41.8 (1082) 43.6 (1046) 34.9 (2724) 32.0 (973)
Muslim 35.6 (132) 31.2 (128) 36.7 (392) 24.3 (118)
Christian 54.0 (50) 52.9 (51) 47.5 (61) n=14
Other (Sikh, Buddhist, Jain, …) 55.3 (103) 45.3 (117) 28.9 (180) 47.8 (81)
Caste
SC 52.5 (160) — 29.6 (673) 31.1 (227)
ST 50.0 (68) — 38.5 (226) 20.5 (59)
OBC 38.9 (553) — 33.6 (1338) 34.2 (503)
General / other 44.6 (655) — 38.8 (1081) 33.3 (400)
Cells: estimate (unweighted n). Cells with n < 50 are not estimated.
india_groups("g_govfirst", caption = "India: 'Governance-first' (% of those classified), by group")
India: ‘Governance-first’ (% of those classified), by group
2001 2006 2012 2023
Sex
Male 39.2 (932) 38.5 (892) 46.9 (1966) 37.8 (693)
Female 61.0 (554) 55.5 (524) 62.5 (1405) 51.2 (496)
Age
18-34 47.3 (640) 46.5 (564) 51.6 (1307) 43.5 (485)
35-54 45.8 (614) 44.6 (610) 53.9 (1451) 42.6 (488)
55+ 51.3 (230) 41.3 (242) 55.8 (599) 48.3 (216)
Education
Lower 55.2 (625) 52.6 (578) 63.1 (1449) 49.8 (380)
Middle 47.0 (413) 43.0 (440) 45.6 (1426) 44.6 (456)
Higher 36.3 (443) 35.0 (394) 47.6 (494) 37.6 (351)
Party
BJP 53.0 (370) 36.0 (311) 47.4 (876) 43.1 (471)
INC 42.1 (394) 47.1 (465) 54.5 (864) 36.2 (224)
Left 52.6 (95) 58.6 (152) 62.1 (198) n=42
Other party 44.8 (359) 39.7 (401) 56.1 (1155) 46.5 (195)
Religion
Hindu 49.3 (1082) 46.0 (1046) 53.7 (2724) 44.7 (973)
Muslim 54.5 (132) 58.6 (128) 48.7 (392) 47.7 (118)
Christian 36.0 (50) 27.5 (51) 42.6 (61) n=14
Other (Sikh, Buddhist, Jain, …) 32.0 (103) 37.6 (117) 64.4 (180) 34.5 (81)
Caste
SC 42.5 (160) — 58.4 (673) 44.9 (227)
ST 33.8 (68) — 50.4 (226) 49.6 (59)
OBC 52.3 (553) — 54.0 (1338) 40.7 (503)
General / other 44.4 (655) — 50.7 (1081) 47.0 (400)
Cells: estimate (unweighted n). Cells with n < 50 are not estimated.
plot_dumbbell("g_govfirst", waves = c("W4", "W5", "W6", "W7"),
              title = "India: 'Governance-first' by group, 2001 → 2023",
              xlab = "% governance-first (of those classified)")

Robustness: accountability without demonstrations and boycotts

Willingness to protest depends on opportunity as well as preference: safety, mobility, time and social norms all hold some groups back, women above all. This check rebuilds the accountability side from the other three questions only (more say in government, more say at work, petition) and compares the groups.

gt_lv <- c("Accountability-first", "Want both", "Governance-first", "Neither")
gt_dist <- function(d, v) {
  d |>
    filter(!is.na(.data[[v]])) |>
    group_by(g = factor(as.character(.data[[v]]), gt_lv)) |>
    summarise(p = sum(weight), .groups = "drop") |>
    mutate(p = 100 * p / sum(p))
}
gt_versions <- function(v) {
  ind <- india |>
    group_by(wave) |>
    group_modify(~ gt_dist(.x, v)) |>
    ungroup() |>
    transmute(g, col = paste("India", india_years[wave]), p)
  reg <- wvs |>
    filter(wave == "W7", !is_india) |>
    group_by(macro_region, country_code) |>
    group_modify(~ gt_dist(.x, v)) |>
    ungroup() |>
    complete(nesting(macro_region, country_code), g, fill = list(p = 0)) |>
    group_by(macro_region, g) |>
    summarise(p = mean(p), .groups = "drop") |>
    transmute(g, col = ifelse(grepl("Western", macro_region), "W. Europe 2023", "MENA 2023"), p)
  bind_rows(ind, reg)
}
rob <- bind_rows(gt_versions("gtype") |> mutate(version = "With demonstrations and boycotts (main measure)"),
                 gt_versions("gtype_pref") |> mutate(version = "Without demonstrations and boycotts"))
rob_cols <- c(paste("India", india_years), "W. Europe 2023", "MENA 2023")
rob_w <- rob |>
  mutate(col = factor(col, rob_cols)) |>
  arrange(version, g, col) |>
  pivot_wider(names_from = col, values_from = p)
rob_w |>
  select(-version) |>
  rename(` ` = g) |>
  kable(digits = 1, caption = "Governance and accountability groups, with and without demonstrations and boycotts (%)") |>
  styled() |>
  pack_rows(index = table(rob_w$version))
Governance and accountability groups, with and without demonstrations and boycotts (%)
India 2001 India 2006 India 2012 India 2023 W. Europe 2023 MENA 2023
With demonstrations and boycotts (main measure)
Accountability-first 4.8 6.1 6.0 14.3 16.7 6.7
Want both 43.0 43.7 35.0 32.7 57.3 23.6
Governance-first 47.3 44.7 53.4 44.0 23.9 61.7
Neither 4.9 5.5 5.6 9.0 2.1 8.0
Without demonstrations and boycotts
Accountability-first 6.8 6.7 6.8 14.7 17.2 9.2
Want both 34.1 37.5 30.6 25.4 54.1 22.7
Governance-first 55.8 51.4 58.3 51.4 27.0 62.5
Neither 3.3 4.3 4.3 8.5 1.6 5.5
bind_rows(
  india |> filter(wave == "W7", !is.na(sex_f)) |> group_by(sex_f) |> group_modify(~ gt_dist(.x, "gtype")) |>
    mutate(version = "With demonstrations and boycotts"),
  india |> filter(wave == "W7", !is.na(sex_f)) |> group_by(sex_f) |> group_modify(~ gt_dist(.x, "gtype_pref")) |>
    mutate(version = "Without")
) |>
  ungroup() |>
  mutate(col = paste0(sex_f, ": ", version)) |>
  select(g, col, p) |>
  pivot_wider(names_from = col, values_from = p) |>
  arrange(g) |>
  rename(` ` = g) |>
  kable(digits = 1, caption = "India 2023: groups by sex, with and without demonstrations and boycotts (%)") |>
  styled()
India 2023: groups by sex, with and without demonstrations and boycotts (%)
Male: With demonstrations and boycotts Female: With demonstrations and boycotts Male: Without Female: Without
Accountability-first 16.0 12.4 16.4 12.7
Want both 37.5 27.1 26.2 24.4
Governance-first 37.8 51.2 49.1 54.0
Neither 8.7 9.3 8.2 8.9

What this shows.

  • Governance-first is India’s largest group in every survey: 47% (2001), 45% (2006), 53% (2012), 44% (2023). India sits between Western Europe (24% in 2023) and MENA (62%).
  • Accountability-first more than doubled in 2023, from about 6% in every earlier survey to 14%, close to Western Europe (17%) and well above MENA (7%).
  • “Want both” has shrunk: 43–44% in 2001 and 2006, 35% in 2012, 33% in 2023. It remains far below Western Europe (57%) but above MENA (24%). The passage’s “want both” group exists, but it is not the majority and it is not growing.
  • The four surveys are directly comparable: both sides use the same questions in every survey from 2001.
  • Within India, 2023:
    • Women are more often governance-first than men (51% vs 38%).
    • Education matters: “want both” rises from 25% (less educated) to 41% (highly educated); governance-first falls from 50% to 38%.
    • BJP voters are more often governance-first than INC voters (43% vs 36%).
    • Muslims are less often “want both” than Hindus (24% vs 32%).
  • Robustness: without demonstrations and boycotts the picture holds. Governance-first is higher everywhere (India 51% in 2023), India still sits between the two regions, and accountability-first still rises in 2023. The gender gap in governance-first narrows from 13 points (51% vs 38%) to 5 (54% vs 49%): most of it comes from women’s lower willingness or ability to protest, not from different preferences.
  • Caution: 26% (2001) and 29% (2006) of Indian adults could not be classified (17% in 2012, 14% in 2023).

3. Liberal, minimalist or illiberal democrats?

The question. A minimalist conception of democracy asks for free elections and rejects authoritarian alternatives, but does not insist on civil rights, equal rights and a firm commitment to democracy. A maximalist liberal conception insists on all of these. An illiberal conception either does not treat free elections as essential, or accepts authoritarian ways of governing. Which do people hold?

What is calculated. Two sets of questions, each answered yes or no (see the table):

  • Liberal questions (5): free elections, civil rights and women’s equal rights rated 7–10 as essential to democracy; a democratic political system is good; living in a democracy is important (7–10).
  • Authoritarian questions (7): army takeover and religious authorities rated 7–10 as essential to democracy; “people obey their rulers” rated 7–10; army rule, a strong leader without parliament and elections, and experts deciding instead of government called good; greater respect for authority a good thing.

Each respondent gets two scores: the liberal score, the share of the liberal questions they answered yes, and the authoritarian score, the share of the authoritarian questions they answered yes. The democracy score is the liberal score minus the authoritarian score. It runs from −1 (yes to every authoritarian question, no to every liberal one) to +1 (the reverse). This follows Kirsch and Welzel’s measure of liberal minus authoritarian notions of democracy. The three types are bands of this one score:

  • Liberal (maximalist): democracy score of 0.5 or more, with free elections rated 7–10. Liberal answers clearly outweigh authoritarian ones.
  • Minimalist (electoral): democracy score above 0 but below 0.5, with free elections rated 7–10. They lean democratic, but only by a modest margin.
  • Illiberal: democracy score of 0 or less (authoritarian answers match or outweigh liberal ones), or free elections rated 1–6.

A respondent is classified if they answered the free-elections question (asked from 2006) and at least three questions in each set. “People obey their rulers” was asked only from 2012, so in 2006 the authoritarian score uses six questions.

Also shown for each type: willingness to attend a peaceful demonstration or join a boycott, to see whether liberals act on their views. State support is a separate dimension (section 4).

lib_side  <- "Liberal questions: liberal score = share answered yes"
aut_side  <- "Authoritarian questions: authoritarian score = share answered yes"
show_side <- "Shown for each type (not used in the rules)"
q_table(tribble(
  ~side, ~var, ~question, ~format, ~mapped,
  lib_side, "dess_elections", "Essential to democracy: people choose their leaders in free elections", fmt_ess, "7–10 = yes. 1–6 = Illiberal whatever the score",
  lib_side, "dess_civilrights", "Essential to democracy: civil rights protect people from state oppression", fmt_ess, "7–10 = yes",
  lib_side, "dess_women", "Essential to democracy: women have the same rights as men", fmt_ess, "7–10 = yes",
  lib_side, "reg_democracy", "Having a democratic political system", fmt_reg, "1–2 (good) = yes",
  lib_side, "dem_importance", "How important is it for you to live in a country that is governed democratically?", "10-point: 1 not at all important ... 10 absolutely important", "7–10 = yes",
  aut_side, "dess_army", "Essential to democracy: the army takes over when government is incompetent", fmt_ess, "7–10 = yes",
  aut_side, "dess_religious", "Essential to democracy: religious authorities ultimately interpret the laws", fmt_ess, "7–10 = yes",
  aut_side, "dess_obey", "Essential to democracy: people obey their rulers", fmt_ess, "7–10 = yes (from 2012)",
  aut_side, "reg_army", "Having the army rule", fmt_reg, "1–2 (good) = yes",
  aut_side, "reg_strongleader", "Having a strong leader who does not have to bother with parliament and elections", fmt_reg, "1–2 (good) = yes",
  aut_side, "reg_experts", "Having experts, not government, make decisions according to what they think is best for the country", fmt_reg, "1–2 (good) = yes",
  aut_side, "fut_authority", "In the near future: greater respect for authority", "3-point: 1 good thing, 2 don't mind, 3 bad thing", "1 (good thing) = yes",
  show_side, "act_demonstration", "Attending peaceful demonstrations", "3-point: 1 have done, 2 might do, 3 would never do", "1–2 = done or might do",
  show_side, "act_boycott", "Joining in boycotts", "3-point: 1 have done, 2 might do, 3 would never do", "1–2 = done or might do"),
  caption = "Questions used in this section")
Questions used in this section
Question number in the WVS file
Question Response format How it is counted / what it maps to Asked in India W4 W5 W6 W7
Liberal questions: liberal score = share answered yes
Essential to democracy: people choose their leaders in free elections 10-point: 1 not an essential characteristic of democracy … 10 an essential characteristic 7–10 = yes. 1–6 = Illiberal whatever the score 2006, 2012, 2023 — V154 V133 Q243
Essential to democracy: civil rights protect people from state oppression 10-point: 1 not an essential characteristic of democracy … 10 an essential characteristic 7–10 = yes 2006, 2012, 2023 — V157 V136 Q246
Essential to democracy: women have the same rights as men 10-point: 1 not an essential characteristic of democracy … 10 an essential characteristic 7–10 = yes 2006, 2012, 2023 — V161 V139 Q249
Having a democratic political system 4-point: 1 very good, 2 fairly good, 3 fairly bad, 4 very bad 1–2 (good) = yes 2001, 2006, 2012, 2023 V167 V151 V130 Q238
How important is it for you to live in a country that is governed democratically? 10-point: 1 not at all important … 10 absolutely important 7–10 = yes 2006, 2012, 2023 — V162 V140 Q250
Authoritarian questions: authoritarian score = share answered yes
Essential to democracy: the army takes over when government is incompetent 10-point: 1 not an essential characteristic of democracy … 10 an essential characteristic 7–10 = yes 2006, 2012, 2023 — V156 V135 Q245
Essential to democracy: religious authorities ultimately interpret the laws 10-point: 1 not an essential characteristic of democracy … 10 an essential characteristic 7–10 = yes 2006, 2012, 2023 — V153 V132 Q242
Essential to democracy: people obey their rulers 10-point: 1 not an essential characteristic of democracy … 10 an essential characteristic 7–10 = yes (from 2012) 2012, 2023 — — V138 Q248
Having the army rule 4-point: 1 very good, 2 fairly good, 3 fairly bad, 4 very bad 1–2 (good) = yes 2001, 2006, 2012, 2023 V166 V150 V129 Q237
Having a strong leader who does not have to bother with parliament and elections 4-point: 1 very good, 2 fairly good, 3 fairly bad, 4 very bad 1–2 (good) = yes 2001, 2006, 2012, 2023 V164 V148 V127 Q235
Having experts, not government, make decisions according to what they think is best for the country 4-point: 1 very good, 2 fairly good, 3 fairly bad, 4 very bad 1–2 (good) = yes 2001, 2006, 2012, 2023 V165 V149 V128 Q236
In the near future: greater respect for authority 3-point: 1 good thing, 2 don’t mind, 3 bad thing 1 (good thing) = yes 2001, 2006, 2012, 2023 V130 V78 V69 Q45
Shown for each type (not used in the rules)
Attending peaceful demonstrations 3-point: 1 have done, 2 might do, 3 would never do 1–2 = done or might do 2001, 2006, 2012, 2023 V136 V98 V87 Q211
Joining in boycotts 3-point: 1 have done, 2 might do, 3 would never do 1–2 = done or might do 2001, 2006, 2012, 2023 V135 V97 V86 Q210
conc_vars <- c("con_liberal", "con_minimal", "con_illiberal")
conc_share <- function(d) {
  d |>
    group_by(wave) |>
    summarise(across(all_of(conc_vars), ~ 100 * weighted.mean(.x, weight, na.rm = TRUE)),
              unclassified = 100 * sum(weight[is.na(conception)]) / sum(weight),
              .groups = "drop")
}
conc_labels <- c(con_liberal = "Liberal (maximalist)", con_minimal = "Minimalist (electoral)",
                 con_illiberal = "Illiberal", unclassified = "Could not be classified (% of all adults)")

india |>
  filter(wave %in% c("W5", "W6", "W7")) |>
  conc_share() |>
  pivot_longer(-wave) |>
  mutate(name = factor(conc_labels[name], conc_labels), year = india_years[wave]) |>
  select(Type = name, year, value) |>
  pivot_wider(names_from = year, values_from = value) |>
  kable(digits = 1, caption = "India: conceptions of democracy (% of those classified)") |>
  styled() |>
  row_spec(4, italic = TRUE)
India: conceptions of democracy (% of those classified)
Type 2006 2012 2023
Liberal (maximalist) 25.0 29.5 26.4
Minimalist (electoral) 35.8 34.7 40.7
Illiberal 39.2 35.9 32.9
Could not be classified (% of all adults) 25.9 1.8 9.5
conc_country <- wvs |>
  filter(wave %in% c("W5", "W6", "W7")) |>
  group_by(wave, country_code, macro_region) |>
  filter(sum(!is.na(conception)) > 100) |>
  summarise(across(all_of(conc_vars), ~ 100 * weighted.mean(.x, weight, na.rm = TRUE)), .groups = "drop")

conc_country |>
  group_by(wave, macro_region) |>
  summarise(across(all_of(conc_vars), mean), .groups = "drop") |>
  pivot_longer(all_of(conc_vars)) |>
  mutate(cell = sprintf("%.1f", value), Type = factor(conc_labels[name], conc_labels[1:3]),
         col = wave_labels[wave]) |>
  select(Type, macro_region, col, cell) |>
  pivot_wider(names_from = col, values_from = cell, values_fill = "—") |>
  arrange(Type, factor(macro_region, focus_regions)) |>
  select(-Type) |>
  rename(Region = macro_region) |>
  kable(caption = "Conceptions of democracy by region (%, mean of countries)") |>
  styled() |>
  pack_rows(index = table(factor(rep(conc_labels[1:3], each = 3), conc_labels[1:3])))
Conceptions of democracy by region (%, mean of countries)
Region W5 (2004–09) W6 (2010–16) W7 (2017–23)
Liberal (maximalist)
India 25.0 29.5 26.4
Western Europe & Offshoots 73.1 67.1 68.9
Middle East & North Africa 30.3 21.2 23.3
Minimalist (electoral)
India 35.8 34.7 40.7
Western Europe & Offshoots 13.3 16.6 15.7
Middle East & North Africa 42.9 38.2 36.7
Illiberal
India 39.2 35.9 32.9
Western Europe & Offshoots 13.6 16.3 15.3
Middle East & North Africa 26.8 40.5 40.0
conc_cols <- c(`Liberal (maximalist)` = "#0d366b", `Minimalist (electoral)` = "#256abf", Illiberal = "#86b6ef")
conc_plot <- bind_rows(
  india |> filter(wave %in% c("W5", "W6", "W7")) |> conc_share() |> select(-unclassified) |>
    mutate(macro_region = "India"),
  conc_country |> filter(macro_region != "India") |>
    group_by(wave, macro_region) |> summarise(across(all_of(conc_vars), mean), .groups = "drop") |>
    mutate(macro_region = as.character(macro_region))
) |>
  pivot_longer(all_of(conc_vars), names_to = "type", values_to = "pct") |>
  mutate(type = factor(conc_labels[type], conc_labels[1:3]),
         macro_region = factor(macro_region, rev(focus_regions)),
         wave_lab = factor(wave_labels[wave], wave_labels))

p <- ggplot(conc_plot, aes(pct, macro_region, fill = type)) +
  geom_col(width = 0.62, colour = "white", linewidth = 0.6, position = position_stack(reverse = TRUE)) +
  geom_text(aes(label = ifelse(pct >= 6, sprintf("%.0f", pct), ""), group = type,
                colour = type %in% conc_labels[1:2]),
            position = position_stack(vjust = 0.5, reverse = TRUE), size = 3, show.legend = FALSE) +
  facet_wrap(~ wave_lab, ncol = 1) +
  scale_fill_manual(values = conc_cols) +
  scale_colour_manual(values = c(`TRUE` = "white", `FALSE` = ink), guide = "none") +
  scale_x_continuous(expand = expansion(mult = c(0, 0.03)), labels = function(x) paste0(x, "%")) +
  labs(title = "Conceptions of democracy: liberal, minimalist, illiberal",
       x = NULL, y = NULL,
       caption = "% of those classified. Regions: mean of countries. Essentials of democracy were first asked in 2006.") +
  theme_wvs() + theme(panel.grid.major.y = element_blank())
p   # static: interactive bars need a newer ggiraph than is available for R 4.3

plot_country_dots("con_liberal", waves = c("W5", "W6", "W7"),
                  title = "Liberal (maximalist) conception, by country",
                  xlab = "% liberal (maximalist) (of those classified)")
india_groups("con_liberal", caption = "India: liberal (maximalist) conception (% of those classified), by group")
India: liberal (maximalist) conception (% of those classified), by group
2006 2012 2023
Sex
Male 25.7 (925) 29.8 (2251) 25.9 (718)
Female 23.7 (557) 29.0 (1750) 27.0 (531)
Age
18-34 25.4 (574) 29.4 (1512) 27.6 (512)
35-54 25.6 (657) 29.7 (1708) 24.1 (510)
55+ 22.3 (251) 29.1 (760) 27.9 (227)
Education
Lower 18.0 (616) 25.2 (1842) 21.7 (413)
Middle 26.8 (456) 32.8 (1616) 25.5 (475)
Higher 33.3 (408) 34.0 (539) 32.6 (359)
Party
BJP 26.0 (331) 22.5 (1035) 25.6 (494)
INC 26.6 (473) 37.0 (1016) 20.7 (231)
Left 27.2 (158) 46.0 (202) n=39
Other party 22.2 (423) 27.7 (1308) 28.4 (210)
Religion
Hindu 24.9 (1105) 29.4 (3276) 26.3 (1031)
Muslim 29.1 (117) 25.6 (441) 28.6 (119)
Christian 27.8 (54) 52.3 (65) n=14
Other (Sikh, Buddhist, Jain, …) 22.7 (110) 30.7 (205) 24.4 (82)
Caste
SC — 27.1 (771) 29.8 (237)
ST — 40.5 (259) 20.8 (65)
OBC — 29.0 (1616) 24.3 (538)
General / other — 28.2 (1292) 28.2 (409)
Cells: estimate (unweighted n). Cells with n < 50 are not estimated.
india_groups("con_illiberal", caption = "India: illiberal conception (% of those classified), by group")
India: illiberal conception (% of those classified), by group
2006 2012 2023
Sex
Male 36.2 (925) 35.0 (2251) 35.2 (718)
Female 44.2 (557) 37.0 (1750) 30.2 (531)
Age
18-34 39.2 (574) 36.1 (1512) 31.5 (512)
35-54 39.3 (657) 35.5 (1708) 34.7 (510)
55+ 39.0 (251) 37.0 (760) 32.9 (227)
Education
Lower 48.1 (616) 38.9 (1842) 38.7 (413)
Middle 32.5 (456) 34.8 (1616) 33.3 (475)
Higher 33.3 (408) 28.9 (539) 26.1 (359)
Party
BJP 36.6 (331) 40.6 (1035) 35.0 (494)
INC 38.1 (473) 31.5 (1016) 40.9 (231)
Left 24.1 (158) 24.8 (202) n=39
Other party 48.0 (423) 35.9 (1308) 30.7 (210)
Religion
Hindu 39.1 (1105) 36.4 (3276) 32.2 (1031)
Muslim 37.6 (117) 39.0 (441) 42.0 (119)
Christian 44.4 (54) 18.5 (65) n=14
Other (Sikh, Buddhist, Jain, …) 33.6 (110) 24.9 (205) 33.2 (82)
Caste
SC — 34.4 (771) 33.0 (237)
ST — 31.3 (259) 29.6 (65)
OBC — 37.3 (1616) 37.6 (538)
General / other — 36.8 (1292) 27.0 (409)
Cells: estimate (unweighted n). Cells with n < 50 are not estimated.
plot_dumbbell("con_illiberal", waves = c("W5", "W6", "W7"),
              title = "India: illiberal share by group",
              xlab = "% illiberal (of those classified)")

Do liberals act on their views?

For each conception type: the % who have taken part, or would take part, in a peaceful demonstration or a boycott. India uses its own weight. The regions pool their countries with each country weighted equally (equilibrated weight).

cross_tab <- function(v, caption, rows = "conception") {
  groups <- list(
    `India 2006` = filter(india, wave == "W5"), `India 2012` = filter(india, wave == "W6"),
    `India 2023` = filter(india, wave == "W7"),
    `W. Europe 2023` = filter(wvs, wave == "W7", macro_region == "Western Europe & Offshoots"),
    `MENA 2023` = filter(wvs, wave == "W7", macro_region == "Middle East & North Africa"))
  imap_dfr(groups, function(d, nm) {
    w <- if (grepl("India", nm)) "weight" else "weight_eq"
    d |>
      filter(!is.na(.data[[rows]])) |>
      group_by(row = .data[[rows]]) |>
      group_modify(~ wstat(.x[[v]], .x[[w]])) |>
      ungroup() |>
      mutate(sample = nm)
  }) |>
    mutate(cell = ifelse(n < 50, sprintf("<small>n=%d</small>", n), sprintf("%.1f <small>(%d)</small>", est * 100, n)),
           sample = factor(sample, c("India 2006", "India 2012", "India 2023", "W. Europe 2023", "MENA 2023"))) |>
    select(row, sample, cell) |>
    rename(` ` = row) |>
    pivot_wider(names_from = sample, values_from = cell, values_fill = "—") |>
    kable(escape = FALSE, caption = caption, align = c("l", rep("c", 5))) |>
    styled() |>
    footnote(general = "Cells: % (unweighted n). Cells with n < 50 are not estimated.", general_title = "")
}
cross_tab("acc_demo", "Has attended or might attend a peaceful demonstration (%), by conception")
Has attended or might attend a peaceful demonstration (%), by conception
India 2006 India 2012 India 2023 W. Europe 2023 MENA 2023
Liberal (maximalist) 53.6 (332) 55.2 (1057) 57.0 (321) 75.8 (12663) 44.1 (2805)
Minimalist (electoral) 49.9 (465) 44.8 (1188) 53.2 (474) 58.8 (2752) 34.5 (4095)
Illiberal 46.7 (480) 43.7 (1160) 63.7 (383) 58.5 (2915) 32.1 (4593)
Cells: % (unweighted n). Cells with n < 50 are not estimated.
cross_tab("acc_boycott", "Has joined or might join a boycott (%), by conception")
Has joined or might join a boycott (%), by conception
India 2006 India 2012 India 2023 W. Europe 2023 MENA 2023
Liberal (maximalist) 55.2 (337) 47.7 (1032) 40.6 (314) 66.8 (12564) 40.4 (2785)
Minimalist (electoral) 46.0 (474) 35.8 (1164) 40.5 (463) 49.0 (2742) 31.5 (4079)
Illiberal 45.9 (481) 34.4 (1148) 48.7 (366) 50.4 (2912) 29.9 (4579)
Cells: % (unweighted n). Cells with n < 50 are not estimated.

What this shows.

  • Minimalists are India’s largest group. In 2023, 41% of Indians are minimalist, 26% liberal and 33% illiberal. Western Europe is the mirror image: 69% liberal, 16% minimalist, 15% illiberal. MENA is closest to India (23% liberal, 37% minimalist, 40% illiberal).
  • India is moving towards the minimalist position. Minimalists rose from 36% (2006, 2012) to 41% (2023), while illiberals fell from 39% to 33%. The liberal share has stayed at 25–30%.
  • Within India, 2023:
    • Education matters most: 33% of the highly educated are liberal, against 22% of the less educated; illiberals are 26% and 39%.
    • Muslims are more often illiberal than Hindus (42% vs 32%).
    • INC voters are now more often illiberal than BJP voters (41% vs 35%); in 2012 it was the other way round (32% vs 41%).
    • Women are slightly less often illiberal than men (30% vs 35%); in 2006 they were more often illiberal (44% vs 36%).
  • Do liberals act on their views? In Western Europe yes, in India no longer. In Western Europe 76% of liberals would attend a peaceful demonstration, against 59% of illiberals. In India liberals were slightly ahead in 2006 and 2012 (55% vs 44% in 2012), but in 2023 illiberals are more willing to demonstrate (64% vs 57%) and to join a boycott (49% vs 41%).
  • Caution: 26% of Indian adults in 2006 and 10% in 2023 could not be classified (2% in 2012).

4. State support: a separate dimension

The question. Do people want the state to look after those who cannot look after themselves, by taking responsibility for people’s needs, narrowing income gaps, taxing the rich and helping the unemployed? This is kept apart from the conception types in section 3, so that a liberal, a minimalist or an illiberal can each be for or against state support.

What is calculated. Each of the five questions in the table below counts as a “yes” to state support.

A respondent is a state supporter if they say yes to at least 3 of the 5. In 2006 only four were asked, so it is 3 of 4. 2001 had only two, so it cannot be classified. Only people who answered every question asked in their survey are classified.

q_table(tribble(
  ~var, ~question, ~format, ~mapped,
  "econ_govresp", "Government should take more responsibility to ensure that everyone is provided for (1) ... people should take more responsibility to provide for themselves (10)", "10-point scale between the two statements", "1–4 = yes to state support",
  "econ_income", "Incomes should be made more equal (1) ... we need larger income differences as incentives (10)", "10-point scale between the two statements", "1–4 = yes to state support",
  "dess_taxrich", "Essential to democracy: governments tax the rich and subsidise the poor", fmt_ess, "7–10 = yes to state support",
  "dess_unemp", "Essential to democracy: people receive state aid for unemployment", fmt_ess, "7–10 = yes to state support",
  "dess_incomeequal", "Essential to democracy: the state makes people's incomes equal", fmt_ess, "7–10 = yes to state support"),
  caption = "Questions used in this section. State supporter = yes to at least 3")
Questions used in this section. State supporter = yes to at least 3
Question number in the WVS file
Question Response format How it is counted / what it maps to Asked in India W4 W5 W6 W7
Government should take more responsibility to ensure that everyone is provided for (1) … people should take more responsibility to provide for themselves (10) 10-point scale between the two statements 1–4 = yes to state support 2001, 2006, 2012, 2023 V143 V118 V98 Q108
Incomes should be made more equal (1) … we need larger income differences as incentives (10) 10-point scale between the two statements 1–4 = yes to state support 2001, 2006, 2012, 2023 V141 V116 V96 Q106
Essential to democracy: governments tax the rich and subsidise the poor 10-point: 1 not an essential characteristic of democracy … 10 an essential characteristic 7–10 = yes to state support 2006, 2012, 2023 — V152 V131 Q241
Essential to democracy: people receive state aid for unemployment 10-point: 1 not an essential characteristic of democracy … 10 an essential characteristic 7–10 = yes to state support 2006, 2012, 2023 — V155 V134 Q244
Essential to democracy: the state makes people’s incomes equal 10-point: 1 not an essential characteristic of democracy … 10 an essential characteristic 7–10 = yes to state support 2012, 2023 — — V137 Q247
ss_labels <- c(ss_govresp_yes  = "Government should take more responsibility",
               ss_income_yes   = "Incomes should be made more equal",
               ss_taxrich_yes  = "Essential: tax the rich, subsidise the poor",
               ss_unemp_yes    = "Essential: state aid for the unemployed",
               ss_incomeeq_yes = "Essential: state makes incomes equal",
               state_support   = "State supporter (yes to 3 or more)")
tr_ss <- india_trend(as.list(ss_labels))
show_trend(tr_ss, caption = "India: % saying yes to each state-support question [95% CI]")
India: % saying yes to each state-support question [95% CI]
Item 2001 2006 2012 2023
Government should take more responsibility 51.5 [49.1, 53.9]
no answer 18%
48.4 [45.9, 50.8]
no answer 18%
66.7 [65.2, 68.2]
no answer 9%
39.5 [36.8, 42.2]
no answer 2%
Incomes should be made more equal 54.4 [52.0, 56.9]
no answer 19%
48.0 [45.6, 50.4]
no answer 18%
71.1 [69.7, 72.6]
no answer 7%
20.6 [18.4, 22.9]
no answer 3%
Essential: tax the rich, subsidise the poor — 72.7 [70.5, 74.8]
no answer 16%
65.0 [63.5, 66.5]
no answer 2%
69.4 [66.8, 72.1]
no answer 11%
Essential: state aid for the unemployed — 73.5 [71.4, 75.7]
no answer 17%
69.0 [67.6, 70.5]
no answer 2%
66.0 [63.3, 68.7]
no answer 7%
Essential: state makes incomes equal — — 64.3 [62.8, 65.8]
no answer 2%
54.7 [51.8, 57.6]
no answer 12%
State supporter (yes to 3 or more) — 46.3 [43.6, 49.0]
no answer 34%
71.6 [70.1, 73.1]
no answer 13%
52.4 [49.4, 55.5]
no answer 19%
plot_india_lines(tr_ss |> filter(var %in% c("ss_govresp_yes", "ss_income_yes")),
                 title = "India: what the government should do (% yes)", ylab = "% yes")
plot_india_lines(tr_ss |> filter(var %in% c("ss_taxrich_yes", "ss_unemp_yes", "ss_incomeeq_yes")),
                 title = "India: what democracy must guarantee (% yes)", ylab = "% yes")
ss_pan <- imap_dfr(ss_labels, function(lab, v) {
  country_est(v) |>
    group_by(wave, macro_region) |>
    summarise(est = mean(est), k = n(), .groups = "drop") |>
    mutate(item = lab)
}) |>
  mutate(item = factor(item, ss_labels),
         macro_region = factor(macro_region, focus_regions),
         wave_short = factor(sub(" .*", "", wave_labels[wave]), c("W4", "W5", "W6", "W7")))

p <- ggplot(ss_pan, aes(wave_short, est, colour = macro_region, group = macro_region)) +
  geom_line(linewidth = 0.8) +
  geom_point_interactive(aes(fill = macro_region, data_id = paste(item, macro_region, wave),
                             tooltip = sprintf("%s<br>%s, %s: %.0f%%<br>%d %s", item, macro_region,
                                               wave_labels[wave], est, k, ifelse(k == 1, "country", "countries"))),
                         shape = 21, colour = "white", size = 2.6, stroke = 0.7) +
  facet_wrap(~ item, ncol = 3, labeller = label_wrap_gen(32)) +
  scale_colour_manual(values = region_cols, breaks = focus_regions) +
  scale_fill_manual(values = region_cols, guide = "none") +
  scale_y_continuous(limits = c(0, 100), breaks = c(0, 25, 50, 75, 100)) +
  labs(title = "State support, question by question: India vs the two regions",
       x = NULL, y = "% yes",
       caption = paste0("Regions: mean of countries. India: W4 2001, W5 2006, W6 2012, W7 2023.
",
                        "Essentials questions start in W5; state makes incomes equal starts in W6.")) +
  theme_wvs(10) + theme(panel.spacing = unit(1.2, "lines"))
show_plot(p, 11, 6.5)
imap_dfr(ss_labels, function(lab, v) {
  country_est(v) |>
    group_by(wave) |>
    mutate(r = rank(-est, ties.method = "min"), N = n()) |>
    ungroup() |>
    filter(country_code == 356) |>
    transmute(item = lab, wave, cell = sprintf("%.0f%%<br><small>%d of %d</small>", est, r, N))
}) |>
  arrange(wave) |>
  mutate(col = wave_labels[wave]) |>
  select(Question = item, col, cell) |>
  pivot_wider(names_from = col, values_from = cell, values_fill = "—") |>
  arrange(match(Question, ss_labels)) |>
  (\(x) kable(x, escape = FALSE, align = c("l", rep("c", ncol(x) - 1)),
              caption = "India on each state-support question: % yes and rank among all countries shown (1 = most supportive)"))() |>
  styled() |>
  footnote(general = "Countries: India plus every Western European and MENA country surveyed in that wave.",
           general_title = "")
India on each state-support question: % yes and rank among all countries shown (1 = most supportive)
Question W4 (1999–2004) W5 (2004–09) W6 (2010–16) W7 (2017–23)
Government should take more responsibility 52%
7 of 13
48%
9 of 23
67%
4 of 22
39%
16 of 21
Incomes should be made more equal 54%
2 of 12
48%
4 of 23
71%
1 of 22
21%
19 of 21
Essential: tax the rich, subsidise the poor — 73%
3 of 21
65%
6 of 22
69%
5 of 21
Essential: state aid for the unemployed — 74%
11 of 21
69%
11 of 22
66%
11 of 21
Essential: state makes incomes equal — — 64%
4 of 22
55%
7 of 21
State supporter (yes to 3 or more) — 46%
9 of 21
72%
4 of 22
52%
12 of 21
Countries: India plus every Western European and MENA country surveyed in that wave.
region_compare("state_support", caption = "State supporters (%), India and regions")
State supporters (%), India and regions
Region W5 (2004–09) W6 (2010–16) W7 (2017–23)
India 46.3 (1) 71.6 (1) 52.4 (1)
Western Europe & Offshoots 32.1 (14) 42.3 (8) 44.6 (11)
Middle East & North Africa 53.6 (6) 54.3 (13) 58.2 (9)
India’s rank among countries shown (1 = highest) 9 of 21 4 of 22 12 of 21
Cells: mean of country estimates (number of countries).
plot_region_lines("state_support", title = "State supporters: India, Western Europe and MENA",
                  ylab = "% state supporters",
                  caption = "Regions: mean of country estimates. Not classifiable in 2001 (only two questions asked).")
plot_country_dots("state_support", waves = c("W5", "W6", "W7"),
                  title = "State supporters, by country", xlab = "% state supporters")
india_groups("state_support", caption = "India: state supporters (%), by group")
India: state supporters (%), by group
2006 2012 2023
Sex
Male 44.7 (838) 70.5 (2044) 50.4 (651)
Female 48.9 (489) 73.2 (1520) 54.8 (466)
Age
18-34 46.1 (523) 70.3 (1373) 50.1 (457)
35-54 46.3 (581) 71.8 (1534) 53.1 (457)
55+ 46.6 (223) 73.7 (638) 57.5 (203)
Education
Lower 52.2 (529) 74.3 (1610) 55.3 (360)
Middle 46.7 (411) 69.8 (1457) 49.1 (428)
Higher 37.0 (381) 68.2 (493) 53.6 (327)
Party
BJP 41.3 (303) 65.4 (949) 48.2 (434)
INC 50.5 (412) 79.1 (907) 50.5 (207)
Left 46.8 (141) 76.3 (186) n=36
Other party 44.3 (384) 70.5 (1185) 54.3 (190)
Religion
Hindu 44.3 (995) 70.5 (2902) 52.9 (925)
Muslim 56.1 (107) 73.1 (402) 45.7 (105)
Christian n=38 96.5 (57) n=11
Other (Sikh, Buddhist, Jain, …) 55.0 (100) 79.1 (191) 52.8 (74)
Caste
SC — 76.2 (697) 58.4 (223)
ST — 76.8 (228) 58.4 (59)
OBC — 69.7 (1452) 52.3 (474)
General / other — 69.9 (1131) 48.0 (361)
Cells: estimate (unweighted n). Cells with n < 50 are not estimated.
plot_dumbbell("state_support", waves = c("W5", "W6", "W7"),
              title = "India: state supporters by group", xlab = "% state supporters")

Do the two kinds of question go together?

The first two questions ask what the government should do. The other three ask what democracy must guarantee. The table gives the correlation between the number of “yes” answers on each pair (0–2 and 0–3). Regions: mean of country correlations.

ss_cor <- wvs |>
  filter(wave %in% c("W5", "W6", "W7")) |>
  group_by(wave, country_code, macro_region) |>
  filter(sum(!is.na(ss_policy_n) & !is.na(ss_essential_n)) > 100) |>
  summarise(r = cor(ss_policy_n, ss_essential_n, use = "complete.obs"), .groups = "drop")
ss_cor |>
  group_by(wave, macro_region) |>
  summarise(r = mean(r), .groups = "drop") |>
  mutate(macro_region = factor(macro_region, focus_regions), col = wave_labels[wave]) |>
  select(Region = macro_region, col, r) |>
  pivot_wider(names_from = col, values_from = r) |>
  arrange(Region) |>
  kable(digits = 2, caption = "Correlation: 'government should' questions vs 'democracy must' questions") |>
  styled() |>
  footnote(general = "2006 'democracy must' count uses two questions (state makes incomes equal not asked).",
           general_title = "")
Correlation: ‘government should’ questions vs ‘democracy must’ questions
Region W5 (2004–09) W6 (2010–16) W7 (2017–23)
India 0.03 0.24 0.09
Western Europe & Offshoots 0.14 0.27 0.28
Middle East & North Africa 0.11 0.18 0.06
2006 ‘democracy must’ count uses two questions (state makes incomes equal not asked).

State support and the conception of democracy

cross_tab("state_support", "State supporters (%), by conception of democracy")
State supporters (%), by conception of democracy
India 2006 India 2012 India 2023 W. Europe 2023 MENA 2023
Liberal (maximalist) 43.7 (309) 85.6 (1056) 55.1 (293) 48.5 (12333) 65.4 (2746)
Minimalist (electoral) 49.7 (461) 77.6 (1255) 60.6 (441) 47.0 (2656) 69.0 (3961)
Illiberal 38.4 (463) 53.9 (1252) 39.2 (359) 25.6 (2803) 43.5 (4500)
Cells: % (unweighted n). Cells with n < 50 are not estimated.

What this shows.

  • India’s state support rose and then fell back. State supporters (yes to at least 3) were 46% in 2006, 72% in 2012 and 52% in 2023. India went from 4th of 22 countries in 2012 to 12th of 21 in 2023. Western Europe rose steadily (32% → 42% → 45%); MENA stayed near 54–58%.
  • The 2023 fall comes from the “government should” questions. “Government should take more responsibility” fell from 67% to 40%, and “incomes should be made more equal” from 71% to 21% (19th of 21 countries). The “democracy must” questions held up: tax the rich 65% → 69%, unemployment aid 69% → 66%, equal incomes 64% → 55%. The 2023 swing on the two economic scales also appears in the WVS’s own published tables, but is large enough to need checking against other surveys.
  • The two kinds of question are only loosely linked. In India the correlation was 0.03 in 2006, 0.24 in 2012 and 0.09 in 2023; Western Europe 0.14–0.28, MENA 0.06–0.18. Read the category alongside the separate questions.
  • State support goes with a democratic conception, liberal or minimalist. In India in 2023, 55% of liberals and 61% of minimalists were state supporters, against 39% of illiberals (2012: 86%, 78% and 54%). The same holds in Western Europe (49%, 47%, 26%) and MENA (65%, 69%, 44%). Wanting democracy and wanting a supportive state go together; illiberals want less of both.
  • Within India, 2023, support is highest among the marginalised. 58% of SC and ST respondents were state supporters, against 48% of general castes. INC voters’ support fell furthest (79% → 51%), and is now close to BJP voters (48%).

5. Does it differ across Indian states?

The question. Fukuyama stresses that governance varies within countries. Do the patterns above hold across Indian states?

What is calculated. The main measures from sections 1 to 3 by state, for 2001 (18 states), 2012 (17 states) and 2023 (8 states). States with fewer than 150 respondents are marked; treat them as indicative only.

tribble(
  ~Measure, ~`Built from`, ~Section,
  "Trust in the state / in checking institutions, and the gap", "8 confidence questions", "1",
  "Strong leader good; experts good", "Two ways-of-governing questions (1–2 = good)", "3",
  "Want both (governance and accountability)", "Yes on at least half of the delivery and of the accountability questions", "2") |>
  kable(caption = "Measures used in this section (questions as listed in each section)") |>
  styled()
Measures used in this section (questions as listed in each section)
Measure Built from Section
Trust in the state / in checking institutions, and the gap 8 confidence questions 1
Strong leader good; experts good Two ways-of-governing questions (1–2 = good) 3
Want both (governance and accountability) Yes on at least half of the delivery and of the accountability questions 2
state_tab <- function(w) {
  india |>
    filter(wave == w, !is.na(in_state)) |>
    group_by(State = in_state) |>
    summarise(n = n(),
              `Trust in state %`    = 100 * weighted.mean(state_trust, weight, na.rm = TRUE),
              `Trust in checking %` = 100 * weighted.mean(check_trust, weight, na.rm = TRUE),
              `Gap (pts)`           = `Trust in state %` - `Trust in checking %`,
              `Strong leader good %`= 100 * weighted.mean(reg_strongleader_good, weight, na.rm = TRUE),
              `Experts good %`      = 100 * weighted.mean(reg_experts_good, weight, na.rm = TRUE),
              `Want both %`         = 100 * weighted.mean(g_both, weight, na.rm = TRUE),
              .groups = "drop") |>
    arrange(desc(`Gap (pts)`))
}
for (w in c("W4", "W6", "W7")) {
  tb <- state_tab(w)
  print(tb |>
          kable(digits = 1, caption = paste0("India ", india_years[w], ": measures by state (sorted by trust gap)")) |>
          styled() |>
          row_spec(which(tb$n < 150), color = "grey"))
  cat("

")
}
India 2001: measures by state (sorted by trust gap)
State n Trust in state % Trust in checking % Gap (pts) Strong leader good % Experts good % Want both %
Chhattisgarh 46 61.1 42.9 18.3 100.0 70.0 42.9
Madhya Pradesh 115 56.2 40.7 15.6 86.4 72.9 61.8
Kerala 71 63.0 47.5 15.5 16.9 21.8 65.0
Karnataka 112 57.3 41.8 15.5 100.0 98.4 24.4
Tamil Nadu 129 87.8 73.7 14.1 48.7 71.3 46.9
Jharkhand 65 56.9 43.8 13.2 95.2 95.0 37.0
Delhi 43 45.0 33.3 11.7 69.2 91.9 25.7
Odisha 68 63.7 52.6 11.1 6.2 72.4 51.3
Assam 61 29.5 21.8 7.7 50.0 47.7 27.3
Rajasthan 102 76.9 70.0 7.0 92.6 96.2 34.7
Andhra Pradesh 152 57.5 50.8 6.7 37.1 45.0 48.3
Uttar Pradesh 328 58.0 55.1 2.9 76.9 61.6 49.5
Maharashtra 194 60.6 57.8 2.8 62.7 70.5 41.5
Haryana 50 40.4 38.5 1.9 100.0 100.0 41.2
West Bengal 174 59.2 57.6 1.6 29.3 64.1 12.7
Gujarat 96 58.7 58.6 0.1 17.9 69.1 40.4
Bihar 147 42.5 48.7 -6.1 64.9 75.6 62.6
Punjab 49 59.5 75.7 -16.2 62.5 36.2 81.2
India 2012: measures by state (sorted by trust gap)
State n Trust in state % Trust in checking % Gap (pts) Strong leader good % Experts good % Want both %
Unlabelled (W6 code 356019) 64 52.0 29.9 22.1 93.5 96.8 33.3
Rajasthan 278 63.5 50.6 12.9 92.9 86.7 33.5
Punjab 151 59.7 47.1 12.6 79.8 73.0 16.4
Gujarat 259 60.1 49.9 10.3 79.8 52.2 49.2
Bihar 332 58.0 48.2 9.8 76.0 71.0 14.5
Madhya Pradesh 256 55.9 48.0 7.9 88.5 81.6 19.2
Chhattisgarh 99 66.2 58.4 7.7 98.3 93.0 46.7
Odisha 355 73.5 66.1 7.3 24.0 97.0 75.5
Karnataka 239 60.6 55.2 5.4 42.9 48.3 53.2
Uttar Pradesh 596 59.8 54.5 5.3 93.6 90.3 27.8
Maharashtra 280 73.4 68.2 5.2 53.2 56.1 28.7
Andhra Pradesh 307 68.3 69.1 -0.8 39.3 47.6 34.9
Haryana 122 71.4 72.5 -1.2 91.1 69.9 15.8
West Bengal 294 54.5 58.8 -4.3 25.8 62.0 5.0
Kerala 192 78.5 82.9 -4.4 7.9 36.6 50.8
Delhi 94 41.8 49.1 -7.3 75.0 64.2 28.3
Jharkhand 160 44.2 59.4 -15.2 96.6 83.8 72.3
India 2023: measures by state (sorted by trust gap)
State n Trust in state % Trust in checking % Gap (pts) Strong leader good % Experts good % Want both %
Telangana 170 71.4 52.2 19.1 64.8 75.5 28.0
Delhi 187 83.9 70.0 13.9 88.2 76.8 33.1
Bihar 198 77.4 64.7 12.7 74.2 58.4 39.5
Haryana 95 74.0 61.7 12.3 76.6 67.6 31.9
Punjab 100 44.5 35.0 9.5 31.8 81.8 46.3
Uttar Pradesh 292 78.1 70.6 7.4 94.3 80.8 37.0
West Bengal 169 74.7 67.7 7.0 27.2 60.2 20.8
Maharashtra 160 76.8 70.9 5.8 71.0 82.0 28.2
p <- india |>
  filter(wave %in% c("W4", "W6", "W7"), !is.na(in_state), !grepl("Unlabelled", in_state)) |>
  group_by(wave, in_state) |>
  summarise(n = n(), state_trust = 100 * weighted.mean(state_trust, weight, na.rm = TRUE),
            strongleader = 100 * weighted.mean(reg_strongleader_good, weight, na.rm = TRUE), .groups = "drop") |>
  filter(n >= 80) |>
  mutate(year = factor(india_years[wave], india_years)) |>
  ggplot(aes(state_trust, strongleader)) +
  geom_point_interactive(aes(data_id = paste(in_state, year),
                             tooltip = sprintf("%s, %s<br>Trust in state: %.0f%%<br>Strong leader good: %.0f%%<br>n = %d",
                                               in_state, year, state_trust, strongleader, n)),
                         shape = 21, fill = region_cols["India"], colour = "white", size = 3.4, stroke = 0.8) +
  geom_text_repel(aes(label = in_state), size = 2.7, colour = ink2, max.overlaps = 30, seed = 3) +
  facet_wrap(~ year, nrow = 1) +
  scale_x_continuous(breaks = c(40, 60, 80)) +
  labs(title = "Indian states: trust in the state vs support for a strong leader",
       x = "Trust in the state (%)", y = "Strong leader is good (%)",
       caption = "States with at least 80 respondents.") +
  theme_wvs(10) + theme(panel.spacing.x = unit(1.5, "lines"))
show_plot(p, 11, 5)

What this shows.

  • States differ enormously, more than India differs from the two regions. In 2012 support for a strong leader ranges from 8% in Kerala and 24–26% in Odisha and West Bengal to over 90% in Uttar Pradesh, Rajasthan, Jharkhand, Chhattisgarh and Haryana.
  • National India figures therefore depend heavily on which states are sampled. This is a further reason to read the 8-state 2023 sample with care.
  • The state labelled “Unlabelled (W6 code 356019)” has no name in the codebook and only 64 respondents; ignore it.

Robustness: the seven states surveyed in every wave

head_items <- c(state_trust = "Trust in the state", check_trust = "Trust in checking institutions",
                trust_gap = "Trust gap (pts)", g_both = "Want both", g_govfirst = "Governance-first")
bind_rows(
  india_trend(head_items) |> mutate(sample = "All states"),
  india_trend(head_items, data = filter(india, in_state %in% common_states)) |> mutate(sample = "Seven common states")
) |>
  mutate(cell = ifelse(is.na(est), "—", sprintf("%.1f", est * 100)), year = india_years[wave]) |>
  select(Item = item, Sample = sample, year, cell) |>
  pivot_wider(names_from = year, values_from = cell) |>
  arrange(match(Item, head_items)) |>
  kable(caption = "India: key measures, all states vs Bihar, Delhi, Haryana, Maharashtra, Punjab, UP, West Bengal",
        align = c("l", "l", rep("c", 5))) |>
  styled() |>
  collapse_rows(columns = 1, valign = "top")
India: key measures, all states vs Bihar, Delhi, Haryana, Maharashtra, Punjab, UP, West Bengal
Item Sample 2001 2006 2012 2023
Trust in the state All states 59.1 64.7 62.5 74.7
Seven common states 55.4 65.0 60.6 75.2
Trust in checking institutions All states 53.8 63.8 57.9 63.8
Seven common states 54.8 61.6 56.3 65.5
Trust gap (pts) All states 4.7 0.7 4.2 10.7
Seven common states 0.7 3.4 3.8 9.6
Want both All states 43.0 43.7 35.0 32.7
Seven common states 42.5 39.3 19.1 33.4
Governance-first All states 47.3 44.7 53.4 44.0
Seven common states 51.5 52.0 69.3 44.8