Two Way Analytics with R Shiny and Pokemon
By: Marshall Krassenstein
Tags: Data Science, R, Analytics, Data Visualization, Shiny

We now have a chart with some basic filtering and tooltips. So far, we’ve done nothing outside what is easily possible in typical BI visualization tools. To make our app different, we can start by doing some basic database operations. For one, I have a lot of Pokemon I like, they are near and dear to my heart from many hours of childhood gameboy games. It would be interesting if I could build in some functionality for users to submit their favorite Pokemon.

Submitting data will not be challenging. First we’ll add a submit button to the UI in the side bar and a paragraph tag as a message for users.

# Include in the UI side panel

p("If this is one of your favorite Pokemon, press submit below"),

actionButton('submit', "Submit Favorite")

Then we’ll add an event handler for clicking the action button to the server function.

# Include in server. Writes to poke_survey table after the user presses submit

observeEvent(input$submit, {

submit_date <- as.character(Sys.time())

df <- data.frame(generation = input$poke_gen,

pokemon_name = input$pokemon_name,

submit_date = submit_date) # Append data to existing table if exists

dbWriteTable(con, 'poke_survey', df, append=T)

})

I’ll submit a couple of names, and then go back to the DB Browser to look at the results.

DB Browser results from clicking the submit button

Boom, in just a few lines of code, we have user submitted data. If you can do that on Tableau outside of using a lot of custom javascript, feel free to reach out to me and let me know. And as we can see in the image above, I also capture the exact date of the submission, which suggests we can write in any data at our disposal when a user clicks submit.

Unfortunately, as I wrote that last paragraph and admired the picture of our new submission table, I realized that I like Sudowoodo, but I don’t know if it’s one of my favorite Pokemon. In addition, it would have been nice to confirm with the user before saving the data. Finally, after 7+ generations of Pokemon, I’m not sure I even remember what they all look like anymore.

Let’s deal with my memory problems first. It turns out someone made another post on Kaggle including images of all the Pokemon (https://www.kaggle.com/vishalsubbiah/pokemon-images-and-types). Besides the exciting notion that bigger nerds than me exist, this dataset also allows an image of the selected Pokemon pop up in the application with surprisingly little code.

# Include in the UI side panel

imageOutput("pokemon_image", inline = T) # Server piece

output$pokemon_image <- renderImage({

req(input$pokemon_name)

# filename is ./images/`pokemon_name`.png

# Won't work with the .jpg images which I should fix at some point

filename <- normalizePath(file.path('./images',

paste(tolower(input$pokemon_name), '.png', sep='')))



# Return a list containing the filename

list(src = filename)

}, deleteFile = FALSE)

And now we have images pop up when we select a Pokemon as in the example below:

I actually do love Ducklett because it feels like it spawned in a moment when the creators had a mental lapse, and said ‘screw it, let’s just make a duck Pokemon and call it ‘Ducklett’. Like, it’s just a blue-ish duck. I could go outside my house and find a closely related animal right now.

Anyway, before I reveal to the world how much I love Ducklett, I want to give myself a chance to confirm I love it. Below, I use Dean Atali’s fabulous ‘shinyalerts’ package to make a confirmation dialog popup.

# Submit button pop up

observeEvent(input$submit, {

results <- shinyalert(

title = "Submit Pokemon?",

text = sprintf("Click Confirm to submit %s as one of your favorites",input$pokemon_name),

closeOnEsc = TRUE,

closeOnClickOutside = TRUE,

html = TRUE,

type = "warning",

showConfirmButton = TRUE,

showCancelButton = TRUE,

confirmButtonText = "Submit",

confirmButtonCol = "#539BBD",

cancelButtonText = "Cancel",

inputId = 'submission_alert',

callbackR = function(value) {if(input$submission_alert){shinyalert("Congratulations! You submitted something")}}

)

})



observeEvent(input$submission_alert, {

if (input$submission_alert) {

submit_date <- as.character(Sys.time())

df <- data.frame(generation = input$poke_gen,

pokemon_name = input$pokemon_name,

submit_date = submit_date)

dbWriteTable(con, 'poke_survey', df, append=T)

}

})

Shinyalert confirm submission modal

Beautiful. At this point we have an application that shows information and ingests information. But we can’t actually see what was submitted. To deal with that, I’m going to create a new tab that will display some summaries of the information. First, I need to make a navigation bar. And while I’m doing that, I may as well format my dashboard by adding an icon, making use of the ‘shinythemes’ package, and adding a border around my plot. This will change the UI function in a lot of places so I have the complete UI code below: