Jeremy Pastore
Jeremy Pastore

Reputation: 343

cannot coerce type 'closure' to vector of type 'character'

I am trying to build an interactive scatter-plot using shiny. Using the iris data, I would like to have a user select the x and y dimensions of a scatter plot *petal vs sepal) and then output a simple scatter plot of the selected dimensions. Pretty straightforward.

First I needed to build a function that allows me to pass strings representing the dimensions to ggplot. I did this and tested it with static data. Works fine.

Next I define two dropdowns and two subsequent strings (using shiny) for petal and sepal dimensions (these are my x and y axis).

I next set the two string variables using shiny's reactive() function using a switch statement.

This appears to be where things go wrong.

The error I get is: Error: cannot coerce type 'closure' to vector of type 'character'

I've taken a number of steps to debug my code. I first plugged in hard coded dimensions (e.g. "Petal.Length") into the final line of my code output$myplot = renderPlot({myplotfunct( ...

This works great. The plot renders as I expect it to.

I then added a debug line to track the value of the string I am passing this plot function. Bingo. It's empty. Why is it empty?? Seems like it should be passed a value from the UI.r file.

Code is below.

Any help would be greatly appreciated. Thanks!

UI.R

library(shiny)

# Define UI for dataset viewer application
shinyUI(fluidPage(

# Application title
titlePanel("Shiny Text"),

# Sidebar with controls to select a dataset and specify the
# number of observations to view
sidebarLayout(
  sidebarPanel(
    selectInput("dataset1", "Choose a Sepal Measure:", 
              choices = c("Sepal Length", "Sepal Width")),

    selectInput("dataset2", "Choose a Petal Measure:", 
              choices = c("Petal Length", "Petal Width"))
 ),

 # Main Scatter Plot
 mainPanel(

   textOutput("testvar"),

   plotOutput("myplot")
   )
  )
))

Server.R

library(shiny)
library(datasets)

library(ggplot2)

#Define a function to plot passed string variables in ggplot

myplotfunct = function(df, x_string, y_string) {
  ggplot(df, aes_string(x = x_string, y = y_string)) + geom_point()
}

shinyServer(function(input, output) {

# Sepal Inputs
datasetInput1 <- reactive({
  switch(input$dataset1,
       "Sepal Length" = "Sepal.Length",
       "Sepal Width" = "Sepal.Width")
})

# Petal Inputs
datasetInput2 <- reactive({
  switch(input$dataset2,
       "Petal Length" = "Petal.Length",
       "Petal Width" = "Petal.Width")
})

#Debug print value of sting being passed
output$testvar = renderText(print(datasetInput1))

# Plot
output$myplot = renderPlot({myplotfunct(iris, datasetInput1, datasetInput2)})

})

Upvotes: 34

Views: 180361

Answers (1)

faidherbard
faidherbard

Reputation: 1035

The call to datasetInput1 and datasetInput2 in the two last lines is the reason of the error.

You should instead call datasetInput1() and datasetInput2(). Otherwise R tries to convert the function to char. It should be:

#Debug print value of sting being passed
output$testvar = renderText(print(datasetInput1()))

# Plot
output$myplot = renderPlot({myplotfunct(iris, datasetInput1(), datasetInput2())})

The () allows you to get the value of the reactive element rather than interact with the reactive element itself. This is a pretty fundamental concept with Shiny and if that's not something you are yet familiar yet, perhaps revisit the shiny tutorial.

Just by adding the (), the error disappears as you can see below:

enter image description here

Upvotes: 37

Related Questions