Chris
Chris

Reputation: 307

R shiny intreactively choose variables to perform calculations

I have a simple DF with several variables. Now I want to calculate a difference between the two of them and plot it. The code below gives me what I want:

library(shiny)
library(shinydashboard)
library(tidyverse)


my_df <- data.frame("id" = c(1, 2, 3), 
                    "var1" = c(100, 200, 300), 
                    "var2" = c(120, 190, 350), 
                    "var3" = c(122, 183, 351)) %>% 
  mutate(dif = var2 - var1)

ggplot(my_df, aes(x=id, y=dif)) + 
geom_bar(stat = "identity")

Now I want to do it in Shiny to be able to choose vars that are used to calculate the difference. I've tried this:

library(shiny)
library(shinydashboard)
library(tidyverse)


my_df <- data.frame("id" = c(1, 2, 3), 
                    "var1" = c(100, 200, 300), 
                    "var2" = c(120, 190, 350), 
                    "var3" = c(122, 183, 351))


ui <- fluidPage(
  

  sidebarLayout(
    
    
    sidebarPanel(
      
     
      selectInput("value1", label = h3("Select box1"), 
                  choices = colnames(my_df[2:4]), 
                  selected = 1),
      
      selectInput("value2", label = h3("Select box2"), 
                  choices = colnames(my_df[2:4]), 
                  selected = 1)
      
    ),
    
 
    mainPanel(
      

      plotOutput(outputId = "plot")
      
    )
  )
)

server <- function(input, output) {
  
  dat <- reactive({
    my_df$dif = input$value1 - input$value2
  })
  
  output$plot <- renderPlot({
    ggplot(dat(), aes(x = id, y = dif))+
      geom_bar(stat = "identity")
    
  })
  
}

shinyApp(ui, server)

As a result, I get an error message saying "Non-numeric Argument to Binary Operator". What's wrong?

Upvotes: 2

Views: 333

Answers (1)

akrun
akrun

Reputation: 887501

In the server part, we need to subset the columns based on the column name i.e. the input$value1 and input$value2 are just column names as string. Use [[ to extract the value of the column from the dataset. Also, return the dataset after creating the 'dif' column

library(ggplot2)
server <- function(input, output) {
  
  dat <- reactive({
    my_df$dif = my_df[[input$value1]] - my_df[[input$value2]]
    my_df
  })
  
  output$plot <- renderPlot({
    ggplot(dat(), aes(x = id, y = dif))+
      geom_bar(stat = "identity")
    
  })
  
}

-testing

shinyApp(ui = ui, server = server)

-output

enter image description here


Or if we want to use mutate from dplyr

library(dplyr)
server <- function(input, output) {
  
  dat <- reactive({
    my_df %>%
         mutate(dif = cur_data()[[input$value1]] - cur_data()[[input$value2]])
    
    
  })
  
  output$plot <- renderPlot({
    ggplot(dat(), aes(x = id, y = dif))+
      geom_bar(stat = "identity")
    
  })
  
}

Upvotes: 2

Related Questions