niels_theun
niels_theun

Reputation: 3

Use reactive variables in regular functions R shiny

I'm trying to build a bilingual dashboard. In this dashboard I want to choose the right language column (either ENG or NL) based on input$language. This column serves as the levels input for a function in which a plotly graph is made.

The problem is now that when I use the radiobutton and change the language, nothing changes in the plotly graph. I'm guessing the regular function is not updating when something changes in the 'custom_levels_lang' reactive variable.

How can I make this work?

server.R

library(shinydashboard)
library(dplyr)
library(tidyr)
library(shiny)
library(plotly)

#make bilangual df
ID = c("level_1_graph1","level_1_graph1")
NL = c("Ja","Nee")
ENG = c("Yes","No")

levels_lang = data.frame(ID,NL,ENG)


#create df for pie-chart
S <- c("Ja","Nee")
n <- c(645,544)
percentage <- c(54,46)


df <- data.frame(S,n,percentage)


function(input, output, session) {



# Creating levels by language


custom_levels_lang <- reactive({

#select chosen language for input$language, then transpose all levels per 
#graph number to separate columns
#gives custom_levels_lang$'name'
df <- levels_lang %>%
select(ID,one_of(input$language)) %>%
mutate(row = row_number()) %>%
spread_("ID",input$language)

#make list
df <- as.list(df)

#remove na's from list
df <- lapply(df, function(x) x[!is.na(x)])

return(df)



  })    





#create pie-chart    
plot_pie <- function(custom_levels){


plt <- renderPlotly({


#give right levels based on chosen language      
levels(df$S) <-  custom_levels



  #construct plot
  df %>%
    plot_ly(
      labels = df$S,
      values = ~percentage,
      type = 'pie',
      hole = 0.5,
      textinfo = 'percent',
      text = ~paste("n = ", n),
      hoverinfo = 'text') %>% 
    layout(
      showlegend = TRUE,
      legend = list(x = 0.2, y = -0.3),
      title = "title") %>% 
    config(
      displaylogo = FALSE,
      collaborate = FALSE,
      modeBarButtonsToRemove = list('zoom2d','pan2d','zoomIn2d','zoomOut2d',
      'autoScale2d','resetScale2d','toggleHover',
      'toggleSpikelines','hoverClosestCartesian','hoverCompareCartesian'))
})

return(plt)

}

output$plt1 <- plot_pie(custom_levels = custom_levels_lang()$level_1_graph1)

}

ui.R

library(shinydashboard)
library(dplyr)
library(tidyr)
library(shiny)
library(plotly)

header <- dashboardHeader(
title = "Welcome",
titleWidth = 450)

sidebar <- dashboardSidebar(width = 300, radioButtons("language", label = "Kies taal", choices = list("Nederlands" = "NL", "English" ="ENG"), selected = "NL"))

body <- dashboardBody( plotlyOutput('plt1') )

dashboardPage(header,sidebar,body)

Upvotes: 0

Views: 515

Answers (1)

GyD
GyD

Reputation: 4072

The renderPlotly function has to be outside the function call so that it gets notified whenever its dependency (custom_levels_lang()$level_1_graph1) changes.

In your code it's not in a reactive context, so it only gets rendered once.

plot_pie <- function(custom_levels){
  #give right levels based on chosen language      
  levels(df$S) <-  custom_levels

  #construct plot
  plt <- df %>%
    plot_ly(
      labels = df$S,
      values = ~percentage,
      type = 'pie',
      hole = 0.5,
      textinfo = 'percent',
      text = ~paste("n = ", n),
      hoverinfo = 'text') %>% 
    layout(
      showlegend = TRUE,
      legend = list(x = 0.2, y = -0.3),
      title = "title") %>% 
    config(
      displaylogo = FALSE,
      collaborate = FALSE,
      modeBarButtonsToRemove = list('zoom2d','pan2d','zoomIn2d','zoomOut2d',
                                    'autoScale2d','resetScale2d','toggleHover',
                                    'toggleSpikelines','hoverClosestCartesian','hoverCompareCartesian'))
  return(plt)
}

output$plt1 <- renderPlotly(plot_pie(custom_levels = custom_levels_lang()$level_1_graph1))

Upvotes: 1

Related Questions