Data manipulation not working in R Shiny

Hi,
I am trying to do some data manipulation after uploading the data file to the Shiny app. The app allows the user to choose from the variable names for the variable to be manipulated. Here I am just dividing the variable by 100. However, I get the error saying that the data cannot be displayed because the variable is non-numeric even though from the data structure I can see that the chosen variable is numeric.

Warning: Error in : error in evaluating the argument 'x' in selecting a method for function 'head': :information_source: In argument: potency = input$potencyx/100.
Caused by error in input$potencyx / 100:
! non-numeric argument to binary operator

When I try enclosing the argument with as.numeric(), the dataset is displayed. However, all the values are NA.

I have no idea what went wrong... I am using an example dataset with numeric variables. Any test dataset I use seems to give the same error.

The code is as below:

library(shiny)
library(tidyverse)

ui <- fluidPage(
  
  titlePanel("Potency vs Concentration"),
  
  fluidRow(
    # Accept CSV, XLSX, TSV as file uploads
    column(6, fileInput("upload", NULL, accept = c(".csv",".xlsx",".tsv"))),
    
    # "Empty inputs" - they will be updated after the data is uploaded
    column(6, selectInput('potencyx', 'Potency', "", selected = "")),
  ),
  
  fluidRow(
    # Get numeric input of how many rows to display
    column(6, numericInput("n", "Rows", value = 5, min = 1, step = 1)),
    
    # "Empty inputs" - they will be updated after the data is uploaded
    column(6, selectInput('concx', 'Concentration', "", selected = "")),
  ),
  
  # Display first N rows 
  tableOutput("head"),
  
  # Display data structure
  verbatimTextOutput("str"),

# Display data after manipulation
  tableOutput("head2")
)

server <- function(input, output, session) {
  data <- reactive({
    req(input$upload)
    
    ext <- tools::file_ext(input$upload$name)
    df <- switch(ext,
                 csv = vroom::vroom(input$upload$datapath, delim = ","),
                 tsv = vroom::vroom(input$upload$datapath, delim = "\t"),
                 xlsx = readxl::read_excel(input$upload$datapath),
                 validate("Invalid file; Please upload a .csv or .xlsx or .tsv file")
    )
    
    # Update inputs 
    updateVarSelectInput(session, inputId = 'potencyx', label = 'Potency',
                         data = df, selected=NULL)
    updateVarSelectInput(session, inputId = 'concx', label = 'Concentration',
                         data = df, selected=NULL)
    
    return(df)
  })
  
  # Show data before manipulation
  output$head <- renderTable({
    req(input$upload)
    
    head(data(), input$n)
    
  })
  
# Show data structure
  output$str <- renderPrint({
    req(input$upload)
    
    str(data())
    
  })
  
# Data manipulation
  data2 <- reactive({
    
    df2 <- data() |>
      mutate(potency = as.numeric(input$potencyx)/100,
             lnPotency = log(potency),
      )
    return(df2)
  })
  
# Show data after manipulation
  output$head2 <- renderTable({
    req(input$upload,input$potencyx)
    
    head(data2(), input$n)
    
  })
  
}

shinyApp(ui, server)

In the above line of code, input$potencyx is a string; it's the name of the column you want to act on. Using as.numeric() on the name of the column just returns NA. I can reproduce the error like this

DF <- data.frame(A= 1:5, B = 26)
DF |> mutate(A = "A"/100)
Error in `mutate()`:
ℹ In argument: `A = "A"/100`.
Caused by error in `"A" / 100`:
! non-numeric argument to binary operator

There is probably an elegant way around this problem using mutate but this should work.

df2 <- data()
df2$potency <- data()[[input$potencyx]]/100
df2$lnPotency <- log(df2$potency)
return(df2)

Thanks! That worked but only partly for me.

I also found the more elegant way using mutate.

data <- data |>
  mutate(potency = !!as.symbol(params$potencyx)/100,
         lnPotency = log(potency),
         ) 

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.