Comparing intraclass correlations for Schwarz values across European countries

ICC for the First Graph =













ICC for the Second Graph =
Contents

1. This app
2. The data
3. ICC
4. Schwartz's model
5. How to use this app

Information about this app
The purpose of this app is to provide an interactive and educational way of understanding the intraclass correlation coefficient (ICC).

Information about the data
The data our app uses is takens from The European Social Survey (ESS), a cross-national survey carried out by The European Science Foundation. The ESS measures attitudes, beliefs, and behavior patterns of a diverse European population.
Our app uses the round seven ESS dataset. we sampled 100 responses each from 13 countries, with two additional fictional countries added for educational purposes. One fictional country we added extremely high on the values while the other one is extremely low. For each country we have data for their scores on the 10 Schwarz values.

Intraclass correlation coefficient (ICC)
The intraclass correlation coefficient describes tells us the proportion of the total variance that is between groups rather than within groups. An ICC of close to 0 indicates that most of the variance in the data is within countries, but a ICC closer to 1 indicates that most of the variance is between countries. It's a similar concept to the F ratio used in an ANOVA. For example, the ICC can be used to quantify the degree to which siblings resemble each other for a given trait. It is also sometimes used as a inter-rater reliability test in order to assess the consistency of different raters.

Schwartz's model of universal human values
The Theory of Basic Human Values measures universal values that are recognised throughout all cultures. Schwartz's theory identifies 10 motivationally distinct values and describes the relationships between them.

This dataset consists of the composite scores for each participant for 2 or 3 items which represent the aforementioned values. Participants read sentences describing values of a fictional individual and mark to which level (1 = not at all like me to 6 = very much like me) they consider themselves similar to the fictional person's life values. In the following table, value names and descriptions are provided.

How to use this app
Use the drop-down boxes to select any 2 measures to compare. You can choose from the 10 Schwarz values. Once you have selected a measure, the app will generate some a boxplot for each country that has been ticked, along with their ICC values. Notice how the data for each measure differs, and how it affects the ICC for that measure. Which variables vary most between countries, and which vary mostly within country? Does changing the number of countries affect the ICC value?

The glorious app designers. Left to right: Richie, Sandra, Lea, Mirela, Nadine, Massimiliano.

Sandra Garcia Garcia, Compultense University of Madrid
Lea Jakob, University of Zagreb
Nadine Koch, University of Tubingen
Thomas Richardson, University of Glasgow
Mirela Zaneva, University of Amsterdam
Massimiliano Zuccarini, University of Padua

show with app

#Sandra Garcia Garcia, Compultense University of Madrid
#Lea Jakob, University of Zagreb
#Nadine Koch, University of Tubingen
#Thomas Richardson, University of Glasgow
#Mirela Zaneva, University of Amsterdam
#Massimiliano Zuccarini, University of Padua





library(tidyr)
library(lme4)
library(dplyr)
library(ggplot2)
library(shiny)

#================= Prepare the Data =============================================
dat <- read.csv("ESS7e02.csv", header = T, sep = ";", 
                na.strings = c("789","7","8","9"))
name <- names(dat)
dat2 <- na.omit(dat)
dat2$cntry <- as.character(dat2$cntry)

#str(dat)
# aggregate(. ~ cntry, dat2, FUN = mean)
n_country <- 100

fiction_lo <- as.data.frame(
    matrix(sample(c(1,2), 21*n_country, replace=T),nrow = n_country)
)

fiction_low <- cbind(1:n_country, rep("FL",100), fiction_lo)
fiction_lo2 = fiction_low
fiction_lo2[,8] = rep(c(1,2,3,4), 25)
fiction_lo2[,20] = rep(c(1,1.5), 50)

names(fiction_low) <- names(dat2)
names(fiction_lo2) <- names(dat2)
datt <- rbind(dat2,fiction_lo2)

fiction_hi <- as.data.frame(
    matrix(sample(c(5,6), 21*n_country, replace=T), nrow = n_country))
fiction_high <- cbind(1:n_country, rep("FH",100), fiction_hi)
fiction_hi2 = fiction_high
fiction_hi2[,20] = rep(c(5.5,6), 25)
names(fiction_hi2) <- names(dat2)
dat2_c <- rbind(datt,fiction_hi2)

dat3 <- data.frame(
    country = dat2_c$cntry,
    self_direction = (dat2_c$ipcrtiv + dat2_c$impfree)/2, 
    power = (dat2_c$imprich + dat2_c$iprspot)/2,
    universalism = (dat2_c$ipeqopt + dat2_c$impenv + dat2_c$ipudrst)/3,
    stimulation = (dat2_c$ipadvnt + dat2_c$impdiff)/2,
    hedonism = (dat2_c$impfun + dat2_c$ipgdtim)/2,
    security = (dat2_c$impsafe + dat2_c$ipstrgv)/2,
    achievement = (dat2_c$ipshabt + dat2_c$ipsuces)/2,
    conformity = (dat2_c$ipbhprp + dat2_c$ipfrule)/2,
    tradition = (dat2_c$imptrad + dat2_c$ipmodst)/2,
    benevolence = (dat2_c$iplylfr + dat2_c$iphlppl)/2
)

dat3 <- dat3[!dat3$country == "BE",]
dat3 <- dat3[!dat3$country == "NO",]
dat3 = droplevels(dat3)

dat4 = group_by(dat3, country)
dat5 = sample_n(dat4, 100)
data.new = dat5

#============== Calculate the ICC ===============================================

Give_me_the_ICC = function(column_name, your_data) {
    # A function to calculate the ICC for any variable
    Model = lmer(formula = paste0(column_name, '~ (1|country)'), data= your_data)
    
    summary(Model)
    
    vc = VarCorr(Model)
    Country_variance = as.numeric(vc[[1]]) ## diag(vc[["cntry"]])
    resid = attr(vc, "sc")^2
    Total_variance = Country_variance + resid
    ICC = Country_variance/Total_variance
    return(ICC)
}

#Give_me_the_ICC('security', dat5) #example 

#All_ICC_dat5 = sapply(colnames(dat5[,-1]), Give_me_the_ICC, dat5)
#All_ICC_dat5

#range(All_ICC_dat5)

#========================= Plot it ==============================================

Give_me_a_Blue_Plot = function(Y, your_data){
    #plot_colour = sample(x=c("blue","red","dark green", "purple"), 
    #                     replace = T, size = 1,)
    
    ggplot(your_data, aes(x = country, y = Y) ) + 
        geom_boxplot(fill = "blue", colour = "blue", 
                     alpha = 0.35, outlier.size = 0)+ 
        geom_jitter(colour = "blue", height = 1, width = 0.5, size  = 1)
    
    # makes a boxplot of each country for a single variable Y
    #outlier.size = -1 gets rid of the outlier points as they aren't useful for us
}

Give_me_a_Orange_Plot = function(Y, your_data){
    
    ggplot(your_data, aes(x = country, y = Y) ) + 
        geom_boxplot(fill = "orange", colour = "orange", 
                     alpha = 0.35, outlier.size = 0)+ 
        geom_jitter(colour = "orange", height = 1, width = 0.5, size  = 1)
    
    # makes a boxplot of each country for a single variable Y
    #outlier.size = -1 gets rid of the outlier points as they aren't useful for us
}

#Give_me_a_Plot(dat5$benevolence) #example


#================ UI ===========================================================
ui <- fluidPage(
    includeScript("../../../Matomo-tquant.js"),
    tags$head(tags$link(rel = "stylesheet",
                                    type = "text/css", href = "bootstrap.css")),
    tabsetPanel(
        tabPanel("App page", fluidRow(
            h3("Comparing intraclass correlations for Schwarz values 
               across European countries", align = "center"),
            
            column(2, 
                   selectInput("variable", "Variable for Graph 1:", 
                                  c("Self Direction" = 'self_direction', 
                                    "Power" = 'power', 
                                    "Universalism" = 'universalism',
                                    "Hedonism" = "hedonism",
                                    "Stimulation" = 'stimulation',
                                    "Security" = 'security',
                                    "Achievement" = 'achievement',
                                    "Conformity" = 'conformity',
                                    "Tradition" = 'tradition',
                                    "Benevolence" = 'benevolence'
                                  )
                    ),
            
                selectInput("variable2", 
                        "Variable for Graph 2:", 
                        c("Self Direction" = 'self_direction', 
                          "Power" = 'power', 
                          "Universalism" = 'universalism',
                          "Hedonism" = "hedonism",
                          "Stimulation" = 'stimulation',
                          "Security" = 'security',
                          "Achievement" = 'achievement',
                          "Conformity" = 'conformity',
                          "Tradition" = 'tradition',
                          "Benevolence" = 'benevolence'
                        )
            ),
            checkboxGroupInput("country", 
                               choices = c("Austria" = "AT", "Switzerland" = "CH", "Czech Republik" = "CZ",
                                           "Germany" = "DE", "Denmark" = "DK", "Estonia" = "EE",
                                           "Fiction high" = "FH", "Finland" = "FI", "Fiction low" = "FL",
                                           "France" = "FR", "Ireland" = "IE", "The Netherlands" = "NL", 
                                           "Poland" = "PL", "Sweden" = "SE", "Slovenia" = "SI"), 
                               label = "Country", 
                               selected = c("AT","CH", "CZ", "DE"))
            ),
            
            column(7, plotOutput("plot1", height = "300px"),
                   plotOutput("plot2", height = "300px")),
            
            column(2, p("ICC for the First Graph = "),
                   textOutput("ICC1"),
                   
                   br(), br(), br(), br(), br(), br(), br(), br(), br(), br(),br(),br(),
                   
                   ("ICC for the Second Graph = "),
                   textOutput("ICC2")
            )
        )),
        tabPanel("Information", 
        HTML("<b>Contents</b>
            <br><br>
            1.	This app<br>
            2.	The data<br> 
            3.	ICC<br>
            4.	Schwartz's model<br> 
            5.	How to use this app
            <br><br>
            
                                     
            <b>Information about this app</b><br>
            The purpose of this app is to provide an
            interactive and educational way of understanding the intraclass correlation
            coefficient (ICC).<br><br>
                                     
            <b>Information about the data</b><br>
            The data our app uses is takens from The European Social Survey (ESS),
            a cross-national survey carried out by The European Science Foundation. The
            ESS measures attitudes, beliefs, and behavior patterns of a diverse European
            population.<br>
            Our app uses the round seven ESS dataset. we sampled 100 responses each from 
            13 countries, with two additional fictional countries added for educational 
            purposes. One fictional country we added extremely
            high on the values while the other one is extremely low. For each country
            we have data for their scores on the 10 Schwarz values.<br><br>
                                     
            <b>Intraclass correlation coefficient (ICC)</b><br>
            The intraclass correlation coefficient describes tells us the proportion of the 
            total variance that is between groups rather than within groups. An ICC of close to 0
            indicates that most of the variance in the data is within countries, but a ICC closer 
            to 1 indicates that most of the variance is between countries. It's a similar concept to 
            the F ratio used in an ANOVA. For example, the ICC can be used to quantify the degree to 
            which siblings resemble each other for a given trait. It is also sometimes used as a inter-rater
            reliability test in order to assess the consistency of different raters.<br><br>
            
            <b>Schwartz's model of universal human values</b><br>
            The Theory of Basic Human Values measures universal
            values that are recognised throughout all cultures. Schwartz's theory
            identifies 10 motivationally distinct values and
            describes the relationships between them.<br><br>"),
        
            imageOutput("Schwarz"),
            
            HTML("
            This dataset consists of the composite scores for each participant
            for 2 or 3 items which represent the aforementioned values. Participants
            read sentences describing values of a fictional individual and mark to which
            level (1 = not at all like me to 6 = very much like me) they consider
            themselves similar to the fictional person's life values. In the
            following table, value names and descriptions are provided.<br><br>

            <b>How to use this app</b><br> 
             Use the drop-down boxes to select any 2 measures to compare.
             You can choose from the 10 Schwarz values. Once you have selected a measure, 
             the app will generate some a boxplot for each country  that has been ticked,
             along with their ICC values. Notice how the data for each measure differs, 
             and how it affects the ICC for that measure.
             Which variables vary most between countries, and which vary mostly 
             within country? Does changing the number of countries affect the ICC value?
             <br> <br>")),
        
             tabPanel("Meet the authors", 
                 imageOutput("The_Authors"),
                 p(HTML("The glorious app designers. Left to right: 
                   Richie, Sandra, Lea, Mirela, Nadine, Massimiliano.<br><br>

                  Sandra Garcia Garcia, Compultense University of Madrid<br>
                  Lea Jakob, University of Zagreb<br>
                  Nadine Koch, University of Tubingen<br>
                  Thomas Richardson, University of Glasgow<br>
                  Mirela Zaneva, University of Amsterdam<br>
                  Massimiliano Zuccarini, University of Padua")
                 ))))

#===================== Server ================================================== 

server <- function(input, output){
    output$plot1 <- renderPlot({
        
        data.new <- data.frame()
        for(i in 1:length(input$country)){
            if(length(input$country) == i){
                for(j in 1:i){
                    data.new <- rbind(data.new,
                                      as.data.frame(dat5[dat5$country == input$country[j],]))
                }
            }else{}
        }
        data.new = droplevels(data.new)
        
        Give_me_a_Blue_Plot(data.new[[input$variable]], data.new)
    })
    
    output$plot2 <- renderPlot({
        data.new <- data.frame()
        for(i in 1:length(input$country)){
            if(length(input$country) == i){
                for(j in 1:i){
                    data.new <- rbind(data.new, 
                                      as.data.frame(dat5[dat5$country == input$country[j],]))
                }
            }else{}
        }
        data.new = droplevels(data.new)
        Give_me_a_Orange_Plot(data.new[[input$variable2]], data.new)
    })
    
    output$ICC1 = renderPrint({
        data.new <- data.frame()
        for(i in 1:length(input$country)){
            if(length(input$country) == i){
                for(j in 1:i){
                    data.new <- rbind(data.new, 
                                      as.data.frame(dat5[dat5$country == input$country[j],]))
                }
            }else{}
        }
        data.new = droplevels(data.new)
        Give_me_the_ICC(input$variable,data.new)
    })
    
    output$ICC2 = renderPrint({
        data.new <- data.frame()
        for(i in 1:length(input$country)){
            if(length(input$country) == i){
                for(j in 1:i){
                    data.new <- rbind(data.new, 
                                      as.data.frame(dat5[dat5$country == input$country[j],]))
                }
            }else{}
        }
        data.new = droplevels(data.new)
        Give_me_the_ICC(input$variable2,data.new)
    })
    
    output$The_Authors = renderImage({
        list(
            src = "www/images/authors.png",
            filetype = "image/png",
            alt = "The authors of this app. They are probably with you now.")}, 
        deleteFile = F)
    
    output$Schwarz = renderImage({
        list(
            src = "www/images/circle1.jpg",
            filetype = "image/jpg",
            alt = "Schwarz' model")}, 
        deleteFile = F)
  }

#=========== Run App ============================================================
  
shinyApp(ui = ui, server = server)