0

i have a data.frame from my DB, and i am trying to create a R Shiny Web App in which i could choose from the two dropdown menus (based on values from combination of row and column in my data.frame) and pass those variables to plotly

Lets say i have this data in my data frame:

# |User|N00   |Percentage|N01 |
  |----|------|----------|----|
  |35  |2229  | 4.46830  |918 |
  |37  |153   | 0.00307  |0   |
  |39  |1557  | 0.03120  |0   |
  |41  |4997  | 0.10014  |0   |
  |42  |1     | 0.00002  |0   |
  |44  |12221 | 0.24490  |0   |
  |46  |5     | 0.00010  |0   |
  |50  |342   | 0.00685  |0   |
  |51  |123   | 0.00246  |0   |
  |56  |2     | 0.00004  |1   |
  |57  |0     | 0.00000  |0   |
  |60  |62275 |1.24796   |2799|

What i would like to do is to have one dropdown with values in Column "User" and second dropdown with Headers, so i could choose "User" and "Header" and get back the appropriate result (data.frame).

So what i would need from the combination of the two dropdowns is to do something like this:

select(data_to_choose_from, User, values)[data_to_choose_from$id==values2, ]

Where values is the result of first dropdown (user), and values2 is the result of the second dropdown (headers), which looks like this:

enter image description here

So when i choose for example User "35" and Columnn "N00", i would like to get this result:

 |User|N00   |
 |----|------|
 |35  |2229  |

After i get this result i would like to pass the number in Column "N00" to some variable and create gauge with this number that would for example look like this (this is just and example, i have to tweak this to make it more "legible"):

enter image description here

I have this:

library(shiny) #Load libraries
library(plotly) #Load libraries

data_to_choose_from <- data.frame(a) #Assign data from data.frame(a), which is data i have from my DB to new variable

ui <- fluidPage(
    sidebarLayout(
        sidebarPanel(
            selectizeInput("User", "User", choices=NULL, selected=NULL), #First dropdown
            selectizeInput("Metrics", "Metrics", choices=NULL, selected=NULL), #Second dropdown
            textOutput("values"), #Show what did i choose in the first dropdown
            textOutput("values2"), #Show what did i choose in the second dropdown
            tableOutput("table") #Output tha table based on my choices in dropdowns
        ),
        mainPanel(
            plotlyOutput('p') #Plot a visualization base on data from output table
        )
    )
)

server <- function(input, output, session) { #First dropdown, reference to my data.frame
    updateSelectizeInput(session, 'User',
                         choices = data_to_choose_from$User,
                         server = TRUE
    )
    updateSelectizeInput(session, 'Metrics',
                         choices = names(data_to_choose_from), #Second dropdown, reference to my data.frame
                         server = TRUE
    )

    output$values <- renderText({(input$User)}) #Output of first dropdown

    output$values2 <- renderText({(input$Metrics)}) #Output of second dropdown

    output$values3 <- as.vector(select(data_to_choose_from, values)[data_to_choose_from$id==values2, ]) #Put this as vector to plot_ly

    output$table <- select(data_to_choose_from, id, values)[data_to_choose_from$id==values2, ] #Filtered data.frame output based on original data

    output$plot <- renderPlotly( #Here i would like to create the plot to render in mainpanel
    p <- plot_ly(
        type = "indicator",
        mode = "gauge+number+delta",
        value = i,
        title = list(text = values2, font = list(size = 24)),
        delta = list(reference = 400, increasing = list(color = "RebeccaPurple")),
        gauge = list(
            axis = list(range = list(NULL, 500), tickwidth = 1, tickcolor = "darkblue"),
            bar = list(color = "darkblue"),
            bgcolor = "white",
            borderwidth = 2,
            bordercolor = "gray",
            steps = list(
                list(range = c(0, values3), color = "cyan"),
                list(range = c(values3, 400), color = "royalblue")),
            threshold = list(
               line = list(color = "red", width = 4),
                thickness = 0.75,
                value = values3 + 100))) %>%
        layout(
            margin = list(l=20,r=30),
            paper_bgcolor = "lavender",
            font = list(color = "darkblue", family = "Arial")))
}
shinyApp(ui, server)

Unfortunately this does not work, i suppose my code is wrong from the ground up, i try to follow the documentation but i am kinda lost..

I am trying to learn R and i am confused as to how variables and Shiny R in general works, any information that would help me to achieve what i want would be greatly appreacited, if there is something unclear please let me know and i will edit my question, thanks

1 Answer 1

1

There are multiple problems.

When you do output$values <- renderSomething({......}), you can't access to ...... by calling values (you even can't call output$values).

Replace output$values3 with

  values3 <- reactive({
    req(input$User, input$Metrics)
    data_to_choose_from[data_to_choose_from$User == input$User, input$Metrics]
  })

Now you can get the value of values3 by calling values3(). So replace values3 in your renderPlotly with values3(). And replace text = values2 with text = input$Metrics.

The line req(input$User, input$Metrics) means that input$User and input$Metrics must be available. This avoids an error at the launching of the app because these variables are available only after the action of updateSelectizeInput.

If you want to render a table, use renderTable:

  output$table <- renderTable({
    req(input$User, input$Metrics)
    subset(data_to_choose_from, User == input$User, select = c("User", input$Metrics)) 
  })

You do output$plot <- renderPlotly({ p <- plot_ly(.......) }) so in your ui that should be plotlyOutput("plot"), not plotlyOutput("p"). The p <- is useless, you can remove it.

Now in plot_ly you do value = i but i is not defined. I don't know what you intended to do (I'm not familiar with this kind of plots).

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much! I will try this as soon as i get home and i will let you know if it works for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.