swisher679
swisher679

Reputation: 23

How to Create a Reactive Base R Boxplot in Shiny?

I have my data frame named df...

pain_severity = c(1, 5, 10, 8, 6, 4)

urinary_severity = c(3, 8, 9, 7, 6, 10)

df = data.frame(pain_severity, urinary_severity)

I let the user choose whether they want pain or urinary severity in select input...

UI:

tabPanel("1-Variable Visualization",
                          sidebarLayout(
                            sidebarPanel(
                              h1("Menu Selection"),

selectInput(inputId = "variable_choice", 
            label = "Variable", 
            choices = df, 
            selected = "pain_severity")

mainPanel(
         tabsetPanel(type = "tabs",
                     tabPanel("Boxplot", plotOutput("boxplot")),
)))))

SERVER:

server <- function(input, output, session) {

output$boxplot <- renderPlot({
boxplot(input$variable_choice, 
        data = df, 
        main = "", xlab="", ylab = "", horizontal = TRUE)

points(mean(input$variable_choice, na.rm = TRUE), 
       data = df, 
       1, 
       col = "red")

  })

}

I keep getting an error that reads... ERROR: non-numeric argument to binary operator

Why does this happen? When I run the code in base R using just pain or urinary severity as my variable it works perfectly. When I ask it to adapt based on user input from variable_choice, it gives me that error message. Do I have to use ggplot when trying to run user inputs?

Upvotes: 0

Views: 264

Answers (2)

swisher679
swisher679

Reputation: 23

Thank you. Starja is right. I have a more in depth code for choices based on user selections that I felt would bog down the original question so I simplified it by just writing df, but I should have said colnames(df), you're right. The boxplot works perfectly, but the point returns an NA value and the error says "argument is not numeric or logical: returning NA" and the point does not show up on the graph.

My solution to this was to use colMeans and define it in the server like so...

SERVER:

col_mean <- colMeans(filtered_data()[1:908], na.rm = TRUE)
points(col_mean[input$variable_choice], 1, col = "red")

I created col_mean to grab the first 908 numeric columns in my dataset and convert it to a one mean point in a new dataset. I then used that new dataset in points which gave me the correct mean display for each.

Upvotes: 1

starja
starja

Reputation: 10365

Your code has several issues:

  • the choices argument should only take a vector of column names, try choices = colnames(df)
  • the plot functions either need a formula (however I couldn't make it work without a grouping variable) or the data itself. Try:
output$boxplot <- renderPlot({
boxplot(df[input$variable_choice], 
        main = "", xlab=input$variable_choice, ylab = "", horizontal = TRUE)

points(mean(df[input$variable_choice], na.rm = TRUE), 
       1, 
       col = "red")

  })

In this way, you use the character input$variable_choice to index your data.frame

Upvotes: 1

Related Questions