Home > Enterprise >  if statement is not interpretable as logical in Shiny reactive function
if statement is not interpretable as logical in Shiny reactive function

Time:05-07

I am currently working on an R Shiny project and below is a small reprex of the things I am trying to accomplish in my actual project. The basic idea is to process reactive data tables that are generated from user inputs through conditional statements in eventReactive functions. In this example below, I want to either add, multiply or subtract the user input using conditional "if" statements. I get this error: "Error in if: argument is not interpretable as logical". I know I am not sub-setting col1 correctly for logical comparison here and can't seem to find a solution.

library(shiny)
library(DT)
library(tidyverse)


input_data <- data.frame(input1 = character(),
                         input2 = double(),
                         stringsAsFactors = FALSE)

ui <- fluidPage(
  
  titlePanel("Title"),
  
  sidebarLayout(
    sidebarPanel(
      selectInput("input1",
                  "Input 1",
                  choices = c("Add", "Multiply", "Subtract")),
      numericInput("input2",
                   "Input 2",
                   value = 100),
      actionButton("add_btn",
                   "Add Input"),
      actionButton("process_btn", 
                   "Process Input"),
      position = "left"
    ),
    
    mainPanel(
      DT::dataTableOutput("input_table"),
      DT::dataTableOutput("output_table")
    )
  )
)

server <- function(input, output) {
  input_table <- reactiveVal(input_data)
  observeEvent(input$add_btn, {
    t = rbind(input_table(), data.frame(col1 = input$input1, col2 = input$input2))
    input_table(t)
  })
  
  output$input_table <- DT::renderDataTable({
    datatable(input_table())
  })
  
  output_table <- eventReactive(input$process_btn, {
    input_table() %>%
      if(input_table()$col1 == "Add") {
        mutate(col3 = col2   50)
      } else if(input_table()$col1 == "Multiply") {
        mutate(col3 = col2 * 50)
      } else 
        mutate(col3 = col2 - 50)
  })
  output$output_table <- DT::renderDataTable({
    datatable(output_table())
  })
}

CodePudding user response:

You can not use if to build constitutional pipe %>% (especially depending on the content of the piped object).

You can use ifelse() instead, or better : if_else()`:

input_table() %>%
  mutate(col3 = 
    if_else(col1 == "Add",
           col2   50,
           if_else(col1 == "Multiply",
                  col2 * 50,
                  col2 - 50)
  )

As you have several conditions you also can use case_when():

input_table() %>%
  mutate(col3 = 
           case_when(
             col1 == "Add" ~ col2   50,
             col1 == "Multiply" ~ col2 * 50,
             TRUE ~ col2 - 50)
         )
  • Related