library(tidyverse)
library(haven)
library(labelled)
library(survey)
library(forcats)
library(openxlsx)
library(Hmisc)
library(ggplot2)
library(kableExtra)
library(dplyr)
library(tidyr)
library(stringr)
library(knitr)
library(cregg)
library(scales)
library(readxl)

WVS_India <- read_excel("D:/Populism and Democrary/World value survey/WVS India.xlsx")
View(WVS_India)

Deatils

18 of 28 states covered, accounting for 97% of population

Sampling- four‑stage multistage stratified random design

40 Lok Sabha constituencies allocated by state population.

2 assembly constituencies per LS seat (80 ACs).

2 polling stations per AC (=160 PS clusters).

20–25 names drawn per PS from electoral rolls using circular Probability Proportion to Size (PPS) sampling, with ~20% over‑sample to allow substitution within same family and gender.

N=2001, national adult population 18+, both sexes.

Demographics

gender_india_table <- WVS_India %>%
  mutate(gender = case_when(
    `V235: Sex` == 1 ~ "Male",
    `V235: Sex` == 2 ~ "Female",
    TRUE ~ "Missing"
  )) %>%
  count(gender) %>%
  mutate(pct = round(100 * n / sum(n), 1))

print(gender_india_table)
## # A tibble: 3 × 3
##   gender      n   pct
##   <chr>   <int> <dbl>
## 1 Female    861  43  
## 2 Male     1137  56.8
## 3 Missing     3   0.1
# EDUCATION RECODING 

education_table <- WVS_India %>%
  mutate(education = case_when(
    `V238R: Highest educational level: Respondent (recoded into 3 groups)` == 1 ~ "Low (No/Primary)",
    `V238R: Highest educational level: Respondent (recoded into 3 groups)` == 2 ~ "Medium (Secondary)",
    `V238R: Highest educational level: Respondent (recoded into 3 groups)` == 3 ~ "High (Tertiary)",
    TRUE ~ "Missing"
  )) %>%
  filter(!is.na(`V238R: Highest educational level: Respondent (recoded into 3 groups)`)) %>%
  count(education, sort = TRUE) %>%
  mutate(pct = round(100 * n / sum(n), 1))

print(education_table)
## # A tibble: 4 × 3
##   education              n   pct
##   <chr>              <int> <dbl>
## 1 Low (No/Primary)     999  49.9
## 2 Medium (Secondary)   547  27.3
## 3 High (Tertiary)      436  21.8
## 4 Missing               19   0.9
#Religion 
religion_table <- WVS_India %>%
  mutate(religion_3cat = case_when(
    `V185G: Religious denomination -Main group` == 6 ~ "Hindu",    
    `V185G: Religious denomination -Main group` == 5 ~ "Muslim",   
    TRUE ~ "Others"   # Sikh, Christian, No answer, Buddhist etc
  )) %>%
  filter(!is.na(`V185G: Religious denomination -Main group`)) %>%
  count(religion_3cat, sort = TRUE) %>%
  mutate(pct = round(100 * n / sum(n), 1))

print(religion_table)
## # A tibble: 3 × 3
##   religion_3cat     n   pct
##   <chr>         <int> <dbl>
## 1 Hindu          1513  75.6
## 2 Others          326  16.3
## 3 Muslim          162   8.1

political categories

Now we will try to categories respondents based on the following questions V231: Which party would you vote: first choice V233: Party that would never vote We will make two categories - vote for BJP/vote for INC, Never vote for BJP/Never vote for INC

WVS_India <- WVS_India %>%
  mutate(
    vote_choice = case_when(
      `V231: Which party would you vote: first choice` == 356068 ~ "Vote BJP",
      `V231: Which party would you vote: first choice` == 356067 ~ "Vote INC",
      !is.na(`V231: Which party would you vote: first choice`) ~ "Vote Other",
      TRUE ~ NA_character_
    ),
    
    party_reject = case_when(
      `V233: Party that would never vote` == 356068 ~ "Never BJP",
      `V233: Party that would never vote` == 356067 ~ "Never INC",
      !is.na(`V233: Party that would never vote`) ~ "Reject Other",
      TRUE ~ NA_character_
    )
  )

table(WVS_India$vote_choice, WVS_India$party_reject, useNA = "ifany")
##             
##              Never BJP Never INC Reject Other
##   Vote BJP           5        57          361
##   Vote INC         111        11          515
##   Vote Other       115        89          737

left/right

party_v114_vote <- WVS_India %>%
  filter(vote_choice %in% c("Vote BJP", "Vote INC", "Vote Other")) %>%
  filter(`V114: Self positioning in political scale` %in% 1:10) %>%
  group_by(vote_choice) %>%
  summarise(
    leftright_mean = round(mean(`V114: Self positioning in political scale`, na.rm = TRUE), 2),
    n_valid = n(),
    .groups = "drop"
  )

print(party_v114_vote)
## # A tibble: 3 × 3
##   vote_choice leftright_mean n_valid
##   <chr>                <dbl>   <int>
## 1 Vote BJP              5.39     233
## 2 Vote INC              4.46     295
## 3 Vote Other            3.85     456
party_v114_vote %>%
  ggplot(aes(x = reorder(vote_choice, leftright_mean),
             y = leftright_mean,
             fill = vote_choice)) +
  geom_col(alpha = 0.8) +
  geom_text(aes(label = paste0(leftright_mean, " (n=", n_valid, ")")),
            hjust = -0.1, size = 3.5) +
  coord_flip() +
  scale_fill_brewer(type = "qual", palette = "Set2") +
  theme_minimal(base_size = 12) +
  labs(title = "Left–Right Self-Placement by Vote Choice",
       subtitle = "V114: 1 = Left, 10 = Right",
       x = "Vote Choice", y = "Mean Score",
       caption = "Valid responses only") +
  theme(legend.position = "none")

party_v114_reject <- WVS_India %>%
  filter(party_reject %in% c("Never BJP", "Never INC")) %>%
  filter(`V114: Self positioning in political scale` %in% 1:10) %>%
  group_by(party_reject) %>%
  summarise(
    leftright_mean = round(mean(`V114: Self positioning in political scale`, na.rm = TRUE), 2),
    n_valid = n(),
    .groups = "drop"
  )

print(party_v114_reject)
## # A tibble: 2 × 3
##   party_reject leftright_mean n_valid
##   <chr>                 <dbl>   <int>
## 1 Never BJP              4.63     114
## 2 Never INC              5.56      88
party_v114_reject %>%
  ggplot(aes(x = reorder(party_reject, leftright_mean),
             y = leftright_mean,
             fill = party_reject)) +
  geom_col(alpha = 0.8) +
  geom_text(aes(label = paste0(leftright_mean, " (n=", n_valid, ")")),
            hjust = -0.1, size = 3.5) +
  coord_flip() +
  scale_fill_brewer(type = "qual", palette = "Set1") +
  theme_minimal(base_size = 12) +
  labs(title = "Left–Right Self-Placement by Party Rejection",
       subtitle = "V114: 1 = Left, 10 = Right",
       x = "Party Rejected", y = "Mean Score",
       caption = "Valid responses only") +
  theme(legend.position = "none")

Democratic profile

WVS_India <- WVS_India %>%
  rename(
    V157 = matches("^V157")
  )
democracy_long <- WVS_India %>%
  select(
    vote_choice,
    party_reject,
    V152 = `V152: Democracy: Governments tax the rich and subsidize the poor.`,
    V153 = `V153: Democracy: Religious authorities interpret the laws.`,
    V154 = `V154: Democracy: People choose their leaders in free elections.`,
    V155 = `V155: Democracy: People receive state aid for unemployment.`,
    V156 = `V156: Democracy: The army takes over when government is incompetent.`,
    V157,
    V158 = `V158: Democracy: The economy is prospering.`,
    V159 = `V159: Democracy: Criminals are severely punished.`,
    V160 = `V160: Democracy: People can change the laws in referendums.`,
    V161 = `V161: Democracy: Women have the same rights as men.`
  ) %>%
  pivot_longer(
    V152:V161,
    names_to = "item",
    values_to = "score"
  ) %>%
  filter(score %in% 1:10)

democracy_long <- democracy_long %>%
  mutate(
    item_label = recode(item,
      "V152" = "Tax rich, subsidize poor",
      "V153" = "Religious authorities interpret laws",
      "V154" = "Free elections",
      "V155" = "Unemployment aid",
      "V156" = "Army rule if govt incompetent",
      "V157" = "Civil rights protect liberty",
      "V158" = "Economy prospering",
      "V159" = "Criminals severely punished",
      "V160" = "Referendums change laws",
      "V161" = "Women equal rights"
    )
  )
democracy_vote_profile <- democracy_long %>%
  filter(vote_choice %in% c("Vote BJP", "Vote INC")) %>%
  group_by(vote_choice, item_label) %>%
  summarise(mean_score = mean(score, na.rm = TRUE), .groups = "drop")

ggplot(democracy_vote_profile,
       aes(x = reorder(item_label, mean_score),
           y = mean_score,
           fill = vote_choice)) +
  geom_col(position = "dodge", alpha = 0.8) +
  coord_flip() +
  theme_minimal() +
  labs(title = "Democracy Profile by Party Acceptance",
       subtitle = "Mean importance scores across all democracy items",
       x = "", y = "Mean score") +
  theme(legend.title = element_blank())

democracy_reject_profile <- democracy_long %>%
  filter(party_reject %in% c("Never BJP", "Never INC")) %>%
  group_by(party_reject, item_label) %>%
  summarise(mean_score = mean(score, na.rm = TRUE), .groups = "drop")
ggplot(democracy_reject_profile,
       aes(x = reorder(item_label, mean_score),
           y = mean_score,
           fill = party_reject)) +
  geom_col(position = "dodge", alpha = 0.8) +
  coord_flip() +
  theme_minimal() +
  labs(title = "Democracy Profile by Party Rejection",
       subtitle = "Mean importance scores across all democracy items",
       x = "", y = "Mean score") +
  theme(legend.title = element_blank())

Well the most interesting thing is those who are never gonna vote for BJP has the highest means for Religious authorities interpret the laws as an essential characteristics of democracy.

Actually the most interesting lot is “never bjp” the behavior is very contradictory to normal assumptions

religion_by_rejection <- WVS_India %>%
  mutate(
    religion_3cat = case_when(
      `V185G: Religious denomination -Main group` == 6 ~ "Hindu",
      `V185G: Religious denomination -Main group` == 5 ~ "Muslim",
      TRUE ~ "Others"
    )
  ) %>%
  filter(
    party_reject %in% c("Never BJP", "Never INC"),
    !is.na(`V185G: Religious denomination -Main group`)
  ) %>%
  count(party_reject, religion_3cat) %>%
  group_by(party_reject) %>%
  mutate(pct = round(100 * n / sum(n), 1)) %>%
  ungroup()

print(religion_by_rejection)
## # A tibble: 6 × 4
##   party_reject religion_3cat     n   pct
##   <chr>        <chr>         <int> <dbl>
## 1 Never BJP    Hindu           150  64.9
## 2 Never BJP    Muslim           47  20.3
## 3 Never BJP    Others           34  14.7
## 4 Never INC    Hindu           110  70.1
## 5 Never INC    Muslim           12   7.6
## 6 Never INC    Others           35  22.3
religion_by_vote <- WVS_India %>%
  mutate(
    religion_3cat = case_when(
      `V185G: Religious denomination -Main group` == 6 ~ "Hindu",
      `V185G: Religious denomination -Main group` == 5 ~ "Muslim",
      TRUE ~ "Others"
    )
  ) %>%
  filter(
    vote_choice %in% c("Vote BJP", "Vote INC"),
    !is.na(`V185G: Religious denomination -Main group`)
  ) %>%
  count(vote_choice, religion_3cat) %>%
  group_by(vote_choice) %>%
  mutate(pct = round(100 * n / sum(n), 1)) %>%
  ungroup()
print(religion_by_vote)
## # A tibble: 6 × 4
##   vote_choice religion_3cat     n   pct
##   <chr>       <chr>         <int> <dbl>
## 1 Vote BJP    Hindu           389  92  
## 2 Vote BJP    Muslim            2   0.5
## 3 Vote BJP    Others           32   7.6
## 4 Vote INC    Hindu           463  72.7
## 5 Vote INC    Muslim           62   9.7
## 6 Vote INC    Others          112  17.6

up next profile based on social class (subjective)

WVS_India <- WVS_India %>%
  mutate(
    class_3cat = case_when(
      `V252: Social class (subjective)` %in% c(1, 2) ~ "Upper class",
      `V252: Social class (subjective)` %in% c(3, 4) ~ "Middle/working class",
      `V252: Social class (subjective)` == 5 ~ "Lower class",
      TRUE ~ "Others"
    )
  )
class_distribution <- WVS_India %>%
  count(class_3cat) %>%
  mutate(pct = round(100 * n / sum(n), 1))

print (class_distribution)
## # A tibble: 4 × 3
##   class_3cat               n   pct
##   <chr>                <int> <dbl>
## 1 Lower class            530  26.5
## 2 Middle/working class  1026  51.3
## 3 Others                  54   2.7
## 4 Upper class            391  19.5
science_class_profile <- WVS_India %>%
  select(
    class_3cat,
    V91 = `V91: Science and technology are making our lives healthier, easier, and more comfortable`,
    V92 = `V92: Because of science and technology, there will be more opportunities for the next generation`,
    V93 = `V93: Science and technology make our way of life change too fast`,
    V94 = `V94: We depend too much on science and not enough on faith`
  ) %>%
  filter(class_3cat != "Others") %>%
  filter(if_all(V91:V94, ~ .x %in% 1:10)) %>%
  group_by(class_3cat) %>%
  summarise(
    across(V91:V94, ~ round(mean(.x), 2)),
    N = n(),
    .groups = "drop"
  )


science_class_profile %>%
  rename(
    `Science improves life` = V91,
    `Science creates future opportunities` = V92,
    `Science changes life too fast` = V93,
    `Too much science, not enough faith` = V94,

  ) %>%
  kable(
    digits = 2,
    caption = "Attitudes toward Science, Technology, and Faith by Subjective Social Class"
  ) %>%
  kable_styling(
    bootstrap_options = c("striped", "hover", "condensed"),
    full_width = FALSE
  )
Attitudes toward Science, Technology, and Faith by Subjective Social Class
class_3cat Science improves life Science creates future opportunities Science changes life too fast Too much science, not enough faith N
Lower class 7.45 7.42 7.60 6.38 291
Middle/working class 7.92 8.02 8.06 6.78 766
Upper class 8.37 8.34 8.70 7.38 320
WVS_India <- WVS_India %>%
  rename(
    V116 = `V116: Income equality`,
    V117 = `V117: Private vs state ownership of business`,
    V118 = `V118: Government responsibility`,
    V119 = `V119: Competition good or harmful`,
    V120 = `V120: Hard work brings success`,
    V121 = `V121: Wealth accumulation`
  )

econ_values_class_profile <- WVS_India %>%
  select(class_3cat, V116:V121) %>%
  filter(class_3cat != "Others") %>%
  filter(if_all(V116:V121, ~ .x %in% 1:10)) %>%
  group_by(class_3cat) %>%
  summarise(
    across(V116:V121, ~ round(mean(.x), 2)),
    n = n(),
    .groups = "drop"
  )

print (econ_values_class_profile)
## # A tibble: 3 × 8
##   class_3cat            V116  V117  V118  V119  V120  V121     n
##   <chr>                <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <int>
## 1 Lower class           5.25  6.35  4.82  2.7   3.62  5.15   201
## 2 Middle/working class  4.96  5.73  4.59  2.44  3.58  5.81   616
## 3 Upper class           5.66  5.69  5.12  2.21  2.69  5.07   258
econ_values_long <- econ_values_class_profile %>%
  pivot_longer(
    V116:V121,
    names_to = "item",
    values_to = "mean_score"
  ) %>%
  mutate(
    item = recode(item,
      "V116" = "Income equality vs inequality incentives",
      "V117" = "Private vs state ownership",
      "V118" = "Govt vs individual responsibility",
      "V119" = "Competition good vs harmful",
      "V120" = "Hard work vs luck",
      "V121" = "Zero-sum wealth vs Larger the pie"
    )
  )
ggplot(
  econ_values_long,
  aes(x = item, y = mean_score, fill = class_3cat)
) +
  geom_col(position = position_dodge(width = 0.8), width = 0.7) +
  geom_text(
    aes(label = round(mean_score, 2)),
    position = position_dodge(width = 0.8),
    vjust = -0.4,
    size = 3
  ) +
  coord_flip() +
  theme_minimal(base_size = 12) +
  labs(
    title = "Economic value by subjective social class",
    subtitle = "Mean position on 1–10 scales",
    x = "",
    y = "Mean score",
    fill = "Social class"
  )