I am relatively new to R and currently, I am trying to build a simple Shiny app.
I believe that the input is good, however, my output does not seem to work properly.
My app should allow users to select the number of ingredients they want to use and the output should give all the names of the recipes with that specific number of ingredients.
How can I connect the input to the desired output?
ui <- fluidPage(
titlePanel("Foodify"),
#Input
selectInput("number_of_ingredients", "How many ingredients would you like to use?",
choices = c(dt.ingredients.and.directions.recipe$dt.number.of.ingredients), selected = 5, selectize = TRUE),
mainPanel(textOutput("ingredients")
))
server <- function(input, output){
ingredients.data <- reactive({as.data.frame(dt.ingredients.and.directions.recipe)})
recipes <- reactive(ingredients.data()[which(row.names(ingredients.data()) == input$number_of_ingredients),])
output$ingredients <- renderPrint({ingredients.data()$Recipe_name})
}
shinyApp(ui = ui, server = server)
I think you could simplify your app.
You had your recipe data as reactive
- does it need to be? If you have your data already present in a data frame, you can filter that in either a separate reactive
block or in your output
.
Here is a brief example that simplifies things (filtering your data frame in the output
). If your input
changes (different number of recipes) the text output will automatically update.
Will this meet your needs?
dt.ingredients.and.directions.recipe <- data.frame(
dt.number.of.ingredients = c(1,2,3),
Recipe_name = c("First", "Second", "Third"),
stringsAsFactors = F
)
ui <- fluidPage(
titlePanel("Foodify"),
#Input
selectInput("number_of_ingredients", "How many ingredients would you like to use?",
choices = unique(dt.ingredients.and.directions.recipe$dt.number.of.ingredients),
selected = 1,
selectize = TRUE),
mainPanel(textOutput("ingredients")
)
)
server <- function(input, output){
output$ingredients <- renderPrint({
dt.ingredients.and.directions.recipe[dt.ingredients.and.directions.recipe$dt.number.of.ingredients == input$number_of_ingredients, "Recipe_name"]
})
}
shinyApp(ui = ui, server = server)
If you want to use a separate reactive
block to filter you can also do the following:
server <- function(input, output){
recipes <- reactive({
dt.ingredients.and.directions.recipe[dt.ingredients.and.directions.recipe$dt.number.of.ingredients == input$number_of_ingredients,]
})
output$ingredients <- renderPrint({
recipes()$Recipe_name
})
}
Edit (3/1/20) :
There is flexibility in how your recipe results can appear. Right now, this was using renderPrint
which just captures any print output and converts it to a string.
There are a number of alternative ways to show your data. One way is to use renderTable
instead (and in your ui
replace with tableOutput
instead of textOutput
. Also would take a look at the DT
package in shiny.
This will display the recipe results in a single column:
library(shiny)
dt.ingredients.and.directions.recipe <- data.frame(
dt.number.of.ingredients = c(7,2,7,8,6),
Recipe_name = c("Jam Toaster Tarts", "Oven-Dried Strawberries", "Fried Whole Fish", "Veggie Italian Hoagies", "Buttered Tomatoes with Ginger"),
stringsAsFactors = F
)
ui <- fluidPage(
titlePanel("Foodify"),
#Input
selectInput("number_of_ingredients", "How many ingredients would you like to use?",
choices = sort(unique(dt.ingredients.and.directions.recipe$dt.number.of.ingredients)),
selected = 1,
selectize = TRUE),
mainPanel(tableOutput("ingredients")
)
)
server <- function(input, output){
output$ingredients <- renderTable({
data.frame(Recipe = dt.ingredients.and.directions.recipe[dt.ingredients.and.directions.recipe$dt.number.of.ingredients == input$number_of_ingredients, "Recipe_name"])
})
}
shinyApp(ui = ui, server = server)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.