Explore the World's Most Nutritious Foods with Shiny

Nutritious Foods

A recent study by food scientists titled “Uncovering the Nutritional Landscape of Food” ranked the world’s healthiest foods, focusing on options which will help fulfill, but not exceed, your daily nutritional requirements. In this context, foods which are nutritionally well-rounded and adaptable to a variety of diets rate out highly, while more “one sided” foods slip down the rankings.

Luckily for us, the researchers also published the data they used for the study, allowing us to view and manipulate the information. I’ve built a tool using R and Shiny to get a quick-and-dirty look at the data, so that users can quickly and easily see the healthiest options available when looking for protein, fat, or carb-centric foods.

The Code

Part of the reason I wanted to look into this data was also to get a start using the Shiny package in R - Shiny is an awesome tool for interactive graphics and visualizations. I’ve included my Shiny app below for anyone looking to build a similar tool… the code is a little rough, but it was a great learning experience!

library(shiny)
library(dplyr)

# Read data file
library(readxl)
Nutrition <- read_excel("Nutrition.xlsx")

# Define UI for dataset viewer app ----
ui <- fluidPage(
  
  # App title ----
  titlePanel("The World's Most Nutritious Foods"),
  
  # Sidebar layout with a input and output definitions ----
  sidebarLayout(
    
    # Sidebar panel for inputs ----
    sidebarPanel(
      
      # Input: Selector for choosing dataset ----
      selectInput(inputId = "category",
                  label = "Choose a food category:",
                  choices = c("All", "Protein-rich", "Fat-rich", "Carbohydrate-rich")),
      
      # Input: Variable to filter by ----
      selectInput(inputId = "sort",
                  label = "Select variable to sort by",
                  choices = c("Nutrition Score", "Price")),
      
      # Input: Number of observations to view ----
      sliderInput(inputId = "obs",
                  label = "Number of observations to view:",
                  min = 0, max = 50,
                  value = 10)
      
    ),
    
    # Main panel for displaying outputs ----
    mainPanel(
      
      # Output: Verbatim text for data summary ----
      verbatimTextOutput("summary"),
      
      # Output: HTML table with requested number of observations ----
      tableOutput("view")
      
    )
  )
)

# Define server logic to summarize and view selected dataset ----
server <- function(input, output) {
  
  # Return the requested dataset ----
  categoryInput <- reactive({
    switch(input$category,
           "All" = c("Protein-rich", "Fat-rich", "Carbohydrate-rich"),
           "Protein-rich" = "Protein-rich",
           "Fat-rich" = "Fat-rich",
           "Carbohydrate-rich" = "Carbohydrate-rich"
           )
  })
  
  # Return the variable to be sorted by
  sortSelector <- reactive({
    switch(input$sort,
           "Nutrition Score" = "Nutritional_Fitness",
           "Price" = "Price_Per_100g")
  })
  
  # Generate a summary of the dataset ----
  output$summary <- renderPrint({
    new_dataset <- Nutrition %>% filter(Category == categoryInput())
    new_dataset <- new_dataset %>% select(Nutritional_Fitness, Price_Per_100g)
    summary(new_dataset)
  })
  
  # Show the first "n" observations ----
  output$view <- renderTable({
    new_dataset <- Nutrition %>% filter(Category == categoryInput()) 
    new_dataset <- new_dataset %>% select(Name, Nutritional_Fitness, Price_Per_100g)
    new_dataset <- new_dataset %>% arrange(desc(get(sortSelector())))
    head(new_dataset, n = input$obs)
  })
}

shinyApp(ui, server)