<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Shiny on Methods Bites</title>
    <link>https://socialsciencedatalab.mzes.uni-mannheim.de/tags/shiny/</link>
    <description>Recent content in Shiny on Methods Bites</description>
    <generator>Hugo -- gohugo.io</generator>
    <lastBuildDate>Tue, 17 Dec 2019 01:00:00 +0100</lastBuildDate>
    
        <atom:link href="https://socialsciencedatalab.mzes.uni-mannheim.de/tags/shiny/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Shiny Apps: Development and Deployment</title>
      <link>https://socialsciencedatalab.mzes.uni-mannheim.de/article/shiny-apps/</link>
      <pubDate>Tue, 17 Dec 2019 01:00:00 +0100</pubDate>
      
      <guid>https://socialsciencedatalab.mzes.uni-mannheim.de/article/shiny-apps/</guid>
      <description><![CDATA[
        </p>
<p>Shiny Apps allow developers and researchers to easily build interactive web applications within the environment of the statistical software R. Using these apps, R users can interactively communicate their work to a broader audience. In this <a href="https://socialsciencedatalab.mzes.uni-mannheim.de/categories/tutorials/">Method Bites Tutorial</a>, <a href="https://twitter.com/kongavras">Konstantin Gavras</a> and <a href="https://twitter.com/Nick_Baumann97">Nick Baumann</a> present a comprehensive recap of Konstantin Gavras’ (University of Mannheim) workshop materials to illustrate how Shiny Apps enable vivid data presentation as well as its usefulness as an analytical tool.</p>
<p>After reading this blog post and engaging with the applied examples, readers should:</p>
<ul>
<li>be able to retrace the logic behind the structure of Shiny Apps,</li>
<li>be able to build their own Shiny App, and</li>
<li>be able to deploy their Shiny App and run them in the world wide web.</li>
</ul>
<p><em>Note:</em> This blog post provides a summary of Konstantin’s workshop in the MZES Social Science Data Lab with some adaptations. Konstantin’s original workshop materials, including slides and scripts, are available from our <a href="https://github.com/SocialScienceDataLab/shiny-development-deployment">GitHub</a>. A recording of the workshop is available on <a href="https://www.youtube.com/watch?v=QT3WUQu99pM">Youtube</a>.</p>
<div id="contents" class="section level5">
<h5>Contents</h5>
<ol style="list-style-type: decimal">
<li><a href="#shiny-apps-and-data-presentation">Shiny Apps and Data Presentation</a></li>
<li><a href="#the-structure-of-shiny-apps">The Structure of Shiny Apps</a></li>
<li><a href="#developing-shiny-apps">Developing Shiny Apps</a>
<ol style="list-style-type: decimal">
<li><a href="#building-a-shiny-app-from-scratch">Building a Shiny App from Scratch</a></li>
<li><a href="#building-the-ui">Building the UI</a></li>
<li><a href="#implementing-the-server-logic">Implementing the Server Logic</a></li>
<li><a href="#rendering-plots">Rendering Plots</a></li>
</ol></li>
<li><a href="#deployment">Deployment</a>
<ol style="list-style-type: decimal">
<li><a href="#deployment-using-shinyapps.io">Deployment using shinyapps.io</a></li>
<li><a href="#deployment-using-shiny-server">Deployment using Shiny Server</a></li>
</ol></li>
<li><a href="#conclusion">Conclusion</a></li>
</ol>
</div>
<div id="shiny-apps-and-data-presentation" class="section level3">
<h3>Shiny Apps and Data Presentation</h3>
<p>Data are usually collected in a raw format and, no matter how well processed and analyzed, results should be presented in a plain and simple way in order to make them accessible for everyone. Unfortunately, the potential of effective data presentation is all too often not fully exploited. Yet, presentation is crucial as it illustrates the actual outcome of research. If not effectively visualized, we waste a great opportunity to build credibility, attract and sustain the interest of readers, and make large amounts of information easily accessible. Here, we introduce Shiny Apps as a powerful and highly flexible tool for interactive data presentation in the world wide web.</p>
<p>Shiny is an R package that offers cost- and programming-free tools for building web applications using R. It was developed by <a href="https://github.com/jcheng5">Joe Chang</a> to serve as a reactive web framework for R that allows calculations, display of R objects, and the presentation of results. Since Shiny Apps come with an extensive back-end setup, users do not need extensive web development skills to build and host standalone apps on a homepage. However, for those keen on bringing their apps to perfection, Shiny Apps allows for CSS, HTML and JavaScript extensions.Shiny Apps can be used either for data presentation, as a communication tool for results, or even as an interactive analytical tool.</p>
<p>In what follows, we introduce the Shiny environment and guide readers through the development of Shiny Apps. Using the famous Kaggle <code>titanic</code> data set, we draw the distinction between the front-end <code>ui.R</code> and back-end <code>server.R</code>, which are required to build Shiny apps. Following this, we introduce important concepts and features to build an interactive app, including control widgets, reactivity, and rendering.</p>
</div>
<div id="the-structure-of-shiny-apps" class="section level3">
<h3>The Structure of Shiny Apps</h3>
<p>Shiny applications have two components. The front-end builds the webpage that is actually shown to the user. As already mentioned, the HTML page is written by Shiny itself and includes layout, appearance, and design features. In Shiny terminology, this is called the <code>ui</code>, which stands for user interface. The <code>ui</code> file contains R functions that are then translated into an HTML file.
The other component is the back-end, which includes the code for producing the app’s contents (e.g. functions or data import, management, and analysis). Here, we create the objects that are later shown on the front-end. In Shiny terminology this is called the <code>server</code>.</p>
<div id="ways-of-setting-up-a-shiny-app" class="section level5">
<h5>Ways of Setting Up a Shiny App</h5>
<p>Shiny Apps can be set up in two different ways.</p>
<p><strong>1. Single-file App:</strong>
In a single-file app, <code>ui</code> and <code>server</code> are stored in one script. In this case, we create a file named <code>app.R</code> that contains both the server and UI components. This technique is used when developing very simple Shiny Apps and lacks some advantages of the alternative two-files App method.</p>
<p><strong>2. Two-files App:</strong>
Here, <code>ui</code> and <code>server</code> are stored in two separate scripts, which implies a clear separation between front-end and back-end. This method is preferable when developing more advanced Shiny Apps. It is <strong>important that the files are named <code>ui.R</code> and <code>server.R</code> and always stored in a separate folder</strong>. In this tutorial, we are going to develop Shiny Apps using the two-files method.</p>
</div>
</div>
<div id="developing-shiny-apps" class="section level3">
<h3>Developing Shiny Apps</h3>
<div id="building-a-shiny-app-from-scratch" class="section level5">
<h5>Building a Shiny App from Scratch</h5>
<p>To set up, make sure that all required packages are installed and subsequently load the <code>shiny</code>,<code>tidyverse</code>, and <code>plotly</code> packages along with R’s example data set <code>titanic</code>.</p>
<details>
<p><summary> Code: R packages used in this tutorial</summary></p>
<pre class="r"><code>## Packages
pkgs &lt;- c(&quot;shiny&quot;,
          &quot;tidyverse&quot;,
          &quot;titanic&quot;,
          &quot;plotly&quot;)

## Install uninstalled packages
lapply(pkgs[!(pkgs %in% installed.packages())], install.packages)

## Load all packages to library
lapply(pkgs, library, character.only = TRUE)</code></pre>
<pre><code>## Warning: package &#39;shiny&#39; was built under R version 3.6.3</code></pre>
<pre><code>## Warning: package &#39;ggplot2&#39; was built under R version 3.6.3</code></pre>
<pre><code>## Warning: package &#39;tidyr&#39; was built under R version 3.6.3</code></pre>
<pre><code>## Warning: package &#39;plotly&#39; was built under R version 3.6.3</code></pre>
</details>
<p><br />
Next, create a new folder with two R scripts, <code>ui.R</code> and <code>server.R</code>:</p>
<details>
<p><summary>Code: Load packages and create folder with two R scripts</summary></p>
<pre class="r"><code>ui &lt;- fluidPage()
server &lt;- function(input, output) {
}</code></pre>
</details>
<p></br>
Subsequently, launch the Shiny App by pressing the “Run App” button in the top right corner of the Source pane. Also, have a look at the the code chunk below, which provides an example of a Shiny App.</p>
<details>
<p><summary>Code: Example </summary></p>
<pre class="r"><code>runExample(&quot;01_hello&quot;)
# To show other Apps, please type runExample(NA) and choose another example</code></pre>
</details>
<p></br></p>
</div>
<div id="building-the-ui" class="section level5">
<h5>Building the UI</h5>
<p>When building a Shiny App, one should have in mind what the app should look like. Hence, we build the UI first. In simple Shiny Apps, the whole UI fits in the <code>fluidPage</code>: every new object is passed comma-separated, and text can be passed to the UI simply by entering strings. In order to format text, Shiny uses HTML wrappers, i.e., functions that take text as arguments (plus further style options).</p>
<ul>
<li><code>h1()</code>: top-level header</li>
<li><code>h2()</code>: secondary header</li>
<li><code>strong()</code>: make text bold</li>
<li><code>em()</code>: make text italicized</li>
<li><code>br()</code>: add line break</li>
<li><code>titlePanel()</code>: adds an official header</li>
</ul>
<p>Until now, we only have a plain white page. We need a proper layout to make our app look nicer. <code>sidebarlayout</code> is the simplest layout format. It splits your page in two parts: a <code>sidebarPanel</code>and a <code>mainPanel</code>. Inside <code>sidebarLayout</code> you may use <code>sidebarPanel</code> to specify the appearance of the side panel of your page. The <code>mainPanel</code> contains the results of the
<code>server</code>.</p>
<details>
<p><summary>Code: Building the plain UI </summary></p>
<pre class="r"><code>ui &lt;- fluidPage(titlePanel(&quot;Title of my Shiny App&quot;),
                sidebarLayout(
                  sidebarPanel(&quot;My input goes here&quot;),
                  mainPanel(&quot;The results go here&quot;)
                ))</code></pre>
</details>
<p></br>
In order to interact with Shiny Apps, we need control widgets, such as buttons, select boxes, or sliders. These allow us to navigate the app. The type of the widget you choose depends on the design of your app. You can either specify inputs, enter text, or select specific dates to create results. All input functions have two arguments: <code>inputId</code> and <code>label</code>.</p>
<p><code>inputId</code> tells Shiny to refer to a particular input when retrieving values for the back-end. <strong>It is important that the ID names you use are unique</strong>. If you have two IDs with the same name, there will not be a warning or error message. Consequently, the app may use the wrong input in the wrong place without notification. An overview of all types of widgets you can work with is provided <a href="https://shiny.rstudio.com/tutorial/written-tutorial/lesson3/">here</a>. The <code>label</code> option specifies the text displaying the label of the control widget. The control labels go in the <code>sidebarPanel</code>. Here, we specify the possible values, range, and the appearance of the control widget.</p>
<p>Having added the input and the control widgets, we finally need to specify the output elements of our app. These outputs might be plots, tables, text, images, or maps. These will be built in the <code>server</code> file of our two-files app. In the UI, we only build the placeholder, which means that every output function has an <code>outputId</code> argument to identify the output created in <code>server.R</code>. Here, we use <code>plotlyOutput</code> to refer to a plot that will be generated later in <code>server.R</code>. Output elements should always be added to the <code>mainPanel()</code> function. Other types of output elements are:</p>
<ul>
<li><code>dataTableOutput()</code>: data table</li>
<li><code>imageOutput()</code>: image</li>
<li><code>plotOutput()</code>: plot</li>
<li><code>tableOutput()</code>: table</li>
<li><code>verbatimTextOutput()</code>: text</li>
<li><code>textOutput()</code>: text</li>
<li><code>uiOutput()</code>: raw HTML</li>
<li><code>htmlOutput()</code>: raw HTML</li>
</ul>
<p>The code chunk below demonstrates how widget and output elements can be combined.</p>
<details>
<p><summary>Code: Finishing the UI </summary></p>
<pre class="r"><code># The most simple structure of the UI:
ui &lt;- fluidPage(
  titlePanel(&quot;Visualizing the Titanic data set&quot;),
  sidebarLayout(
    sidebarPanel(
      checkboxInput(&quot;checkbox&quot;,
                    &quot;Activate all filters&quot;,
                    FALSE),
      radioButtons(
        &quot;buttons&quot;,
        &quot;Did the passenger survive?&quot;,
        choices = c(&quot;did not survive&quot; = 0, &quot;did survive&quot; = 1),
        selected = 0
      ),
      selectInput(&quot;selector&quot;,
                  &quot;Select the class of the passenger&quot;,
                  choices = c(1, 2, 3)),
      sliderInput(
        &quot;slider&quot;,
        &quot;Pick a range of fare (in $)&quot;,
        min = 0,
        max = 550,
        value = c(10, 50),
        pre = &quot;$&quot;
      ),
      selectInput(
        &quot;selectVars&quot;,
        &quot;Select the variable to be displayed&quot;,
        choices = c(
          &quot;Age&quot; = &quot;Age&quot;,
          &quot;# of Siblings/Spouses on board&quot; = &quot;SibSp&quot;,
          &quot;# of Parents/Children on board&quot; = &quot;Parch&quot;
        )
      )
    ),
    mainPanel(plotlyOutput(&quot;greatPlot&quot;),
              textOutput(&quot;goodText&quot;))
  )
)</code></pre>
</details>
<p></br></p>
</div>
<div id="implementing-the-server-logic" class="section level5">
<h5>Implementing the Server Logic</h5>
<p>Having finished the front-end, we now turn to building the <code>server</code> or the back-end. The <code>server</code> logic in Shiny Apps uses an <code>input</code> argument, which contains the values of the input given by the users, as well as an <code>output</code> argument, which contains the plots and tables created as a function of the input arguments. Output objects can be created without any input specification, but always need to be connected with the UI by an <code>outputId</code>. To do so, save the output object into the <code>output</code> list. We then build the object using one of the available render functions. For every object type, there is a unique render function, e.g. <code>renderPlot()</code>. The table below provides a brief overview of which <code>render</code> functions work with which output formats.</p>
<table class="table table-striped table-hover table-condensed table-responsive" style="margin-left: auto; margin-right: auto;">
<thead>
<tr>
<th style="text-align:left;">
render()
</th>
<th style="text-align:left;">
Output()
</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align:left;">
<code>renderDataTable()</code>
</td>
<td style="text-align:left;">
<code>dataTableOutput()</code>
</td>
</tr>
<tr>
<td style="text-align:left;">
<code>renderImage()</code>
</td>
<td style="text-align:left;">
<code>imageOutput()</code>
</td>
</tr>
<tr>
<td style="text-align:left;">
<code>renderPlot()</code>
</td>
<td style="text-align:left;">
<code>plotOutput()</code>
</td>
</tr>
<tr>
<td style="text-align:left;">
<code>renderPrint()</code>
</td>
<td style="text-align:left;">
<code>verbatimTextOutput()</code>
</td>
</tr>
<tr>
<td style="text-align:left;">
<code>renderTable()</code>
</td>
<td style="text-align:left;">
<code>tableOutput()</code>
</td>
</tr>
<tr>
<td style="text-align:left;">
<code>renderText()</code>
</td>
<td style="text-align:left;">
<code>textOutput()</code>
</td>
</tr>
<tr>
<td style="text-align:left;">
<code>renderUI()</code>
</td>
<td style="text-align:left;">
<code>uiOutput()</code> and <code>htmlOutput()</code>
</td>
</tr>
</tbody>
</table>
<p>We have to make sure that we accurately assign our IDs to their corresponding render and output functions. Since we named our <code>plotOutput</code> in the UI <code>greatPlot</code>, we have to assign it to this ID. As we use the <code>plotOutput</code> function in the UI, we need the <code>renderPlot</code> function to match it. Furthermore, our plots need a connection to the input and the control widgets. The logic behind the input list is the same as for the output list: As we used the <code>sliderInput</code> function in the UI and named it <code>slider</code>, we now access the respective object. Given the structure of the input, we specify it to fit the output object.</p>
<details>
<p><summary>Code: Fitting IDs and output/render functions </summary></p>
<pre class="r"><code>output$greatPlot &lt;- renderPlot({
  plot(rnorm(input$slider[1]))
})</code></pre>
</details>
<p></br></p>
</div>
<div id="rendering-plots" class="section level5">
<h5>Rendering Plots</h5>
<p>There are several ways of increasing the interactivity of plots. For example, one can simply add code to the <code>renderplot()</code> function. Another very simple way of increasing interactivity is filtering. However, when filtering, the whole code will get re-executed every time the user re-specifies anything, which can become very memory-intensive and repetitive when building several plots! We therefore use reactive variables to extract the filtering from the render functions. Reactive variables can now be used for different objects, which change simultaneously with different input. Additionally, we use <code>plotly</code> plots to make it even more interactive. You simply need to replace the <code>plotOutput()</code> with <code>plotlyOutput()</code> in the <code>UI</code>.</p>
<details>
<p><summary>Code: Make plots reactive and interactive </summary></p>
<pre class="r"><code># Back-end
# The server function takes input and output as arguments
# input: Input provided by the user to specify a certain appearance, data 
#        or result
# output: The output created by the functions specified in the back end

server &lt;- function(input, output) {
  # Create a reactive variable to use it for different objects interactively
  filtered &lt;- reactive({
    titanic_train %&gt;%
      filter(
        Fare &gt;= input$slider[1],
        Fare &lt;= input$slider[2],
        Pclass == input$selector,
        Survived == input$buttons
      )
  })
  
  # Plot the variables of the titanic_train data set
  # Using if-conditions to specify the variables being plotted
  output$greatPlot &lt;- renderPlotly({
    if (input$checkbox == TRUE) {
      x &lt;- filtered()[, input$selectVars]
      plotHist &lt;- ggplot(filtered(), aes(x)) +
        geom_histogram()
    } else {
      x &lt;- titanic_train[, input$selectVars]
      plotHist &lt;- ggplot(titanic_train, aes(x)) +
        geom_histogram()
    }
    
    ggplotly(plotHist)
  })
  
  output$goodText &lt;- renderText({
    if (input$checkbox == TRUE) {
      x &lt;- nrow(filtered()[filtered()$Survived == 1, ])
      text &lt;-
        paste0(&quot;Using your filter &quot;, x, &quot; passengers have survived&quot;)
      return(text)
    } else {
      x &lt;- nrow(titanic_train[titanic_train$Survived == 1, ])
      text &lt;- paste0(&quot;In total &quot;, x, &quot; passengers have survived&quot;)
      return(text)
    }
  })
}</code></pre>
</details>
<p></br>
To finally visiualize our plot locally, we simply run <code>shinyApp(ui = ui, server = server)</code>. This allows us to see the final Shiny App, including some additional components, which increases the functionality of the app even further.</p>
<div style="position:relative;padding-top:56.25%;">
<p><iframe src="https://kgavras.shinyapps.io/Shiny_Development_Deployment/" frameborder="0" allowfullscreen marginheight="100"
    style="position:absolute;top:0;left:0;width:100%;height:100%;" scrolling="yes" onload="resizeIframe(this)"></iframe></p>
</div>
</div>
</div>
<div id="deployment" class="section level3">
<h3>Deployment</h3>
<div id="deployment-using-shinyapps.io" class="section level5">
<h5>Deployment using shinyapps.io</h5>
<p>Until now, we only ran our apps locally on our machine. In order to present an app to a broader audience, we need to deploy it in the world wide web. We have to take care that our app is protected by a firewall and that we have a stable URL. For simple apps, deploy the app using a free account on <a href="https://www.shinyapps.io/">shinyapps.io</a>. If done so, go back to RStudio, press the deploy button in the top right corner of the Source pane, re-enter your credentials, select the correct files, and let the magic happen!</p>
</div>
<div id="deployment-using-shiny-server" class="section level5">
<h5>Deployment using Shiny Server</h5>
<p>For certain apps you might not want to use <a href="wwww.shinyapps.io">shinyapps.io</a>, for instance if:</p>
<ul>
<li>the size of the app would require a (very) costly plan, or</li>
<li>you want full control over the app and host it yourself, or</li>
<li>you love playing around with Unix code.</li>
</ul>
<p>A free alternative is Shiny Server, which allows you to host your own app in a controlled environment (e.g. inside your organization). The professional version of Shiny Server (Shiny Server Pro) allows you to deploy password-protected apps and use an administrative dashboard that provides you with usage statistics. However, you need an own server to host the app (e.g. Digital Ocean or Amazon Web Services), which may still be costly.</p>
<p>Another alternative is hosting the app on university servers. For instance, members of the University of Mannheim can use the web services provided by the universities of Baden-Württemberg, the <em>bwCloud</em>, for free.</p>
<p>When using Shiny Server, the required steps are a bit more complicated:</p>
<ol style="list-style-type: decimal">
<li><a href="https://www.bw-cloud.org/de/erste_schritte">Register</a> for the bwCloud</li>
<li>Log into the bwCloud Dashboard</li>
<li>Create an SSH-key pair to connect to your server (find a short intro <a href="https://www.bw-cloud.org/de/bwcloud_scope/nutzen">here</a>)</li>
<li>Install <a href="https://www.putty.org/">PuTTY</a> (Windows) or start a remote connection in the Shell (MAC) as well as <a href="https://filezilla-project.org/">Filezilla</a></li>
<li>Set up the SSH-client to access remote connections</li>
<li>Build a virtual machine (the server) using your bwCloud dashboard and connect to your virtual machine using SSH with PuTTY</li>
</ol>
<p>After setting up the server, we need to enter our Unix system and install R, all relevant packages, and Shiny Server using Unix code</p>
<ol style="list-style-type: decimal">
<li>Install R on your machine</li>
</ol>
<pre class="r"><code>sudo apt-get install r-base</code></pre>
<p>If you are lucky, this will install the correct version. Otherwise, this <a href="https://www.digitalocean.com/community/tutorials/how-to-install-r-on-ubuntu-18-04">tutorial</a> might be of help.</p>
<ol start="2" style="list-style-type: decimal">
<li>Install dependencies to install R packages</li>
</ol>
<pre class="r"><code>sudo apt-get -y install libcurl4-gnutls-dev 
sudo apt-get -y install libxml2-dev libssl-dev</code></pre>
<ol start="3" style="list-style-type: decimal">
<li>Install R packages within R, including <code>shiny</code> (easy!)</li>
</ol>
<pre class="r"><code>install.packages(&quot;shiny&quot;)</code></pre>
<ol start="4" style="list-style-type: decimal">
<li>Install Shiny Server (check for latest version!)</li>
</ol>
<pre class="r"><code>wget https://download3.rstudio.org/ubuntu-12.04/x86_64/shiny-server-1.5.6.875-amd64.deb
sudo gdebi shiny-server-1.5.6.875-amd64.deb</code></pre>
<ol start="5" style="list-style-type: decimal">
<li>Open port 3838 and check whether your firewall is set up</li>
</ol>
<pre class="r"><code>sudo ufw allow 3838</code></pre>
<ol start="6" style="list-style-type: decimal">
<li>Test whether Shiny Server runs correctly. Open this in your browser: <code>http://134.155.108.111:3838/</code> (replace with your IP-address)</li>
<li>Use Filezilla to access your server and upload your app files to the <code>/srv/shiny-server/</code> folder. It should run when typing in the correct URL associated with your app: <code>http://134.155.108.111:3838/foldername/projectname/</code></li>
<li>The above will likely not work immediately. In this case, you need to go back and troubleshoot… (click <a href="https://www.digitalocean.com/community/tutorials/how-to-set-up-shiny-server-on-ubuntu-16-04">here</a> for a tutorial)</li>
</ol>
</div>
</div>
<div id="conclusion" class="section level3">
<h3>Conclusion</h3>
<p>Data presentation is crucial for accessible scientific research. Even with accurate and comprehensive data that supports relevant findings, failure to present the data in an easily accessible way can result in wasted opportunities. Shiny Apps are a powerful and free-of-cost tool that allows scholars to provide readers with easy-to-use, interactive, and comprehensive insights into their research. For instance, scholars can use Shiny Apps to program an interactive online appendix and thereby offer readers full control to compare findings under different specifications of measurement and modeling.</p>
<p>However, the advantages of creating a functional web-application exclusively with R has some limitations. Considering the design and the placement of inputs (such as sliders) or outputs (such as graphics and tables), Shiny is limited. When combining Shiny with HTML, CSS, and JavaScript, however, it offers a good way to program professional web-apps. Shiny is particularly great for fast prototyping and fairly easy to use with little experience in programming. It comes with many different charting libraries and captures feedback and comments in a structured manner. It therefore offers an exciting toolbox that can be a valuable addition to scientific research.</p>
</div>
<div id="about-the-presenter" class="section level3">
<h3>About the Presenter</h3>
<p>Konstantin Gavras
<a href="mailto:konstantin@gavras.de"><i class="fa
              fa-envelope"></i> </a>
<a href="http://konstantin.gavras.de/"><i class="fa
              fa-globe"></i> </a>
<a href="https://twitter.com/kongavras"><i class="fa
              fa-twitter"></i></a> is a Ph.D. candidate at the Graduate School of Economic and Social Sciences in Political Science, research associate at the Chair of Political Psychology at the University of Mannheim and doctoral researcher for the MZES project “Fighting together, moving apart? European common defence and shared security in an age of Brexit and Trump”. His research interests comprise the intersection of Social Psychology and Political Behavior, focusing on the behavioral consequences and conditions underlying political attitudes regarding both domestic and foreign policies.</p>
</div>
]]>
      </description>
    </item>
    
  </channel>
</rss>