Diverging Bar Chart using ggplot2

Aditi Hurkat, Sagar Tripathi

Problem Statement

Develop a script in R to plot a diverging bar chart to show positive and negative sentiment in public opinion survey data.

Objective

  • Understand sentiment distribution
  • Convert data for visualization
  • Create a diverging bar chart using ggplot2

Load Required Libraries

library(ggplot2)
library(dplyr)
library(tidyr)

Load Dataset

              States Opinion.of.Children...Quality.of.Meal..in.percent....Good
1    Andhra Pradesh                                                      88.41
2 Arunachal Pradesh                                                      99.37
3              Bihar                                                      5.64
4           Haryana                                                      55.00
5  Himachal Pradesh                                                      90.00
6    Jammu & Kashmir                                                     97.00
  Opinion.of.Children...Quality.of.Meal..in.percent....Average
1                                                         9.92
2                                                         0.63
3                                                        22.06
4                                                        44.50
5                                                         9.55
6                                                         3.00
  Opinion.of.Children...Quality.of.Meal..in.percent....Poor
1                                                      1.68
2                                                      0.00
3                                                     72.30
4                                                      0.50
5                                                      0.45
6                                                        NA
  Opinion.of.Children...Satisfaction..in.percent....Yes
1                                                 93.85
2                                                100.00
3                                                 22.11
4                                                 99.50
5                                                 99.54
6                                                 98.00
  Opinion.of.Children...Satisfaction..in.percent....No
1                                                 6.15
2                                                   NA
3                                                77.89
4                                                 0.50
5                                                 0.46
6                                                 2.00

Exploratory Data Analysis

'data.frame':   17 obs. of  6 variables:
 $ States                                                      : chr  "Andhra Pradesh " "Arunachal Pradesh " "Bihar" "Haryana " ...
 $ Opinion.of.Children...Quality.of.Meal..in.percent....Good   : num  88.41 99.37 5.64 55 90 ...
 $ Opinion.of.Children...Quality.of.Meal..in.percent....Average: num  9.92 0.63 22.06 44.5 9.55 ...
 $ Opinion.of.Children...Quality.of.Meal..in.percent....Poor   : num  1.68 0 72.3 0.5 0.45 ...
 $ Opinion.of.Children...Satisfaction..in.percent....Yes       : num  93.8 100 22.1 99.5 99.5 ...
 $ Opinion.of.Children...Satisfaction..in.percent....No        : num  6.15 NA 77.89 0.5 0.46 ...
    States          Opinion.of.Children...Quality.of.Meal..in.percent....Good
 Length:17          Min.   :  4.61                                           
 Class :character   1st Qu.: 55.85                                           
 Mode  :character   Median : 80.21                                           
                    Mean   : 70.45                                           
                    3rd Qu.: 90.00                                           
                    Max.   :100.00                                           
                                                                             
 Opinion.of.Children...Quality.of.Meal..in.percent....Average
 Min.   : 0.00                                               
 1st Qu.: 7.29                                               
 Median :16.00                                               
 Mean   :22.03                                               
 3rd Qu.:22.06                                               
 Max.   :89.72                                               
                                                             
 Opinion.of.Children...Quality.of.Meal..in.percent....Poor
 Min.   : 0.000                                           
 1st Qu.: 0.545                                           
 Median : 1.525                                           
 Mean   : 7.989                                           
 3rd Qu.: 7.112                                           
 Max.   :72.300                                           
 NA's   :1                                                
 Opinion.of.Children...Satisfaction..in.percent....Yes
 Min.   : 22.11                                       
 1st Qu.: 78.39                                       
 Median : 93.85                                       
 Mean   : 86.56                                       
 3rd Qu.: 98.73                                       
 Max.   :100.00                                       
                                                      
 Opinion.of.Children...Satisfaction..in.percent....No
 Min.   : 0.000                                      
 1st Qu.: 1.817                                      
 Median : 6.920                                      
 Mean   :14.283                                      
 3rd Qu.:21.872                                      
 Max.   :77.890                                      
 NA's   :1                                           

Transform Data

data_long <- data %>%
  pivot_longer(
    cols = c(
      Opinion.of.Children...Satisfaction..in.percent....Yes,
      Opinion.of.Children...Satisfaction..in.percent....No
    ),
    names_to = "Sentiment",
    values_to = "Percentage"
  )

# Convert "No" values to negative
data_long$Percentage <- ifelse(
  data_long$Sentiment == "Opinion.of.Children...Satisfaction..in.percent....No",
  -data_long$Percentage,
  data_long$Percentage
)

# Remove missing values
data_long <- na.omit(data_long)

Check Transformed Data

# A tibble: 6 × 6
  States    Opinion.of.Children.…¹ Opinion.of.Children.…² Opinion.of.Children.…³
  <chr>                      <dbl>                  <dbl>                  <dbl>
1 "Andhra …                  88.4                    9.92                   1.68
2 "Andhra …                  88.4                    9.92                   1.68
3 "Arunach…                  99.4                    0.63                   0   
4 "Bihar"                     5.64                  22.1                   72.3 
5 "Bihar"                     5.64                  22.1                   72.3 
6 "Haryana…                  55                     44.5                    0.5 
# ℹ abbreviated names:
#   ¹​Opinion.of.Children...Quality.of.Meal..in.percent....Good,
#   ²​Opinion.of.Children...Quality.of.Meal..in.percent....Average,
#   ³​Opinion.of.Children...Quality.of.Meal..in.percent....Poor
# ℹ 2 more variables: Sentiment <chr>, Percentage <dbl>

Diverging Bar Chart

Interpretation

  • Positive values represent favorable opinions
  • Negative values represent unfavorable opinions
  • Easy comparison across states

Conclusion

  • Diverging bar charts clearly show sentiment balance
  • Useful for surveys and decision making
  • ggplot2 simplifies data visualization

Thank You

Thank you for your attention!