web application development with r using shiny · is the author of web application development with...

322

Upload: others

Post on 28-Mar-2020

4 views

Category:

Documents


1 download

TRANSCRIPT

Page 1: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present
Page 2: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

WebApplicationDevelopmentwithRUsingShinyThirdEdition

Buildstunninggraphicsandinteractivedatavisualizationstodelivercutting-edgeanalytics

ChrisBeeleyShitalkumarR.Sukhdeve

Page 3: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

BIRMINGHAM-MUMBAI

Page 4: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

WebApplicationDevelopmentwithRUsingShinyThirdEditionCopyright©2018PacktPublishing

Allrightsreserved.Nopartofthisbookmaybereproduced,storedinaretrievalsystem,ortransmittedinanyformorbyanymeans,withoutthepriorwrittenpermissionofthepublisher,exceptinthecaseofbriefquotationsembeddedincriticalarticlesorreviews.

Everyefforthasbeenmadeinthepreparationofthisbooktoensuretheaccuracyoftheinformationpresented.However,theinformationcontainedinthisbookissoldwithoutwarranty,eitherexpressorimplied.Neithertheauthors,norPacktPublishingoritsdealersanddistributors,willbeheldliableforanydamagescausedorallegedtohavebeencauseddirectlyorindirectlybythisbook.

PacktPublishinghasendeavoredtoprovidetrademarkinformationaboutallofthecompaniesandproductsmentionedinthisbookbytheappropriateuseofcapitals.However,PacktPublishingcannotguaranteetheaccuracyofthisinformation.

AcquisitionEditor:DevanshiDoshiContentDevelopmentEditor:AishwaryaGawankarTechnicalEditor:RutujaVazeCopyEditor:SafisEditingProjectCoordinator:SheejalShahProofreader:SafisEditingIndexer:PratikShirodkarGraphics:AlishonMendonsaProductionCoordinator:ArvindkumarGupta

Firstpublished:October2013Secondpublished:January2016Thirdedition:September2018

Productionreference:1260918

PublishedbyPacktPublishingLtd.LiveryPlace35LiveryStreetBirminghamB32PB,UK.

ISBN978-1-78899-312-8

www.packtpub.com

Page 5: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

mapt.io

Maptisanonlinedigitallibrarythatgivesyoufullaccesstoover5,000booksandvideos,aswellasindustryleadingtoolstohelpyouplanyourpersonaldevelopmentandadvanceyourcareer.Formoreinformation,pleasevisitourwebsite.

Page 6: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Whysubscribe?SpendlesstimelearningandmoretimecodingwithpracticaleBooksandVideosfromover4,000industryprofessionals

ImproveyourlearningwithSkillPlansbuiltespeciallyforyou

GetafreeeBookorvideoeverymonth

Maptisfullysearchable

Copyandpaste,print,andbookmarkcontent

Page 7: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Packt.comDidyouknowthatPacktofferseBookversionsofeverybookpublished,withPDFandePubfilesavailable?YoucanupgradetotheeBookversionatwww.packt.comandasaprintbookcustomer,youareentitledtoadiscountontheeBookcopy.Getintouchwithusatcustomercare@packtpub.comformoredetails.

Atwww.packt.com,youcanalsoreadacollectionoffreetechnicalarticles,signupforarangeoffreenewsletters,andreceiveexclusivediscountsandoffersonPacktbooksandeBooks.

Page 8: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Contributors

Page 9: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AbouttheauthorsChrisBeeleyhasbeenusingRandotheropensourcesoftwarefortenyearstobettercapture,analyze,andvisualizedatainthehealthcaresectorintheUK.HeistheauthorofWebApplicationDevelopmentwithRUsingShiny.Heworksfull-time,developingsoftwaretostore,collate,andpresentquestionnairedatausingopentechnologies(MySQL,PHP,R,andShiny),withaparticularemphasisonusingthewebandShinytoproducesimpleandattractivedatasummaries.ChrisisworkinghardtoincreasetheuseofRandShiny,bothwithinhisownorganizationandthroughouttherestofthehealthcaresector,aswelltoenablehisorganizationtobetteruseavarietyofotherdatasciencetools.ChrishasalsodeliveredtalksaboutShinyalloverthecountry.

ShitalkumarR.SukhdeveisaseniordatascientistatPTSmartfrenTelecomTbk,Jakarta,Indonesia.Onhiscareerjourney,hehasworkedwithRelianceJioasadatascientist,entrepreneur,andcorporatetrainer.Hehastrainedover1,000professionalsandstudentsandhasdeliveredover200lecturesonRandmachinelearning.ResearchanddevelopmentinAI-drivenself-optimizingnetworks,predictivemaintenance,optimalnetworkquality,anomalydetection,andcustomerexperiencemanagementfor4GLTEnetworksareallareasofinteresttoShitalkumar.HeisveryexperiencedwithR,Spark,RShiny,H2O,Python,KNIME,theHadoopecosystem,MapReduce,Hive,andconfiguringtheopensourceRShinyserverformachinelearningmodelsanddashboarddeployment.

Iwouldliketothankmyfather,Mr.RajendraSukhdeve;mother,Mrs.ManjuSukhdeve;wife,Sandika;family;andfriendsforalwaysbelievinginmeandallowingmetodevotetimetowritingthisbook.MyspecialthankstoMr.NikolaSucevic,Mr.BhupeshDaheria,andMr.PramodKolhatkarforgivingmeanopportunitytoworkwiththemandexploredatascience.ThankstoPacktPublishingandteamfortheircontinuoussupportandguidance.

Page 10: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AboutthereviewerAbhinavAgrawalhasmorethan13years'ITexperienceandhasworkedwithtopconsultingfirmsandUSfinancialinstitutions.Hisexpertiseliesinthebankingandfinancialservicesdomainandheisaseasonedproject/programmanagementprofessionalwithapassionfordataanalytics,machinelearning,artificialintelligence,roboticsprocessautomation,digitaltransformation,andemergingdigitalpaymentssolutions.HestartedusingRandShinyin2014todevelopweb-basedanalyticssolutionsforclients.HeworksasaprogrammanagerandisafreelanceRinstructorandRShinyconsultant.Inhissparetime,helovestomentordatasciencestudents,makedataanalytics-relatedinstructionalvideosonYouTube,andshareknowledgewiththecommunity.

Page 11: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

PacktissearchingforauthorslikeyouIfyou'reinterestedinbecominganauthorforPackt,pleasevisitauthors.packtpub.comandapplytoday.Wehaveworkedwiththousandsofdevelopersandtechprofessionals,justlikeyou,tohelpthemsharetheirinsightwiththeglobaltechcommunity.Youcanmakeageneralapplication,applyforaspecifichottopicthatwearerecruitinganauthorfor,orsubmityourownidea.

Page 12: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

TableofContentsTitlePage

CopyrightandCredits

WebApplicationDevelopmentwithRUsingShinyThirdEdition

www.PacktPub.com

Whysubscribe?

Packt.com

Contributors

Abouttheauthors

Aboutthereviewer

Packtissearchingforauthorslikeyou

Preface

Whothisbookisfor

Whatthisbookcovers

Togetthemostoutofthisbook

Downloadtheexamplecodefiles

Downloadthecolorimages

Conventionsused

Getintouch

Reviews

1. BeginningRandShinyInstallingR

TheRconsole

CodeeditorsandIDEs

LearningR

Gettinghelp

Loadingdata

Datatypesandstructures

Dataframes,lists,arrays,andmatrices

Variabletypes

Functions

Objects

Basegraphicsandggplot2

Barchart

Linechart

Introductiontothetidyverse

Cecin'estpasunepipe

Gapminder

AsimpleShiny-enabledlineplot

Page 13: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

InstallingShinyandrunningtheexamples

Summary

2. ShinyFirstStepsTypesofShinyapplication

InteractiveShinydocumentsinRMarkdown

AminimalexampleofafullShinyapplication

Theui.Roftheminimalexample

AnoteonHTMLhelperfunctions

Thefinishedinterface

Theserver.Roftheminimalexample

Theprogramstructure

Anoptionalexercise

Embeddingapplicationsindocuments

Widgettypes

TheGapminderapplication

TheUI

Dataprocessing

Reactiveobjects

Outputs

Textsummary

Trendgraphs

Amapusingleaflet

Advancedlayoutfeatures

Summary

3. IntegratingShinywithHTMLRunningtheapplicationsandcode

ShinyandHTML

CustomHTMLlinksinShiny

ui.R

server.R

AminimalHTMLinterface

index.html

server.R

IncludingaShinyapponawebpage

HTMLtemplates

Inlinetemplatecode

server.R

ui.Randtemplate.html

Definingcodeintheui.Rfile

ui.R

Takeastepbackandrewind

Exercise

Debugging

Bootstrap3andShiny

Page 14: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Summary

4. MasteringShiny'sUIFunctionsShiny'slayoutfunctions

Simple

Complete

Doityourself

Combininglayoutfunctions

StreamliningtheUIbyhidingelements

NamingtabPanelelements

BeautifultableswithDataTable

Reactiveuserinterfaces

Thereactiveuserinterfaceexample– server.R

Thereactiveuserinterfaceexample– ui.R

Progressbars

Progressbarwithshinycssloaders

Modals

AlternativeShinydesigns

Summary

5. EasyJavaScriptandCustomJavaScriptFunctionsJavaScriptandShiny

Example1– readingandwritingtheDOM

ui.R

appendText.js

Example2 –sendingmessagesbetweenclientandserver

ui.R

server.R

dropdownDepend.js

Shinyjs

Extendshinyjs

ui.R

server.R

JavaScript

RespondingtoeventsinJavaScript

htmlwidgets

Dygraphs

rCharts

d3heatmap

threejs

Summary

6. DashboardsApplicationsinthischapter

Flexdashboards

Page 15: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Sidebarapplicationwithextrastyling

AddingiconstoyourUI

Usingshinythemes

Usingthegridlayout

ui.R

Fulldashboard

Notifications

Infoboxes

ui.R

GoogleChartsgauge

ResizingtheGooglechart

ui.R

Summary

7. PowerShinyAnimation

ReadingclientinformationandGETrequestsinShiny

CustominterfacesfromGETstrings

Downloadinggraphicsandreports

Downloadablereportswithknitr

Downloadinganduploadingdata

Bookmarking

Bookmarkingstate

EncodingthestateintoaURL

Single-fileapplication

Multiple-fileapplication

Bookmarkingbysavingthestatetotheserver

Interactiveplots

Interactivetables

Rowselection

Columnselection

CellSelection

Linkinginteractivewidgets

Shinygadgets

Addingapassword

Summary

8. CodePatternsinShinyApplicationsReactivityinRShiny

Acloserlookatreactivity

Controllingspecificinputwiththeisolate()function

Runningreactivefunctionsovertime(executionscheduling)

Event-handlingusingobserveEventandeventReactive

Functionsandmodules

Shinytest

Page 16: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Debugging

Handlingerrors(includingvalidate()andreq())

Validate

Handlingmissinginputwithreq()

ProfilingRcode

Debounceandthrottle

Summary

9. PersistentStorageandSharingShinyApplicationsSharingoverGitHub

AnintroductiontoGit

UsingGitandGitHubwithinRstudio

ProjectsinRStudio(h3)

SharingapplicationsusingGit

Sharingusing.zipand.tar

Sharingwiththeworld

Shinyapps.io

Shinyapps.iowithoutRStudio

Shinyserver

RunningShinyapponAmazonAWS

Scoping,loading,andreusingdatainShinyapplications

Temporarydatainput/output

Persistentdatastorage

DatabaseusingDplyr,DBI,andPOOL

SQLInjection

Summary

OtherBooksYouMayEnjoy

Leaveareview-letotherreadersknowwhatyouthink

Page 17: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

PrefaceWiththisbook,youwillbeabletoharnessthegraphicalandstatisticalpowerofRandrapidlydevelopinteractiveandengaginguserinterfacesusingthesuperbShinypackage,whichmakesprogrammingforuserinteractionsimple.Risahighlyflexibleandpowerfultoolusedforanalyzingandvisualizingdata.ShinyistheperfectcompaniontoR,makingitquickandsimpletoshareanalysisandgraphicsfromRforuserstotheninteractwithandqueryovertheweb.LetShinydothehardworkwhileyouspendyourtimegeneratingcontentandstyling,ratherthanwritingcodetohandleuserinputs.Thisbookisfullofpracticalexamplesandshowsyouhowtowritecutting-edgeinteractivecontentfortheweb,rightfromaminimalexampleallthewaytofullystyledandextensibleapplications.

ThisbookincludesanintroductiontoShinyandRandtakesyouallthewaytoadvancedfunctionsinShinyaswellasusingShinyinconjunctionwithHTML,CSS,andJavaScripttoproduceattractiveandhighlyinteractiveapplicationsquicklyandeasily.ItalsoincludesadetailedlookatotherpackagesavailableforR,whichcanbeusedinconjunctionwithShinytoproducedashboards,maps,advancedD3graphics,andmuchmore.

Page 18: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

WhothisbookisforThisbookisforanybodywhowantstoproduceinteractivedatasummariesovertheweb,whetheryouwanttosharethemwithafewcolleaguesorthewholeworld.

Page 19: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

WhatthisbookcoversChapter1,BeginningRandShiny,runsthroughthebasicsofstatisticalgraphics,datainput,andanalysiswithR.WealsodiscussdatastructuresandprogrammingbasicsinRinordertogiveyouathoroughgroundinginRbeforewelookatShiny.

Chapter2,ShinyFirstSteps,helpsyoubuildyourfirstShinyapplication.WebeginbysimplyaddinginteractivecontenttoadocumentwritteninMarkdown;andthendelvedeeperintoShiny,buildingaveryprimitiveandminimalexample;andfinally,we'lllookatmorecomplexapplicationsandtheinputsandoutputsnecessarytobuildthem.

Chapter3,IntegratingShinywithHTML,covershowShinyworkswithexistingwebcontentinHTMLandCSS.WediscusstheShinyhelperfunctionsthatallowyoutoaddacustomHTMLtoastandardShinyapplicationandhowtobuildaminimalexampleofaShinyapplicationinyourownrawHTMLwithShinyrunninginthebackground.We'llalsogetintotheuseofHTMLtemplates,whichmakeintegratingShinywithHTMLeasy.

Chapter4,MasteringShiny'sUIFunctions,describesallthedifferentwaysthatShinyofferstohelpyouachievethelayoutandappearancethatyouwantyourapplicationtohave.Itdiscusseshowtoshowandhideelementsoftheinterface,aswellashowtomaketheinterfacereacttothestateoftheapplication.Producingattractivedatatablesisdiscussed,aswellashowtogiveyourusersmessageswithprogressbarsandmodals.

Chapter5,EasyJavaScriptandCustomJavaScriptFunctions,coversusingJavaScriptwithShiny,rightfromaddingsimpleJavaScriptrightonthepagetoenhanceaprogram'sappearanceorfunctionality,tosendingmessagestoandfromtheclient'sbrowserusingmessagestoandfromJavaScript.Theuseoftheshinyjsandhtmlwidgetspackagesisalsodiscussed,whichfurtheraddtoyourabilitytoaddcustomorcannedJavaScripttoaShinyapplication.

Chapter6,Dashboards,includesacoupleofdifferenttypesofShinydashboard,anddescribeshowtomakeattractiveShinydashboards,usingcolor,icons,anda

Page 20: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

widerangeofinputsandoutputs,aswellashowtolaythemoutusingtheveryflexiblelayoutfunctions,whichcanbeaccessedwithaShinydashboard.

Chapter7,PowerShiny,includesmanypowerfulfeaturesofShiny,suchasanimatingplots,readingclientinformation,andGETrequestsinShiny.Wewillgothroughgraphicsandreportgenerationandhowtodownloadthemusingknitr.Downloadinganduploadingisalsoaninterestingpartofanyapplication,andwe'lltakealookatitinShinywithsomeexamples.Bookmarkingthestateoftheapplicationisanadd-ontoregeneratetheoutputontheapplication.Wewillseeademonstrationoffastapplicationdevelopmentusingwidgetsandgadgets.Attheendofthechapter,wewillseehowtoauthenticatetheapplicationusingapassword.

Chapter8,CodePatternsinShinyApplications,coversthecodingpatternsavailableinShiny.WewilldiscussreactivityinRShiny,controllingspecificinputwiththeisolate()function,runningreactivefunctionsovertime,eventhandlingusingtheobserveEventfunctionsandtheShinytestmodules,debugging,handlingerrors(includingvalidate()andreq()),profilingRcode,debounce,andthrottle.

Chapter9,PersistentStorageandSharingShinyApplications,willexplorehowtokeepyourcodeonGitHub.ThischapterwillincludeanintroductiontoGitHubandhowtointegrateGitwithRStudio.WewillalsolearnhowtoshareyourreportsandaliveapplicationwithShinyapps.io.Thischapterwillalsofocusonthedeploymentoptionsavailable,suchasShinyServerandrunningShinyinAWS.WewillgothroughsomeoftheconceptsthatarevitalfordevelopingagoodShinyapplication,suchasscoping,loading,andreusingdatainShinyapplications.We'llalsolookattemporarydatainput/output,permanentdatafunctions,databases,SQLinjection,anddatabaseswiththepoolpackage.

Page 21: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

TogetthemostoutofthisbookNopreviousexperiencewithR,Shiny,HTML,orCSSisrequiredtousethisbook,althoughyoushouldpossesssomepreviousexperiencewithprogramminginadifferentlanguage.ThisbookcanbeusedwiththeWindows,macOS,orLinuxoperatingsystems.ItrequirestheinstallationofRaswellasseveraluser-contributedpackageswithinR.Randitsassociatedpackagesareallavailableforfree.TheRStudioIDEisrecommendedbecauseitsimplifiessomeofthetaskscoveredinthisbook,butisnotessential.Again,thissoftwareisavailablefreeofcharge.

Page 22: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DownloadtheexamplecodefilesYoucandownloadtheexamplecodefilesforthisbookfromyouraccountatwww.packt.com.Ifyoupurchasedthisbookelsewhere,youcanvisitwww.packt.com/supportandregistertohavethefilesemaileddirectlytoyou.

Youcandownloadthecodefilesbyfollowingthesesteps:

1. Loginorregisteratwww.packt.com.2. SelecttheSUPPORTtab.3. ClickonCodeDownloads&Errata.4. EnterthenameofthebookintheSearchboxandfollowtheonscreen

instructions.

Oncethefileisdownloaded,pleasemakesurethatyouunziporextractthefolderusingthelatestversionof:

WinRAR/7-ZipforWindowsZipeg/iZip/UnRarXforMac7-Zip/PeaZipforLinux

ThecodebundleforthebookisalsohostedonGitHubathttps://github.com/PacktPublishing/Web-Application-Development-with-R-Using-Shiny-third-edition.Incasethere'sanupdatetothecode,itwillbeupdatedontheexistingGitHubrepository.

Wealsohaveothercodebundlesfromourrichcatalogofbooksandvideosavailableathttps://github.com/PacktPublishing/.Checkthemout!

Page 23: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DownloadthecolorimagesWealsoprovideaPDFfilethathascolorimagesofthescreenshots/diagramsusedinthisbook.Youcandownloadithere:https://www.packtpub.com/sites/default/files/downloads/9781788993128_ColorImages.pdf.

Page 24: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ConventionsusedThereareanumberoftextconventionsusedthroughoutthisbook.

CodeInText:Indicatescodewordsintext,databasetablenames,foldernames,filenames,fileextensions,pathnames,dummyURLs,userinput,andTwitterhandles.Hereisanexample:"The[1]phrasetellsyouthatRreturnedoneresult;inthiscase,4."

Ablockofcodeissetasfollows:

<ul>

<li>Firstbullet</li>

<li>Secondbullet</li>

<li>Thirdbullet</li>

</ul>

Whenwewishtodrawyourattentiontoaparticularpartofacodeblock,therelevantlinesoritemsaresetinbold:

tabsetPanel(id="theTabs",

tabPanel("Summary",textOutput("summary"),

value="summary"),

tabPanel("Trend",plotOutput("trend"),

value="trend"),

tabPanel("Map",leafletOutput("map"),

p("Mapdataisfromthemostrecentyearintheselectedrange"),

value="map")

)

Anycommand-lineinputoroutputiswrittenasfollows:

>2+2

[1]4

Bold:Indicatesanewterm,animportantword,orwordsthatyouseeonscreen.Forexample,wordsinmenusordialogboxesappearinthetextlikethis.Hereisanexample:"Tosetupanewproject,gotoFile|NewProjectinRStudio."

Warningsorimportantnotesappearlikethis.

Tipsandtricksappearlikethis.

Page 25: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

GetintouchFeedbackfromourreadersisalwayswelcome.

Generalfeedback:Ifyouhavequestionsaboutanyaspectofthisbook,mentionthebooktitleinthesubjectofyourmessageandemailusatcustomercare@packtpub.com.

Errata:Althoughwehavetakeneverycaretoensuretheaccuracyofourcontent,mistakesdohappen.Ifyouhavefoundamistakeinthisbook,wewouldbegratefulifyouwouldreportthistous.Pleasevisitwww.packt.com/submit-errata,selectingyourbook,clickingontheErrataSubmissionFormlink,andenteringthedetails.

Piracy:IfyoucomeacrossanyillegalcopiesofourworksinanyformontheInternet,wewouldbegratefulifyouwouldprovideuswiththelocationaddressorwebsitename.Pleasecontactusatcopyright@packt.comwithalinktothematerial.

Ifyouareinterestedinbecominganauthor:Ifthereisatopicthatyouhaveexpertiseinandyouareinterestedineitherwritingorcontributingtoabook,pleasevisitauthors.packtpub.com.

Page 26: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ReviewsPleaseleaveareview.Onceyouhavereadandusedthisbook,whynotleaveareviewonthesitethatyoupurchaseditfrom?Potentialreaderscanthenseeanduseyourunbiasedopiniontomakepurchasedecisions,weatPacktcanunderstandwhatyouthinkaboutourproducts,andourauthorscanseeyourfeedbackontheirbook.Thankyou!

FormoreinformationaboutPackt,pleasevisitpackt.com.

Page 27: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

BeginningRandShinyRisfreeandopensource,andisthepre-eminenttoolforstatisticiansanddatascientists.Ithasmorethan6,000user-contributedpackages,whichhelpusersworkinginfieldsasdiverseaschemistry,biology,physics,finance,psychology,andmedicalscience.R'sextremelypowerfulandflexiblestatisticalgraphicsgreatlyhelptheseusersintheirwork.

Inrecentyears,Rhasbecomemoreandmorepopular,andthereareanincreasingnumberofpackagesforRthatmakecleaning,analyzing,andpresentingdataonthewebeasyforeverybody.TheShinypackageinparticularmakesitincrediblyeasytodeliverinteractivedatasummariesandqueriestoendusersthroughanymodernwebbrowser.You'rereadingthisbookbecauseyouwanttousethesepowerfulandflexibletoolsforyourowncontent.

Thisbookwillshowyouhow,rightfromwhenyoujuststartwithR,youcanbuildyourowninterfaceswithShinyandintegratethemwithyourownwebsites.Inthischapter,we'regoingtocoverthefollowingtopics:

DownloadingandinstallingRChoosingacode-editingenvironment/IDELookingatthepowerofRLearningabouthowRStudioandcontributedpackagescanmakewritingcode,managingprojects,andworkingwithdataeasierInstallingShinyandrunningtheexamplesHowtousesomeofShiny'sawesomeapplications,andsomeoftheelementsoftheShinyapplicationthatwewillbuildoverthecourseofthisbook

Risabigsubject,andthisisawhistle-stoptour,soifyougetalittlelostalongtheway,don'tworry.Thischapterisreallyallaboutshowingyouwhat'soutthere,andwillbothencourageyoutodelvedeeperintothebitsthatinterestyouandshowyouplacesyoucangoforhelpifyouwanttolearnmoreonaparticularsubject.

Page 28: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

InstallingRRisavailableforWindows,MacOSX,andLinuxatcran.r-project.org.Thesourcecodeisalsoavailableatthesameaddress.ItisalsoincludedinmanyLinuxpackagemanagementsystems;Linuxusersareadvisedtocheckbeforedownloadingfromtheweb.DetailsoninstallingfromsourceorbinaryforWindows,MacOSX,andLinuxareallavailableatcran.r-project.org/doc/manuals/R-admin.html.

Page 29: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

TheRconsoleWindowsandMacOSXuserscanruntheRapplicationtolaunchtheRconsole.LinuxandMacOSXuserscanalsoruntheRconsolestraightfromtheTerminalbytypingR.

Ineithercase,theRconsoleitselfwilllooksomethinglikethefollowingscreenshot:

RwillrespondtoyourcommandsrightfromtheTerminal.Let'shaveago.RunthefollowingcommandintheRconsole:

>2+2

[1]4

The[1]phrasetellsyouthatRreturnedoneresult,inthiscase,4.ThefollowingcommandshowsyouhowtoprintHelloworld:

Page 30: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

>print("Helloworld!")

[1]"Helloworld!"

Thefollowingcommandshowsthemultiplesofpi:

>1:10*pi

[1]3.1415936.2831859.42477812.56637115.70796318.849556

[7]21.99114925.13274128.27433431.415927

Thisexampleillustratesvector-basedprogramminginR.The1:10phrasegeneratesthenumbers1:10asavector,andeachisthenmultipliedbypi,whichreturnsanothervector,theelementseachbeingpitimeslargerthantheoriginal.OperatingonvectorsisanimportantpartofwritingsimpleandefficientRcode.Asyoucansee,Ragainindexesthevaluesitreturnsattheconsole,withtheseventhvaluebeing21.99.

OneofthebigstrengthsofusingRisthegraphicscapability,whichisexcellent,eveninavanillainstallationofR(thesegraphicsarereferredtoasthebasegraphicsbecausetheyshipwithR).Whenaddingpackagessuchasggplot2andsomeoftheJavaScript-basedpackages,Rbecomesagraphicaltourdeforce,whetherproducingstatistical,mathematical,ortopographicalfigures,orindeedanyothertypeofgraphicaloutput.Togetaflavorofthepowerofthebasegraphics,simplytypethefollowingintheConsoleandseethetypesofplotsthatcanbemadeusingR:

>demo(graphics)

Youcanalsotypethefollowingcommand:

>demo(persp)

Therewillbemoreonggplot2andbasegraphicslaterinthechapter.

Enjoy!TherearemanymoreexamplesofRgraphicsatr-graph-gallery.com.

Page 31: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

CodeeditorsandIDEsTheWindowsandOSXversionsofRbothcomewithbuilt-incodeeditors,whichallowcodetobeedited,saved,andsenttotheRconsole.It'shardtorecommendthatyouusethisbecauseitisratherprimitive.MostuserswouldbebestservedbyRStudio(foundatrstudio.com/),whichincludesprojectmanagementandversioncontrol(includingsupportforGit,whichiscoveredinChapter9,PersistentStorageandSharingShinyApplications),theviewingofdataandgraphics,codecompletion,packagemanagement,andmanyotherfeatures.ThefollowingisanillustrativescreenshotofanRStudiosession:

Ascanbeseen,inthetop-leftcorner,thereisthecode-editingpane(withsyntaxhighlighting).Movingclockwisefromtherewilltakeyoutotheenvironmentpane(inwhichyoucanseethedifferentobjectsthatareloadedintothesession),whichistheviewingpanecontainingvariousoptionssuchasFiles,Plots,Build,Help,andfinally,atthebottomleft,theConsole.Inthemiddle,thereisoneofthemostusefulfeaturesofRStudio,theabilitytoviewdataframes.ThisviewcanbecreatedbyclickingadataframeintheEnvironmentpanelatthetopright.

Page 32: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Thisfunctionalsoenablessortingandfilteringbycolumn.

However,ifyoualreadyuseanIDEforothertypesofcode,itisquitelikelythatRcanbewellintegratedintoit.ExamplesofIDEswithgoodRintegrationincludethefollowing:

EmacswiththeEmacsSpeaksStatisticspluginVimwiththeVim-RpluginEclipsewiththeStatETplugin

Page 33: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

LearningRTherearealmostasmanyusesforRastherearepeopleusingit.Itisnotpossiblethatyourspecificneedswillbecoveredinthisbook.However,youprobablywanttouseRtoprocess,query,andvisualizedata,suchassalesfigures,satisfactionsurveys,concurrentusers,sportingresults,orwhatevertypesofdatayourorganizationprocesses.Fornow,let'sjusttakealookatthebasics.

Page 34: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

GettinghelpTherearemanybooksandonlinematerialsthatcoverallaspectsofR.ThenameRcanmakeitdifficulttocomeupwithusefulwebsearchhits(substitutingCRANforRcansometimeshelp);nonetheless,searchingforRtutorialbringsupusefulresults.Someusefulresourcesincludethefollowing:

AnexcellentintroductiontosyntaxanddatastructuresinR(atgoo.gl/M0RQ5z)VideosonusingRfromGoogle(atgoo.gl/A3uRsh)Swirl(atswirlstats.com)Quick-R(atstatmethods.net)

AttheRconsole,thecodephrase?functionnamecanbeusedtoshowthehelpfileforafunction.Forexample,?helpbringsuphelpmaterials,andusing??helpwillbringupalistofpotentiallyrelevantfunctionsfrominstalledpackages.

SubscribingtoandaskingquestionsontheR-helpmailinglistatstat.ethz.ch/mailman/listinfo/r-helpallowsyoutocommunicatewithsomeoftheleadingfiguresintheRcommunity,aswellasmanyothertalentedenthusiasts.Readthepostingguideanddoyourresearchbeforeyouaskanyquestions,becauseit'sabusyandsometimesunforgivinglist.

TherearetwoStackExchangecommunitiesthatcanprovidefurtherhelpatstats.stackexchange.com/(forquestionsaboutstatisticsandvisualizationwithR)andstackoverflow.com/(forquestionsaboutprogrammingwithR).

TherearemanywaystolearnRandrelatedsubjectsonline;RStudiohasaveryusefullistontheirwebsiteatgoo.gl/8tX7FP.

Page 35: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

LoadingdataThesimplestwayofloadingdataintoRisprobablyusingacomma-separatedvalue(.csv)spreadsheetfile,whichcanbedownloadedfrommanydatasourcesandloadedandsavedinallspreadsheetsoftware(suchasExcelorLibreOffice).Theread.table()commandimportsdataofthistypebyspecifyingtheseparatorasacomma,orusingread.csv(),afunctionspecificallyfor.csvfiles,asshowninthefollowingcommand:

>analyticsData=read.table("~/example.csv",sep=",")

Otherwise,youcanusethefollowingcommand:

>analyticsData=read.csv("~/example.csv")

Notethatunlikeotherlanguages,Ruses<-forassignmentaswellas=.Assignmentcanbemadetheotherwayusing->.Theresultofthisisthatycanbetoldtoholdthevalueof4inay<-4or4->yformat.Therearesomeother,moreadvancedthingsthatcanbedonewithassignmentinR,butdon'tworryaboutthemnow.Inthisbook,Iwillpreferthe=operator,sinceIusethisinmyowncode.Justbeawareofbothmethodssothatyoucanunderstandthecodeyoucomeacrossinforumsandblogposts.

Eitheroftheprecedingcodeexampleswillassignthecontentsoftheexample.csvfiletoadataframenamedanalyticsData,withthefirstrowofthespreadsheetprovidingthevariablenames.AdataframeisaspecialtypeofobjectinR,whichisdesignedtobeusefulforthestorageandanalysisofdata.

RStudiowilleventakecareofloading.csvfilesforyou,ifyouclickontheminthefileselectorpane(inthebottomrightbydefault)andselectImportdataset....Thiscanbeusefultohelpyougetstarted,butasyougetmoreconfidentit'sreallybettertodoeverythingwithcoderatherthanpointingandclicking.RStudiowill,toitsgreatcredit,showyouthecodethatmakesyourpointingandclickingwork,sotakeanoteofitanduseittoloadthedatathenexttimeyourself.

Page 36: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DatatypesandstructuresTherearemanydatatypesandstructuresofdatawithinR.ThefollowingtopicssummarizesomeofthemaintypesandstructuresthatyouwillusewhenbuildingShinyapplications.

Page 37: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Dataframes,lists,arrays,andmatricesDataframeshaveseveralimportantfeaturesthatmakethemusefulfordataanalysis:

Rectangulardatastructures,withthetypicalusebeingcases(forexample,thedaysinonemonth)listeddowntherowsandvariables(pageviews,uniquevisitors,orreferrers)listedalongthecolumnsAmixofdatatypesissupported.Atypicaldataframemightincludevariablescontainingdates,numbers(integersorfloats),andtextWithsubsettingandvariableextraction,Rprovidesalotofbuilt-infunctionalitytoselectrowsandvariableswithinadataframeManyfunctionsincludeadataargument,whichmakesitverysimpletopassdataframesintofunctionsandprocessonlythevariablesandcasesthatarerelevant,whichmakesforcleanerandsimplercode

Wecaninspectthefirstfewrowsofthedataframeusingthehead(analyticsData)command.Thefollowingscreenshotshowstheoutputofthiscommand:

Asyoucansee,therearefourvariableswithinthedataframe:onecontainsdates,twocontainintegervariables,andonecontainsanumericvariable.

Page 38: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Variablescanbeextractedfromdataframesverysimplyusingthe$operator,asfollows:

>analyticsData$pageViews

[1]836676940689647899934718776570651816

[13]731604627946634990994599657642894983

[25]646540756989965821

Variablescanalsobeextractedfromdataframesusing[],asshowninthefollowingcommand:

>analyticsData[,"pageViews"]

Notetheuseofacommawithnothingbeforeittoindicatethatallrowsarerequired.Ingeneral,dataframescanbeaccessedusingdataObject[x,y],withxbeingthenumber(s)orname(s)oftherowsrequiredandybeingthenumber(s)orname(s)ofthecolumnsrequired.Forexample,ifthefirst10rowswererequiredfromthepageViewscolumn,itcouldbeachievedlikethis:

>analyticsData[1:10,"pageViews"]

[1]836676940689647899934718776570

Leavingthespacebeforethecommablankreturnsallrows,andleavingthespaceafterthecommablankreturnsallvariables.Forexample,thefollowingcommandreturnsthefirstthreerowsofallvariables:

>analyticsData[1:3,]

Thefollowingscreenshotshowstheoutputofthiscommand:

Dataframesareaspecialtypeoflist.Listscanholdmanydifferenttypesofdata,includinglists.AswithmanydatatypesinR,theirelementscanbenamed,whichcanbeusefultowritecodethatiseasytounderstand.Let'smakealistoftheoptionsfordinner,withdrinkquantitiesexpressedinmilliliters.

Page 39: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Inthefollowingexample,pleasealsonotetheuseofthec()function,whichisusedtoproducevectorsandlistsbygivingtheirelementsseparatedbycommas.Rwillpickanappropriateclassforthereturnvalue,stringforvectorsthatcontainstrings,numericforthosethatonlycontainnumbers,logicalforBooleanvalues,andsoon:

>dinnerList<-list("Vegetables"=

c("Potatoes","Cabbage","Carrots"),

"Dessert"=c("Icecream","Applepie"),

"Drinks"=c(250,330,500)

)

Notethatcodeisindentedthroughout,althoughenteringcodedirectlyintotheconsolewillnotproduceindentations;itisdoneforreadability.

Indexingissimilartodataframes(whichare,afterall,justaspecialinstanceofalist).Theycanbeindexedbynumber,asshowninthefollowingcommand:

>dinnerList[1:2]

$Vegetables

[1]"Potatoes""Cabbage""Carrots"

$Dessert

[1]"Icecream""Applepie"

Thisreturnsalist.Returninganobjectoftheappropriateclassisachievedusing[[]]:

>dinnerList[[3]]

[1]250330500

Inthiscase,anumericvectorisreturned.Theycanalsobeindexedbyname,asshowninthefollowingcode:

>dinnerList["Drinks"]

$Drinks

[1]250330500

Notethatthisalsoreturnsalist.

Matricesandarrays,which,unlikedataframes,onlyholdonetypeofdata,alsomakeuseofsquarebracketsforindexing,withanalyticsMatrix[,3:6]returningallrowsofthethirdtosixthcolumns,analyticsMatrix[1,3]returningjustthefirstrowofthethirdcolumn,andanalyticsArray[1,2,]returningthefirstrowofthesecondcolumnacrossalloftheelementswithinthethirddimension.

Page 40: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

VariabletypesRisadynamicallytypedlanguage,andyouarenotrequiredtodeclarethetypeofyourvariableswhenusingit.Ofcourse,itisworthknowingaboutthedifferenttypesofvariablethatyoumightreadorwriteusingR.Thedifferenttypesofvariablecanbestoredinavarietyofstructures,suchasvectors,matrices,anddataframes,althoughsomerestrictionsapplyasmentionedpreviously(forexample,matricesmustcontainonlyonevariabletype).Thefollowingbulletlistcontainsthespecificsofusingthesevariabletypes:

Declaringavariablewithatleastonestringinitwillproduceavectorofstrings(inR,thecharacterdatatype),asshowninthefollowingcode:

>c("First","Third",4,"Second")

[1]"First""Third""4""Second"

Youwillnoticethatthenumeral4isconvertedtoastring,"4".Thisisasaresultofcoercion,inwhichelementsofadatastructureareconvertedtootherdatatypesinordertofitwithinthetypesthatareallowedwithinthedatastructure.Coercionoccursautomatically,asinthiscase,orwithanexplicitcalltotheas()function—forexample,as.numeric(),oras.Date().

Declaringavariablethatcontainsonlynumberswillproduceanumericvector,asshowninthefollowingcode:

>c(15,10,20,11,0.4,-4)

[1]15.010.020.011.00.4-4.0

R,ofcourse,alsoincludesalogicaldatatype,asshowninthefollowingcode:

>c(TRUE,FALSE,TRUE,TRUE,FALSE)

[1]TRUEFALSETRUETRUEFALSE

Adatatypeexistsfordates,whichareoftenasourceofproblemsforbeginners,asshowninthefollowingcode:

>as.Date(c("2013/10/24","2012/12/05","2011/09/02"))

[1]"2013-10-24""2012-12-05""2011-09-02"

Page 41: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

TheuseofthefactordatatypetellsRallofthepossiblevaluesofacategoricalvariable,suchasgenderorspecies,asshowninthefollowingcode:

>factor(c("Male","Female","Female","Male","Male"),

levels=c("Female","Male"))

[1]MaleFemaleFemaleMaleMale

Levels:FemaleMale

Page 42: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

FunctionsAsyougrowinconfidencewithR,youwillwanttobeginwritingyourownfunctions.Thisisachievedverysimply,andinamannerquitesimilartomanyotherlanguages.YouwillnodoubtwanttoreadmoreaboutwritingfunctionsinRinmoredetail,butjusttogiveyouanidea,thefollowingcodeisafunctioncalledthesumMultiplyfunctionthataddstogetherxandyandmultipliestheresultbyz:

sumMultiply<-function(x,y,z){

final=(x+y)*z

return(final)

}

ThisfunctioncannowbecalledusingsumMultiply(2,3,6),whichwillreturn2plus3times6,whichgives30.

Page 43: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ObjectsTherearemanyspecialobjecttypeswithinRthataredesignedtomakeiteasiertoanalyzedata.FunctionsinRcanbepolymorphic—thatistosay,theycanrespondtodifferentdatatypesindifferentwaysinordertoproducetheoutputthattheuserdesires.Forexample,theplot()functioninRrespondstoawidevarietyofdatatypesandobjects,includingsingle-dimensionvectors(eachvalueofyplottedsequentially)andtwo-dimensionalmatrices(producingascatterplot),aswellasspecializedstatisticalobjects,suchasregressionmodelsandtimeseriesdata.Inthelattercase,plotsthatarespecializedforthesepurposesareproduced.

Aswiththerestofthisintroduction,don'tworryifyouhaven'twrittenfunctionsbefore,ordon'tunderstandobjectconceptsandaren'tsurewhatthisallmeans.Youcanproducegreatapplicationswithoutunderstandingallthesethings,butasyoudomoreandmorewithR,youwillstarttowanttolearnmoredetailsabouthowRworksandhowexpertsproduceRcode.Thisintroductionisdesignedtogiveyouajumping-offpointtolearnmoreabouthowtogetthebestoutofR(andShiny).

Page 44: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Basegraphicsandggplot2Therearelotsofuser-contributedgraphicspackagesinRthatcanproducesomewonderfulgraphics.YoumaywishtotakealookforyourselfattheCRANtaskviewatcran.r-project.org/web/views/Graphics.html.Wewillhaveaveryquicklookattwoapproaches:basegraphics,socalledbecausetheyformthedefaultgraphicalenvironmentwithinavanillainstallationofR,andggplot2,ahighlypopularuser-contributedpackageproducedbyHadleyWickham,whichisalittletrickiertomasterthanbasegraphics,butcanveryrapidlyproduceawiderangeofgraphicaldatasummaries.Wewillcovertwographsthatarefamiliartoeveryone:thebarchartandthelinechart.

Page 45: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

BarchartUsefulwhencomparingquantitiesacrosscategories,barchartsareverysimpleinbasegraphics,particularlywhencombinedwiththetable()command.Wewillusethempgdataset,whichcomeswiththeggplot2package;itsummarizesthedifferentcharacteristicsofarangeofcars.First,let'sinstalltheggplot2package.Youcandothisstraightfromtheconsoleusingthefollowingcode:

>install.packages("ggplot2")

Alternatively,youcanusethebuilt-inpackagefunctionsinIDEssuchasRStudioorRKWard.We'llneedtoloadthepackageatthebeginningofeachsessioninwhichwewanttousethisdataset,orintheggplot2packageitself.Fromtheconsole,typethefollowingcommand:

>library(ggplot2)

Wewillusethetable()commandtocountthenumberofeachtypeofcarfeaturedinthedataset,asshowninthefollowingcode:

>table(mpg$class)

Thisreturnsatableobject(anotherspecialobjecttypewithinR)thatcontainsthecolumnsshowninthefollowingscreenshot:

Producingabarchartofthisobjectisachievedsimplyusingthefollowingcode:

>barplot(table(mpg$class),main="Basegraphics")

Thebarplotfunctiontakesavectoroffrequencies.Wheretheyarenamed,asisthecaseinourexample(thetable()commandreturningnamedfrequenciesin

Page 46: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

tableform),namesareautomaticallyincludedonthexaxis.Thedefaultsforthisgraphareratherplain.Explore?barplotand?partolearnmoreaboutfine-tuningyourgraphics.

We'vealreadyloadedtheggplot2packageinordertousethempgdataset,butifyouhaveshutdownRinbetweenthesetwoexamples,youwillneedtoreloaditbyusingthefollowingcommand:

>library(ggplot2)

Thesamegraphisproducedinggplot2asfollows:

>ggplot(data=mpg,aes(x=class))+geom_bar()+

ggtitle("ggplot2")

Thisggplotcallshowsthethreefundamentalelementsofggplotcalls:theuseofadataframe(data=mpg);thesetupofaesthetics(aes(x=class)),whichdetermineshowvariablesaremappedontoaxes,colors,andothervisualfeatures;andtheuseof+geom_xxx().Aggplotcallsetsupthedataandaesthetics,butdoesnotplotanything.Functionssuchasgeom_bar()(therearemanyothers;see??geom)tellggplotwhattypeofgraphtoplot,aswellasinstructingittotakeoptionalarguments—forexample,geom_bar()optionallytakesapositionargument,whichdefineswhetherthebarsshouldbestacked,offset,orstretchedtoacommonheighttoshowproportionsinsteadoffrequencies.

Theseelementsarethekeytothepowerandflexibilitythatggplot2offers.Oncethedatastructureisdefined,waysofvisualizingthatdatastructurecanbeaddedandtakenawayeasily,notonlyintermsofthetypeofgraphic(bar,line,orscattergraph)butalsothescalesandcoordinatessystem(log10,polarcoordinates,andsoon)andstatisticaltransformations(smoothingdata,summarizingoverspatialcoordinates,andsoon).Theappearanceofplotscanbeeasilychangedwithpresetanduser-definedthemes,andmultipleplotscanbeaddedinlayers(thatis,addingthemtooneplot)orfacets(thatis,drawingmultipleplotswithonefunctioncall).

Thebasegraphicsandggplotversionsofthebarchartareshowninthefollowingscreenshotforthepurposesofcomparison:

Page 47: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present
Page 48: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

LinechartLinechartsaremostoftenusedtoindicatechange,particularlyovertime.Thistime,wewillusethelongleydataset,featuringeconomicvariablesfrombetween1947and1962,asshowninthefollowingcode:

>plot(x=1947:1962,y=longley$GNP,type="l",

xlab="Year",main="Basegraphics")

Thexaxisisgivenverysimplybythe1947:1962phrase,whichenumeratesallthenumbersbetween1947and1962,andthetype="l"argumentspecifiestheplottingofthelines,asopposedtopointsorboth.

Theggplotcalllooksalotlikethebarchart,exceptwithanxandydimensionintheaestheticsthistime.Thecommandlooksasfollows:

>ggplot(longley,aes(x=1947:1962,y=GNP))+geom_line()+

xlab("Year")+ggtitle("ggplot2")

Page 49: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

IntroductiontothetidyverseThetidyverseis,accordingtoitshomepage,"anopinionatedcollectionofRpackagesdesignedfordatascience"(seehttps://www.tidyverse.org/).Allofthepackagesareinstalledusinginstall.packages("tidyverse"),andcallinglibrary(tidyverse)loadsasubsetofthesepackages,thoseconsideredtohavethemostvalueinday-to-daydatascience.Callinglibrary(tidyverse)loadsthefollowingpackages:

ggplot2:Forplottingdplyr:Fordatawranglingtidyr:Fortidying(anduntidying!)datareadr:Betterfunctionsforreadingcomma-andtab-delimiteddataandothertypesofflatfilespurrr:Foriteratingtibble:Betterdataframesstringr:Fordealingwithstringsforcats:Betterhandlingoffactors,anRpropertyusedtodescribethecategoriesofavariable,describedbrieflyearlierinthechapter

Installingthetidyversealsoinstallsthefollowingpackages,whichthenneedtobeloadedseparatelywiththeirownlibrary()instruction:readxl,haven,jsonlite,xml2,httr,rvest,DBI,lubridate,hms,blob,rlang,magrittr,glue,andbroom.Formoredetailsonthesepackages,consultthedocumentationattidyverse.org/.

Thekeywordinthisdescriptionisopinionated.ThetidyverseisasetofRpackagesthatworkwithtidydata,eitherproducingit,orconsumingit,orboth.TidydatawasdescribedbyHadleyWickhamintheJournalofStatisticalSoftware,Vol59,Issue10(https://www.jstatsoft.org/article/view/v059i10/v59i10.pdf).Tidydataobeysthreeprinciples:

EachvariableformsacolumnEachobservationformsarowEachtypeofobservationalunitformsatable

FormanyRusers,theirfirstintroductiontotidydatawillhavebeenggplot2,

Page 50: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

whichconsumestidydataandrequiresothertypesofdatatobemungedintothisform.Inordertoexplainwhatthismeans,wewilllookatasimpleexample.Forthepurposesofthisdiscussion,wewillignorethelastprinciple,whichismoreaboutorganizinggroupsofdatasetsratherthanindividualdatasets.

Let'shavealookatasimpleexampleofamessydataset.Intherealworld,youwillfinddatasetsthatarealotmessierthanthis,butthiswillservetoillustratetheprinciplesweareusinghere.ThefollowingarethefirstthreerowsofthemedaltableforthePyeongchangWinterOlympics,whichtookplacein2018,asanRdataframe:

medals=data.frame(country=c("Norway","Germany","Canada"),

gold=c(14,14,11),

silver=c(14,10,8),

bronze=c(11,7,10)

)

Ifweprintitattheconsole,itlookslikethefollowingscreenshot:

Thisisperhapsthemostcommonsortofmessydatayouwillcomeacross:greatasasummary,certainlyintelligibletopeoplewatchingtheWinterOlympics,butnottidy.Therearemedalsinthreedifferentcolumns.Atidydatasetwouldcontainonlyonecolumnforthemedaltallies.Let'stidyitupusingthetidyrpackage,whichisloadedwithlibrary(tidyverse),oryoucanloaditseparatelywithlibrary(tidyr).Wecantidythedataverysimplyusingthegather()function.Thegather()functiontakesadataframeasanargument,alongwithkeyandvaluecolumnnames(whichyoucansettowhatyoulike),andthecolumnnamesthatyouwishtobegathered(allothercolumnswillbeduplicatedasappropriate).Inthiscase,wewanttogathereverythingexceptthecountry,sowecanuse-variableNametoindicatethatwewishtogathereverythingexceptvariableName.Thefinalcodelookslikethefollowing:

library(tidyr)

gather(medals,key=Type,value=Medals,-country)

Page 51: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Thishasanicetidyoutput,asshowninthefollowingscreenshot:

Page 52: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Cecin'estpasunepipeNowthatwe'vecoveredtidydata,thereisonemoreconceptthatisverycommoninthetidyversethatweshoulddiscuss.Thisisthepipe(%>%)fromthemagrittrpackage.ThisissimilartotheUnixpipe,andittakestheleft-handsideofthepipeandappliestheright-handsidefunctiontoit.Takethefollowingcode:

mpg%>%summary()

Theprecedingcodeisequivalenttothefollowingcode:

summary(mpg)

Asanotherexample,lookatthefollowingcode:

gapminder%>%filter(year>1960)

Theprecedingcodeisequivalenttothefollowingcode:

filter(gapminder,year>1960)

Pipinggreatlyenhancesthereadabilityofcodethatrequiresseveralstepstoexecute.Takethefollowingcode:

x%>%f%>%g%>%h

Theprecedingcodeisequivalenttothefollowingcode:

h(g(f(x)))

Todemonstratewitharealexample,takethefollowingcode:

groupedData=gapminder%>%

filter(year>1960)%>%

group_by(continent,year)%>%

summarise(meanLife=mean(lifeExp))

Theprecedingcodeisequivalenttothefollowingcode:

summarise(

group_by(

filter(gapminder,year>1960),

Page 53: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

continent,year),

meanLife=mean(lifeExp))

Hopefully,itshouldbeobviouswhichistheeasiertoreadofthetwo.

Page 54: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

GapminderNowwe'velookedattidyingdata,let'shaveaquicklookatusingdplyrandggplottofilter,process,andplotsomedata.Inthissection,andthroughoutthisbook,we'regoingtobeusingtheGapminderdatathatwasmadefamousbyHansRoslingandtheGapminderfoundation.Anexcerptofthisdataisavailablefromthegapminderpackage,asassembledbyJennyBryan,anditcanbeinstalledandloadedverysimplyusinginstall.packages("gapminder");library(gapminder).Asthepackagedescriptionindicates,itincludes,foreachofthe142countriesthatareincluded,thevaluesforlifeexpectancy,GDPpercapita,andpopulation,everyfiveyears,from1952to2007.

Inordertopreparethedataforplotting,wewillmakeuseofdplyr,asshowninthefollowingcode:

groupedData=gapminder%>%

filter(year>1960)%>%

group_by(continent,year)%>%

summarise(meanLife=mean(lifeExp))

Thissingleblockofcode,allexecutedinoneline,producesadataframesuitableforplotting,anduseschainingtoenhancethesimplicityofthecode.Threeseparatedataoperations,filter(),group_by(),andsummarise(),areallused,withtheresultsfromeachbeingsenttothenextinstructionusingthe%>%operator.Thethreeinstructionscarryoutthefollowingtasks:

filter():Thisissimilartosubset().Thisoperationonlykeepsrowsthatmeetcertainrequirements—inthiscase,yearsbeyond1960.group_by():Thisallowsoperationstobecarriedoutonsubsetsofdatapoints—inthiscase,eachcontinentforeachoftheyearswithinthedataset.summarise():Thiscarriesoutsummaryfunctions,suchassumandmean,onseveraldatapoints—inthiscasethemeanlifeexpectancywithineachcontinentandavailableyear.

So,tosummarize,theprecedingcodefiltersthedatatoselectonlyyearsbeyond1960,groupsitbythecontinentandyear,andfindsthemeanlifeexpectancywithinthatcontinentoryear.Printingtheoutputfromtheprecedingcodeyieldsthefollowing:

Page 55: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Asyoucansee,theoutputisatibble,whichhasaniceprintmethodthatonlyprintsthefirstseveralrows.Tibblesareverysimilartodataframes,andareoftenproducedbydefaultinsteadofdataframeswithinthetidyverse.Therearesomenicedifferences,buttheyarefairlyinterchangeablewithdataframesforourpurposes,sowewillnotgetsidetrackedbythedifferenceshere.

Nowwehavementionedtibbles,youcanseethatthedataframeisanicesummaryofthemeanlifeexpectancybyyearandcontinent.

Page 56: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AsimpleShiny-enabledlineplotWehavealreadyseenhoweasyitistodrawlineplotsinggplot2.Let'saddsomeShinymagictoalineplotnow.ThiscanbeachievedveryeasilyindeedinRStudiobyjustnavigatingtoFile|NewFile|RMarkdown|NewShinydocumentandinstallingthedependencieswhenprompted.Onceatitlehasbeenadded,thiswillcreateanewRMarkdowndocumentwithinteractiveShinyelements.RMarkdownisanextensionofMarkdown(seedaringfireball.net/projects/markdown/),whichisitselfamarkuplanguage,suchasHTMLorLaTeX,whichisdesignedtobeeasytouseandread.RMarkdownallowsRcodechunkstoberunwithinaMarkdowndocument,whichrendersthecontentsdynamic.ThereismoreinformationaboutMarkdownandRMarkdowninChapter2,ShinyFirstSteps.ThissectiongivesaveryrapidintroductiontothetypeofresultspossibleusingShiny-enabledRMarkdowndocuments.

FormoredetailsonhowtoruninteractivedocumentsoutsideRStudio,refertogoo.gl/Ngubdo.Bydefault,anewdocumentwillhaveplaceholdercodeinitwhichyoucanruntodemonstratethefunctionality.Wewilladdthefollowing:

---

title:"Gapminder"

author:"ChrisBeeley"

output:html_document

runtime:shiny

---

```{r,echo=FALSE,message=FALSE}

library(tidyverse)

library(gapminder)

inputPanel(

checkboxInput("linear",label="Addtrendline?",value=FALSE)

)

#drawtheplot

renderPlot({

thePlot=gapminder%>%

filter(year>1960)%>%

group_by(continent,year)%>%

summarise(meanLife=mean(lifeExp))%>%

ggplot(aes(x=year,y=meanLife,

group=continent,colour=continent))+

geom_line()

if(input$linear){

Page 57: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

thePlot=thePlot+geom_smooth(method="lm")

}

print(thePlot)

})

```

Thefirstpartbetweenthe---istheYAML,whichperformsthesetupofthedocument.InthecaseofproducingthisdocumentwithinRStudio,thiswillalreadybepopulatedforyou.

Rchunksaremarkedasshown,with```{r}tobeginand```toclose.Theechoandmessageargumentsareoptional—weusethemheretosuppressoutputoftheactualcodeandanymessagesfromRinthefinaldocument.

We'llgointomoredetailabouthowShinyinputsandoutputsaresetuplateroninthebook.Fornow,justknowthattheinputissetupwithacalltocheckboxInput(),which,asthenamesuggests,createsacheckbox.It'sgivenaname("linear")andalabeltodisplaytotheuser("Addtrendline?").Theoutput,beingaplot,iswrappedinrenderPlot().Youcanseethecheckboxvaluebeingaccessedontheif(input$linear){...}line.Shinyinputsarealwaysaccessedwithinput$andthentheirname,so,inthiscase,input$linear.Whentheboxisclicked—thatis,whenitequalsTRUE—wecanseeatrendlinebeingaddedwithgeom_smooth().We'llgointomoredetailabouthowallofthiscodeworkslaterinthebook;thisisafirstlooksothatyoucanstarttoseehowdifferenttasksarecarriedoutusingRandShiny.

You'llhaveaninteractivegraphiconceyourunthedocument(clickonRundocumentinRStudioorusetherun()commandfromthermarkdownpackage),asshowninthefollowingscreenshot:

Page 58: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Asyoucansee,Shinyallowsustoturnonoroffatrendlinecourtesyofgeom_smooth()fromtheggplot2package.

Page 59: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

InstallingShinyandrunningtheexamplesShinycanbeinstalledusingstandardpackagemanagementfunctions,asdescribedpreviously(usingtheGUIorrunninginstall.packages("shiny")attheconsole).

Let'srunsomeoftheexamples,asshowninthefollowingcode:

>library(shiny)

>runExample("01_hello")

Yourwebbrowsershouldlaunchanddisplaythefollowingscreenshot(notethatIclickedontheshowbelowbuttonontheapptobetterfitthegraphiconthepage):

Page 60: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Thegraphshowsthefrequencyofasetofrandomnumbersdrawnfromastatisticaldistributionknownasthenormaldistribution,andthesliderallowsuserstoselectthesizeofthedraw,from0to1,000.Youwillnotethatwhenyoumovetheslider,thegraphupdatesautomatically.ThisisafundamentalfeatureofShiny,whichmakesuseofareactiveprogrammingparadigm.

Thisisatypeofprogrammingthatusesreactiveexpressions,whichkeeptrackofthevaluesonwhichtheyarebased.Thesevaluescanchange(theyareknownasreactivevalues)andupdatethemselveswheneveranyoftheirreactivevalueschange.So,inthisexample,thefunctionthatgeneratestherandomdataanddrawsthegraphisareactiveexpression,andthenumberofrandomdrawsthatitmakesisareactivevalueonwhichtheexpressiondepends.So,wheneverthenumberofdrawschanges,thefunctionre-executes.

Youcanfindmoreinformationaboutthisexample,aswellasacomprehensivetutorialforShiny,atshiny.rstudio.com/tutorial/.

Page 61: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Also,notethelayoutandstyleofthewebpage.ShinyisbasedbydefaultontheBootstraptheme(seegetbootstrap.com/).However,youarenotlimitedbythestylingatall,andcanbuildthewholeUIusingamixofHTML,CSS,andShinycode.

Let'slookataninterfacethatismadewithbare-bonesHTMLandShiny.Notethatinthisandallsubsequentexamples,we'regoingtoassumethatyourunlibrary(shiny)atthebeginningofeachsession.Youdon'thavetorunitbeforeeachexample,exceptatthebeginningofeachRsession.So,ifyouhaveclosedRandhavecomeback,thenrunitontheconsole.Ifyoucan'tremember,runitagaintobesure,asfollows:

library(shiny)

runExample("08_html")

Andhereitis,inallitscustomizableglory:

Page 62: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present
Page 63: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Now,thereareafewdifferentstatisticaldistributionstopickfromandadifferentmethodofselectingthenumberofobservations.Bynow,youshouldbelookingatthewebpageandimaginingallthepossibilitiestherearetoproduceyourowninteractivedatasummariesandstylethemjusthowyouwant,quicklyandsimply.Bytheendofthenextchapter,you'llhavemadeyourownapplicationwiththedefaultUI,andbytheendofthebook,you'llhavecompletecontroloverthestylingandbeponderingwhereelseyoucango.

TherearelotsofotherexamplesincludedwiththeShinylibrary;justtyperunExample()intheconsoletobeprovidedwithalist.

Toseesomereallypowerfulandwell-featuredShinyapplications,takealookattheshowcaseatshiny.rstudio.com/gallery/.

Page 64: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SummaryInthischapter,weinstalledRandexploredthedifferentoptionsforGUIsandIDEs,andlookedatsomeexamplesofthepowerofR.WesawhowRmakesiteasytomanageandreformatdataandproducebeautifulplotswithafewlinesofcode.YoualsolearnedalittleaboutthecodingconventionsanddatastructuresofR.Wesawhowtoformatadatasetandproduceaninteractiveplotinadocumentquicklyandeasily.Finally,weinstalledShiny,rantheexamplesincludedinthepackage,andwereintroducedtoacoupleofbasicconceptsinShiny.

Inthenextchapter,wewillgoontobuildourownShinyapplicationusingthedefaultUI.

Page 65: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ShinyFirstStepsInthepreviouschapter,welookedatR,learnedsomeofitsbasicsyntax,andsawsomeexamplesofthepowerandflexibilitythatRandShinyoffer.ThischapterintroducesthebasicsofShiny.Inthischapter,we'regoingtobuildourownapplicationtointeractivelyexploretheGapminderdatadescribedinthepreviouschapter.Wewillcoverthefollowingtopics:

ThetypesofShinyapplication—RMarkdown,single-file,two-file,ShinygadgetsInteractiveShinydocumentsinRMarkdownSingle-fileShinyapplicationsTwo-fileShinyapplicationsAminimalexampleofafullShinyapplicationWidgettypesThebasicstructureofaShinyprogramTheselectionofsimpleinputwidgets(checkboxesandcombobuttons)Theselectionofsimpleoutputtypes(renderingplotsandmaps,andreturningtext)Theselectionofsimplelayouttypes(pagewithsidebarandtabbedoutputpanel)ReactiveobjectsAbriefsummaryofmoreadvancedlayoutfeatures

Page 66: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

TypesofShinyapplicationInthefirsteditionofthisbook,whichwasbasedonShiny0.6,wedescribedonlytwotypesofapplication.First,afairlysimpleBootstrap-themedinterfacewithinputwidgetsdowntheleftandoutput(asinglepageoratabbedoutputwindow)ontheright.Thesecondtypeconsistedofcustom-builtwebpageswiththeirownHTMLandCSSfiles.Shinyhasdevelopedquiteabitsincethen,andthereareactuallymanytypesofShinyapplicationandmanywaysofbuildingthem.Theseareasfollows:

InteractivemarkdowndocumentswithShinywidgetsembeddedShinyapplications(defaultCSS,writtenentirelyinR)Webpages(forexample,customCSS,HTML,andJavaScript)ShinygadgetsFlexdashboards

Inthischapter,wewillbeconsideringthefirsttwo:interactivedocumentsandfullapplications.Chapter3,IntegratingShinywithHTML,willcoverhowtobuildyourownwebpagescontainingShinyapplications.ShinygadgetsaretoolsforRprogrammersratherthanforendusers,andtheyallowRuserstoexploredataandgenerategraphicsandsummarieswithShinyinterfaces.TheywillbedescribedfurtherinChapter7,PowerShiny.FlexdashboardswillbelookedatinChapter6,Dashboards.

Page 67: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

InteractiveShinydocumentsinRMarkdownAswesawinthepreviouschapter,interactivedocumentscanbemadeveryeasilyusingRMarkdowninRStudio.EvenifyouarenotusingRStudio,itisasimplematterofwritinganRMarkdownfilewithShinycodeinit.IfyoudonotuseRStudio,youwillneedanup-to-dateversionofPandoc(theversioninmanyLinuxdistributionsisnotrecentenough).FormoreoninstallingPandoconLinux,Windows,orMac,gotopandoc.org/installing.html.

RMarkdownisbasedonMarkdown,whichisamarkuplanguagedesignedtobeeasilyconvertedintoHTML,butwhichlooksmuchmorelikeanaturaldocumentinitsrawformat,asopposedtoHTMLorothermarkuplanguages(suchasLaTeX),whichhavemoreprominentandstrange-lookingtags.Forexample,theMarkdownsyntaxforabulletedlistisasfollows:

*Firstbullet

*Secondbullet

*Thirdbullet

TheHTMLequivalentisasfollows:

<ul>

<li>Firstbullet</li>

<li>Secondbullet</li>

<li>Thirdbullet</li>

</ul>

TaggingmarkupinLaTeXisevenmoreverbose.RMarkdownusesMarkdownconventions,butallowscodechunksofRtoberunwithinthedocument,andallowstextandgraphicaloutputtobegeneratedfromthosechunks.CoupledwithPandoc(theSwissArmyknifeofdocumentrendering),MarkdownandRMarkdowncanberenderedintomanyformats,includingXHTML,HTML,epub,LaTeX,.pdf,.doc,.docx,and.odt.

RMarkdownwithShinygoesonestepfurtherandallowsuserstointeractwiththedocumentonawebpage.

Page 68: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Let'sbuildaminimalexample.IfyouareusingRStudio,youwillbegivenaboilerplateShinyMarkdowndocumenttoworkfrom,whichmakesthingsabiteasier,butherewe'llignorethatandbuilditfromscratch.Thecodeisavailableatgoo.gl/N7Qkv8.

Let'sgothrougheachpartofthedocument.NavigatetoFile|NewFile|RMarkdown|Newdocumentandenterthefollowingcode:

#ExampleRMarkdowndocument

Thisisaninteractivedocumentwrittenin*markdown*.Asyoucanseeitiseasytoinclude:

1.Orderedlists

2.*Italics*

3.**Boldtype**

4.Linksto[Documentation](http://example.com/)

##Thisisheadingtwo

Perhapsthisintroducesthevisualisationbelow.

ThisisthedocumentpartoftheShinydocument,writteninMarkdown.Thefollowingconventionscanbenoted:

The#characterisusedforheadingsatlevel1,and##forheadingsatlevel2Numbered(ordered)listsaredesignatedwith1,2,andsoonItalicsaregivenwith*singleasterisks*andaboldformatisgivenwith**doubleasterisks**

Linksarerepresentedusingtheformatof(http://example.com/)

Nextfollowsacodechunk,beginningwith```{r}andendingwith```.Theecho=FALSEargumentisaddedtothechunktopreventtheprintingoftheRcode.Youwillusuallywanttodothis,butnotoneveryoccasion—forexample,whenproducingateachingresource:

```{r,echo=FALSE}sliderInput("sampleSize",label="Sizeofsample",min=10,max=100,value=50,step=1)renderPlot({hist(runif(input$sampleSize))})```

Straightaway,wecanseesomeofthedesignprinciplesinShinyapplications.Wecanseetheseparationofinputcode,sliderInput(),andoutputcode,renderPlot().ThesliderInput()function,asthenamesuggests,definesaninputwidgetthatallowstheusertoselectfromarangeofnumericvalues,inthiscase,between10and100,withastartingvalueof50andastepincreaseof1.TherenderPlot()functionproducesareactiveplotusingwhateverfunctionsitfindswithinitself(inthiscase,thegraphicalfunctionhist(),whichdrawsahistogram).

Page 69: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AswealreadycoveredinChapter1,BeginningRandShiny,reactiveoutputschangewhentheirinputschange.Therunif(n)functionproducesnrandomnumbersbetween0and1(withdefaultarguments).Aswecanseeinthiscase,nisgivenbyinput$sampleSize.InputsareaccessedverysimplyinShinyinthisformat;youcanseethatwenamedtheinputsampleSizewithinthesliderInput()function,whichplacestheselectedvaluefromthewidgetininput$sampleSize(namingitmyInputplacesthevalueininput$myInput).

Therefore,runif()generatesrandomnumbersinthequantityofinput$sampleSize,hist()plotsthemwithahistogram,andrenderPlot({})tellsShinythattheoutputwithinisreactiveandshouldbeupdatedwheneveritsinputs(inthiscase,justinput$sampleSize)change.

Thefinalresultwilllooklikethefollowingscreenshot:

Page 70: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present
Page 71: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

That'sit!YoumadeyourfirstShinyapplication.It'sthateasy.Now,let'sconsiderbuildingfullyfledgedapplications,startingwithaminimalexampleandbuildingupfromthere.

Page 72: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AminimalexampleofafullShinyapplicationThefirstthingtonoteisthatShinyprogramsaretheeasiesttobuildandunderstandusingtwoscripts,whicharekeptwithinthesamefolder.Theyshouldbenamedserver.Randui.R.

Page 73: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Theui.RoftheminimalexampleTheui.RfileisadescriptionoftheUI,andisoftentheshortestandsimplestpartofaShinyapplication.Inthefollowingcode,notetheuseofthe#character,whichmarkslinesofcodeascommentsthatwillnotberun,butwhichareforthebenefitofthehumansproducingthecode:

fluidPage(#Line1

titlePanel("Minimalapplication"),#Line2

sidebarLayout(#Line3

sidebarPanel(#Line4

textInput(inputId="comment",#Line5

label="Saysomething?",#Line6

value=""#Line7

)),#Line8

mainPanel(#Line9

h3("Thisisyousayingit"),#Line10

textOutput("textDisplay")#Line11

)

)

)

Thefollowinglistisanexplanationofeachline:

Line1:FlexiblelayoutfunctionLine2:TitleLine3:Standardinputsonthesidebar;outputsinthemainarealayoutLine4:ThesidebarlayoutfunctionLine5:Givethenameoftheinputelement;thiswillbepassedtoserver.RLine6:ThedisplaylabelforthevariableLine7:TheinitialvalueLine9:TheoutputpanelLine10:ThetitledrawnwiththeHTMLhelperfunctionLine11:TheoutputtextwiththeID,textDisplay,asdefinedinserver.R

TorunaShinyprogramonyourlocalmachine,youjustneedtodothefollowing:

1. Makesurethatserver.Randui.Rareinthesamefolder2. MakethisfolderR'sworkingdirectory(usingthesetwd()command—for

example,setwd("~/shinyFiles/minimalExample"),orwiththeSession>Setworkingdirectorymenuoption)

Page 74: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

3. LoadtheShinypackagewiththelibrary(shiny)command4. TyperunApp()intheconsole(or,inRstudio,clickRunappjustabovethe

codewindow)

UsingrunApp()withthenameofadirectorywithinworksjustaswell—forexample,runApp("~/shinyFiles/minimalExample").SoinsteadofsettingtheworkingdirectorytothelocationofyourapplicationandthenusingrunApp()separately,thewholethingcansimplybecarriedoutinoneinstruction,passingrunApp()inthenameofthedirectorydirectly.Justrememberthatitisadirectoryandnotafilethatyouneedtopointto.

Thefirstinstruction,fluidPage(...,tellsShinythatweareusingafluidpagelayout.ThisisaveryflexiblelayoutfunctionwhosefunctionalitywewillexplorefurtherinChapter4,MasteringShiny'sUIFunctions.Next,thetitleoftheapplicationisdefinedverysimplyusingthetitlePanel()function.Thenfollowsthemainlayoutinstruction;inthiscase,wearegoingtousethesimplestUIlayout,sidebarLayout(),whichplacesinputsontheleft(orright,optionally)andthemainoutputsectioninthemiddle.AlloftheUIelementsaredefinedwithinthesidebarLayout()function.

ThenexttwoinstructionsperformthemainUIsetup,withsidebarPanel()settinguptheapplicationcontrolsandmainPanel()settinguptheoutputarea.ThesidebarPanel()phrasewillusuallycontainalloftheinputwidgets;inthiscase,thereisonlyone:textInput().ThetextInput()widgetisasimplewidgetthatcollectstextfromatextboxthatuserscaninteractwithusingthekeyboard.Theargumentsareprettytypicalamongmostofthewidgets,andareasfollows:

inputId:Thisargumentnamesthevariable,soitcanbereferredtointheserver.Rfilelabel:Thisargumentgivesalabeltoattachtotheinput,sousersknowwhatitdoesvalue:Thisargumentgivestheinitialvaluetothewidgetwhenitissetup;allthewidgetshavesensibledefaultsforthisargument—inthiscase,itisablankstring,""

Whenyoustartout,itcanbeagoodideatospelloutthedefaultargumentsinyourcodeuntilyougetusedtowhichfunctioncontainswhicharguments.Italsomakesyourcodemorereadableandremindsyouwhatthereturnvalueofthe

Page 75: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

functionis(forexample,value=TRUEwouldsuggestaBooleanreturn).

ThefinalfunctionismainPanel(),whichsetsuptheoutputwindow.YoucanseethatIusedoneoftheHTMLhelperfunctionstomakealittletitle,h3("...").Therearemanyofthesehelperfunctionsincluded,andtheyareincrediblyusefulforsituationswhereyoueitherdon'twanttodotoomuchstylingwithHTMLandCSSyourselfordon'tknowhow.Let'sjuststopveryquicklytolookatafewexamples.

Page 76: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AnoteonHTMLhelperfunctionsThereareseveralHTMLhelperfunctionsthataredesignedtogenerateHTMLtogostraightonthepage;type?pintheconsoleforthecompletelist.ThesefunctionsallowyoutomarkuptextinHTMLusingRcode—forexample,h3("Heading3")willproduce<h3>Heading3</h3>,p("Paragraph")willproduce<p>Paragraph</p>,andsoon.

TheHTMLtagsthatwillbeavailableusingthisfunctioninclude<br>,<code>,<div>,<em>,<h1>,<img>,<p>,<pre>,and<span>.Evenmoretagsareavailablethroughtheuseofthetags()function.ThereismoreonShinyandHTMLinChapter3,IntegratingShinywithHTML,andafulllistoftagsandotherhelpisavailableinthedocumentationatshiny.rstudio.com/articles/html-tags.html.

Page 77: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ThefinishedinterfaceTheotherelementthatgoesinmainPanel()isanareatohandlereactivetextthatisgeneratedwithintheserver.Rfile—thatis,acalltotextOutput()withthenameoftheoutputasdefinedinserver.R—inthiscase,textDisplay.

Thefinishedinterfacelookssimilartothefollowingscreenshot:

Ifyou'regettingalittlebitlost,don'tworry.Basically,Shinyisjustsettingupaframeworkofnamedinputandoutputelements;theinputelementsaredefinedinui.Randprocessedbyserver.R,whichthensendsthembacktoui.R,whichknowswheretheyallgoandwhattypesofoutputtheyare.

Page 78: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Theserver.RoftheminimalexampleLet'snowlookatserver.R,whereitshouldallbecomeclear.Lookatthefollowingcode:

function(input,output){#serverisdefinedhereoutput$textDisplay=renderText({#assigntooutput$textDisplay

paste0("Yousaid'",input$comment,#fromtextinput

"'.Thereare",nchar(input$comment),

"charactersinthis.")

})

}

Wedefinethereactivecomponentsoftheapplicationwithinfunction(input,output){...}.Onthewhole,twotypesofthingsgoinhere.Reactiveobjects(forexample,data)aredefined,whicharethenpassedaroundasneeded(forexample,todifferentoutputinstructions),andoutputsaredefined,suchasgraphs.Thissimpleexamplecontainsonlythelatter.We'llseeanexampleofthefirsttypeinthenextexample.

Anoutputelementisdefinednextwithoutput$textDsiplay=renderText({..}).Thisinstructiondoestwobasicthings.First,itgivestheoutputaname(textDisplay)sothatitcanbereferencedinui.R(youcanseeitinthelastpartofui.R).Second,ittellsShinythatthecontentcontainedwithinisreactive(thatis,itwillbeupdatedwhenitsinputschange)andittakestheformoftext.WewillcoveradvancedconceptsinreactiveprogrammingwithShinyinalaterchapter.TherearemanyexcellentillustrationsofreactiveprogrammingattheShinytutorialpages,availableatrstudio.github.io/shiny/tutorial/#reactivity-overview.

Theactualprocessingisverysimpleinthisexample.Inputsarereadfromui.Rbytheuseofinput$...,sotheelementnamedinui.Rascomment(goandhavealookatui.Rnowtofindit)isreferencedwithinput$comment.

Thewholecommandusespaste0()tolinkstringswithnospaces(equivalenttopaste(...,sep="")),picksupthetexttheuserinputtedwithinput$comment,andprintsit,alongwiththenumberofcharacterswithinit(nchar())andsomeexplanatorytext.

That'sit!YourfirstShinyapplicationisready.Thefullcodecanbefoundhere,h

Page 79: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ttps://gist.github.com/ChrisBeeley/4202605cf2e64b4f609e.Usingtheseverysimplebuildingblocks,youcanactuallymakesomereallyusefulandengagingapplications.

Page 80: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

TheprogramstructureSincethefirsteditionofthisbook,asignificantchangehastakenplacewithregardstohowShinyapplicationsarestructured.Anewfeaturehasbeenadded,givingustheabilitytoplacethemallwithinonecodefile.Thisismostusefulwhenbuildingsmalldemonstrationsorexamplesforotherusers,whocanjustpastethewholecodefileintotheconsoleandhavetheapplicationrunautomatically.Inordertomakeuseofthisfunctionality,justcombinethecodefromserver.Randui.R,asshowninthefollowingexample:

library(shiny)

server<-function(input,output){

#contentsofserver.Rfile

}

ui<-fluidPage(#orotherlayoutfunction

#contentsofui.Rfile

)

shinyApp(ui=ui,server=server)

Thisisusefulneitherforlargeapplications,norforthepurposesofexplainingthefunctionsofparticularpartsofcodewithinthisbook,soweshallignoreitfromnowon.Justbeawarethatit'spossible;youmaywellcomeacrossitonforums,andyoumaywishtocontributesomesmallexamplesyourself.

Page 81: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AnoptionalexerciseIfyouwanttohaveapracticebeforewemoveon,taketheexistingcodeandmodifyitsothattheoutputisaplotofauser-definednumberofobservations,withthetextasthetitleoftheplot.Theplotcallshouldlooklikethefollowing:

hist(rnorm(XXXX),main="YYYY")

Intheprecedinglineofcode,XXXXisanumbertakenfromafunctioninui.Rthatyouwilladd(sliderInput()ornumericInput())andYYYYisthetextoutputwealreadyusedintheminimalexample.YouwillalsoneedtomakeuseofrenderPlot();type?renderPlotintheconsoleformoredetails.

Sofarinthischapter,wehavelookedataminimalexampleandlearnedaboutthebasiccommandsthatgointheserver.Randui.Rfiles.Thinkingaboutwhatwe'vedoneintermsofreactivity,theui.Rfiledefinesareactivevalue,input$comment.Theserver.Rfiledefinesareactiveexpression,renderText().Itdependsoninput$comment.

NotethatthisdependenceisdefinedautomaticallybyShiny.TherenderText()expressionusesanoutputfrominput$comment,soShinyautomaticallyconnectsthem.Wheneverinput$commentchanges,renderText()willautomaticallyrunwiththenewvalue.TheoptionalexercisegavetworeactivevaluestotherenderPlot()call,andso,whenevereitherchanges,renderPlot()willbererun.Intherestofthischapter,wewilllookatanapplicationthatusessomeslightlymoreadvancedreactivityconcepts,andbytheendofthebook,wewillhavecoveredallthecapabilitiesthatShinyoffersandwhentousethem.

Page 82: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

EmbeddingapplicationsindocumentsTobrieflyreturntothesubjectofinteractivedocuments,itisworthnotingthatitispossibletoembedentireShinyapplicationswithininteractivedocumentsratherthanhavingtheratherstripped-downfunctionalitythatweembeddedwithinadocumentearlierinthechapter.Justincludealinktothedirectorythatholdstheapplication,likethis:

```{r,echo=FALSE}

shinyAppDir(

"~/myApps/thisApplication",

)

```

Formoreinformationaboutembedding,type?shinyAppintheconsole.

Page 83: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

WidgettypesBeforewemoveontoamoreadvancedapplication,let'shavealookatthemainwidgetsthatyouwillmakeuseofwithinShiny.I'vebuiltaShinyapplicationthatwillshowyouwhattheyalllooklike,aswellastheiroutputsandthetypeofdatatheyreturn.Torunit,justenterthefollowingcommand:

>library(shiny)

runGist(6571951)

Thisisoneoftheseveralbuilt-infunctionsofShinythatallowyoutoruncodehostedontheinternet.DetailsaboutsharingyourowncreationsinotherwaysarediscussedinChapter9,Persistence,Storage,andSharing.Thefinishedapplicationlookslikethefollowingscreenshot:

Page 84: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Youcanseethefunctionnames(checkboxGroupInputandcheckboxInput)asnumberedentriesontheleft-handsideofthepanel;formoredetails,justtype?checkboxGroupInputintotheconsole.

Ifyou'recuriousaboutthecode,it'savailableatgist.github.com/ChrisBeeley/6571951.

Page 85: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

TheGapminderapplicationNowthatwe'vegotthebasics,let'sbuildafullapplication.Beforeweproceed,notethatwewillneedtoinstallafewpackages—tidyverse,gapminder,leaflet,andggmap.EachcanbeinstalledfromCRAN(theofficialRpackagerepository)usingthecodephrasesinstall.packages("tidyverse"),install.packages("gapminder"),andsoon.Wewillnotinstallggmapthisway,though.Atthetimeofwriting,thereisabugintheCRANversion.We'llinstallthedevversioninstead,asshowninthefollowingcode:

install.packages("devtools")

library(devtools)

devtools::install_github("dkahle/ggmap")

Theapplicationisprettysimpletogetusstarted,butitillustratesseveralimportantmethodsandprinciplesinShiny.Itfeaturestabbedoutput,whichallowstheusertoselectdifferentinputsorgroups,whichareeachkeptonaseparatetab.ItfeaturesthestandardShinylayout—thesidebarlayout—withinputsattheleftandoutputsinthemainsection.Thethreetabsgiveatextualsummary,alinegraphshowinglifeexpectancyovertime,andamapwithcirclesscaledtothelifeexpectancyineachcountry.Theapplicationlookslikethefollowingscreenshot:

Page 86: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present
Page 87: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

TheUIIfyoucan,downloadandrunthecodeanddatafromgithub.com/ChrisBeeley/gapminder(thedatagoesinthesamefolderasthecode)soyoucangetanideaofwhateverythingdoes.Ifyouwanttoruntheprogramwithoutcopyingtheactualdataandcodetoyourcomputer(copyingdataandcodeispreferablesothatyoucanplaywithit),justuseanotherfunctiontoshareandrunapplications(wewilldiscussthisinChapter5,EasyJavaScriptandCustomJavaScriptFunctions),asshowninthefollowingcode:

runGitHub("gapminder","ChrisBeeley")

AsinmanyShinyapplications,ui.Risbyfarthesimplerofthetwocodefiles,andisasfollows:

library(shiny)

library(leaflet)

fluidPage(

titlePanel("Gapminder"),

Thefirstthingthatwedoisloadtheleaflet()package.Theleaflet()packageisusedfordrawinginteractivemaps.We'lldiscussitindetaillater.Fornow,justnotethatitisnecessarytoloaditintheUIinordertoaccessaspecialoutputfunctionthatdoesn'texistwithinShiny—leafletOutput().ThewholeinterfaceiswrappedinfluidPage().Thisistrueofmost,butnotall,Shinyapplications.WewilllookindetailatthebasictypesofShinypageandsetupinChapter4,MasteringShiny'sUIFunctions.Itperformsthebasicsetupofthepage,makingitresponsiveandensuringthatitlooksgoodondifferentlysizedbrowsers.ThereismoredetailonthisfunctioninChapter4,MasteringShiny'sUIFunctions.ThetitlePanel()functionisusedtogivetheapplicationanicebigtitle.

ThenextsectionshowsthesetupofthestandardlayoutofaShinyapplication.Simplified,itlookslikethefollowingcode,withsidebarPanel()definingtheinputsontheleftandmainPanel()theinputsontheright,allwrappedinsidebarLayout():

sidebarLayout(

sidebarPanel(

#inputcontrolsinhere

Page 88: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

),

mainPanel(

#outputshere

)

Donotethatkeepingtheinputsontheleftandtheoutputsontherightisthetypicallayout,butShinyistotallyflexible.Youcankeepsomeinputsontherightifyouwish,orevenoutputsontheleft.ThisisjusttheusualsetupthatyouwillseeinasimpleShinyapplication.

WithinsidebarPanel(),wefindtwoinputs,sliderInput()andcheckboxInput(),asshowninthefollowingcode:

sliderInput(inputId="year",

label="Yearsincluded",

min=1952,

max=2007,

value=c(1952,2007),

sep="",

step=5

),

checkboxInput("linear",label="Addtrendline?",value=FALSE)

ThesliderInput()functionallowsyourusertoselectanumber,orarange,usingaslider.Inthiscase,theywillbeselectingarange,therangeofyearsthattheyareinterestedinforthetextsummaryandthetimeseriesgraph.Wehavealreadyseenthefirsttwoarguments,andtheywillbecomeveryfamiliartoyou—inputId

givingtheinputanamesoitcanbereferredtoasinput$name(input$yearinthiscase)andlabel,whichgivesthecontrolanicefriendlylabelfortheusertoreadsotheycanunderstandtheapplication.Youcanseetheotherarguments,givingaminimum,amaximum,andaninitialvalue(inthiscase,two,todefinearange).Wecanoptionallydefinetheseparatortoseparatethethousandsinthenumbers—inthiscase,settingittonothinginordertostoptheyearsappearingas1,952,2,007,andsoon.Notetheuseofstep=5.Thisgivesthenumericgapbetweeneachnotchontheslider.IfitisleftasNULL,thenShinywillpicksomethingsensible.Weuse5herebecausetheGapminderdataissplitintofive-yearchunks.

ThecheckboxInput()functionverysimplygivesyouatickboxthatreturnsTRUEwhentickedandFALSEwhenunticked.Thisexampleincludesallthepossiblearguments,whichgivesitanameandlabelandselectstheinitialvalue.

Page 89: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Thisconcludestheinputs.Let'slookattheoutputpanel,asshowninthefollowingcode:

),#endofsidebarPanel()

mainPanel(

tabsetPanel(

tabPanel("Summary",textOutput("summary")),

tabPanel("Trend",plotOutput("trend")),

tabPanel("Map",leafletOutput("map"),

p("Mapdataisfromthemostrecentyearintheselectedrange;

radiusofcirclesisscaledtolifeexpectancy"))

)

)

ProbablythemostunfamiliarpartofthiscodeistheuseoftabsetPanel().Thisallowsmultipleframesofoutputtobeshownonthescreenandselectedbytheuser,asiscommoninGUIsthatsupporttabbedframes.Notethatprocessingisonlycarriedoutforthecurrentlyselectedtab;invisibletabsarenotupdatedbehindthescenes,butratherwhentheyaremadeactive.Thisisusefultoknowwheresomeoralltabsrequiresignificantdataprocessing.Thesetupisverysimple,withacalltotabsetPanel()containingseveralcallstotabPanel()inwhicheachofthetabsisdefinedwithaheadingandapieceofoutputasdefinedinserver.R.Asyoucansee,therearethreetypesofoutputgivenbythreedifferentoutputfunctions—text,shownbytextOutput();aplot,shownbyplotOutput();andamapproducedwiththeleafletpackageandshownwithleafletOutput()(moreonwhichlater).

Page 90: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DataprocessingAsyouwritemoreandmorecomplexprograms,it'stheserver.Rfilethatwillbecomethelargestbecausethisiswhereallthedataprocessingandoutputgoes,andisevenwheresomeofthefunctionsthathandleadvancedUIfeatureslive.Let'slookatthechunksinorderandtalkabouttheworkcarriedoutineachsection.

Thefirstchunkofcodelookslikethefollowing:

library(tidyverse)

library(gapminder)

library(leaflet)

library(ggmap)

Youcanseethepackagesthatweneedbeingloadedatthetop.Weloadthetidyverseforaccesstothingssuchasdplyrandggplot,formungingdataandplotting,respectively.Thegapminderpackageisusedtoloadasubsetofthegapminderdata.IthasbeenverykindlymungedandplacedonlineintheformofaCRANpackagebyJennyBryan.Wewilltalkmoreaboutthedatathatitmakesavailablelater.Theleafletpackage—which,aswementionedbefore,isusedfordrawingmaps—isloadednext.Finally,theggmappackageisloaded.Thiswillbeusedtoconvertcountrynamestolatitudeandlongitudeforplottingbyleaflet.

Thenextthingthatwedoismungeor,ifwealreadymungedit,loadthedata,asshowninthefollowingcode:

if(!file.exists("geocodedData.Rdata")){

mapData=gapminder%>%

mutate(country2=as.character(country))%>%

group_by(country)%>%

slice(1)%>%

mutate_geocode(country2,source="dsk")%>%

select(-country2)

mapData=left_join(gapminder,mapData)%>%

group_by(country)%>%

fill(lon)%>%

fill(lat)

save(mapData,file="geocodedData.Rdata")

}else{

Page 91: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

load("geocodedData.Rdata")

}

I'mnotgoingtodistractfromShinybytalkingtoomuchaboutthiscode.Essentially,itcheckstoseewhetherthedataisalreadyintherelevantdirectory(whichitwillbeafteryou'verunitonce).Ifitis,itjustloadsthedata.Ifnot,itpreparesitbyproducingasmallerdatasetwithoneinstanceofeachcountryandgeocodingit(thatis,turningitintolatitudeandlongitude),thencombiningitwiththewholedataset(toputalltheyearsforeachcountrybackin),andfillingintheresultingmissinggeocodingsusingtheincrediblyusefulfill()functionofdplyr.Havingdoneallthat,itsavesthedatafornexttime(sincequeryingtheAPIforall142countriestakesquitealongtime).Don'tworrytoomuchifyoucan'tfollowthiscodeatthemoment;it'sreallytherejusttogetthedataontoyourcomputerinasimpleway.

It'sworthnotingthatdatainstructions—andindeedanyothercode—thatappearabovefunction(input,output){}areexecutedoncewhentheapplicationstartsandthenserveallinstancesoftheShinyapplication.Thismakesnodifferencewhenyou'redevelopingonalocalmachine,sincethecodewillstartfresheverytimeyourunit,butonceyoumoveyourcodetoaserver,itcanmakeabigdifference,sincethecodeisonlyrunonceforalltheusersandapplicationinstancesyouhave(untilyourestarttheShinyserver,whichmanagesconnectionstoyourapplicationsonaserver,ofcourse).Therefore,anyintensivedataorprocessingcallsarebestkeptinthissectiontoavoidyourusershavingtowaitalongtimefortheirapplicationtoload.

Page 92: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ReactiveobjectsTherestofthiscodeiswrappedinfunction(input,output){}.Thisisthereactivepartofyourapplication.Wewilltalkinmoredetailaboutreactiveprogramminglaterinthebook;fornow,let'sjustsaythatreactiveprogrammingisatypeofprogrammingwherewhentheinputschange,theoutputschange.

Thenextpieceofcodelookslikethis:

theData=reactive({

mapData%>%

filter(year>=input$year)

})

Thiscodedefinesareactiveobject.Upuntilnow,theserver.Rfilehasjustcontainedalistofoutputcommandsthatproducetheoutput,readytofilltheallocatedspacesinui.R.Here,we'reworkingalittledifferently.Sometimes,youwanttoprepareareactivedatasetonceandthenpassitaroundtheprogramasneeded.

Thismightbebecauseyouhavetabbedoutputwindowsthatusethesamedataset(asinthiscase),andyoudon'twanttowriteandmaintaincodethatpreparesthedataaccordingtothevaluesofreactiveinputswithinallthreefunctions.Thereareothertimeswhenyouwanttocontroltheprocessingofdatabecauseitistimeintensiveoritmightmakeanonlinequery(suchasinthecaseofaliveapplicationthatqueriesdataliveinresponsetoreactiveinputs).Thewaythatyoucantakemorecontroloverdataprocessingfromreactiveinputs,ratherthandistributingitthroughyouroutputcode,istousereactiveobjects.Areactiveobject,likeareactivefunction,changeswhenitsinputchanges.Unlikeareactivefunction,itdoesn'tdoanything,butisjustadataobject(dataframe,number,list,andsoon)thatcanbeaccessedbyotherfunctions.Crucially,whenitruns,itsoutputiscached.Thismeansthataslongasitsinputsdon'tchange,itwillnotrerunifitiscalledonagainbyadifferentpartofyourapplication.Thispreventsyourapplicationfromrunningthesamedataprocessingtasksrepeatedly.

Inthiscase,thedataprocessingisverysmall,sowe'renotreallysavinganytime

Page 93: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

usingreactiveobjects;however,itisstillgoodpracticetousethembecause,aswejustmentioned,itmeansthatyouonlyhaveonedatafunctiontomaintainratherthanseveralscatteredbetweentheoutputs.

Let'shavealookatanexample:

theData=reactive({

mapData%>%

filter(year>=input$year[1],year<=input$year[2])

})

Thisfunction,verysimply,filtersthedatasothatitcontainsonlydatathatwasloggedbetweentheyearsselectedinsliderInput().Thefirstthingtonoteisthat,unlikepreviousexamples,wearenotmakingacall,suchasoutput$lineGraph<-renderPlot({...})oroutput$summaryText<-renderText({...}).Instead,wearemarkingwhateverisinsidethecallreactivebyenclosingitinreactive({...})andassigningit,verysimply,totheData.ThisgeneratesareactiveobjectnamedtheData.Thiscanbeaccessedbycallingthisfunction—thatis,byrunningtheData()(forthewholedataframe),ortheData()$variableName(foravariable),ortheData()[,2:10](forthesecondtothetenthvariable).NotethebracketsaftertheData.Moreinformationonreactiveobjects,whentousethem,andlotsofadviceaboutmanagingandcontrollingreactivityanddataprocessinginyourapplicationisgiveninChapter8,CodePatternsinShinyApplications.

Page 94: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

OutputsFinally,wewilllookathowtheoutputsaredefined.Let'slookfirstatthecodethatproducesthefirsttabofoutput,whichisthetextualsummaryofthedata.

Page 95: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

TextsummaryThetextsummaryfunctioniswrappedinrenderText().ThisletsShinyknowthatthisfunctionreturnstext,asshowninthefollowingcode:

output$summary=renderText({

paste0(input$year[2]-input$year[1],"yearsareselected.Thereare",

length(unique(theData()$country)),"countriesinthedatasetmeasuredat",

length(unique(theData()$year)),"occasions.")

})

Rememberthatthisoutputispickedupinui.RwiththetextOutput()function,whichtakesthe"summary"identifier,which,asyoucansee,isthenamegivenbytheoutput$summary=renderText({...})function.Thefunctionverysimplypastestogethersometextandsomevaluestakenfromtheapplication.

Page 96: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

TrendgraphsThenextpartofthecodespecifiesthegraphofthetrendinlifeexpectancyusingggplot2.Let'slookateachpieceofcode:

#trend

output$trend=renderPlot({

thePlot=theData()%>%

group_by(continent,year)%>%

summarise(meanLife=mean(lifeExp))%>%

ggplot(aes(x=year,y=meanLife,group=continent,colour=continent))+

geom_line()+ggtitle("Graphtoshowlifeexpectancybycontinentovertime")

if(input$linear){

thePlot=thePlot+geom_smooth(method="lm")

}

print(thePlot)

})

Thefirstlinedefinestheoutputasareactiveplot.Thesecondinstructionuseschaineddplyrinstructions,aswesawinChapter1,BeginningRandShiny,firsttogroupthedatabycontinentandyear,andthentocalculatethemeanlifeexpectancyinthegroupsthatresult(inAfricaineachyear,inAmericaineachyear,andsoon).Thisisthensentontoaggplotinstructionforthegivenyearonthexaxis,meanlifeexpectancyontheyaxis,andthegroupings/colorsdefinedbythecontinent.NotethatbyassigningittothePlot,wedonotprintit,butmerelybegintobuilditup.

Thenextsectiontestsforthevalueofthesmoothingcheckbox,input$linear,andifitisTRUE,aregressionlineisaddedtotheplot.Therequirementtoprint()ggplotgraphicshasbeendroppedfromShiny(inthefirsteditionofthisbook,itwasnecessaryforyoutoprint()eachgraphic).Thisgraphicwillneedtobeprintedinanyenvironment,eventheconsole,becauseithasnotbeencalledwithggplot(),butmerelyassignedtothePlot.Normally,whenusingggplot()directlyinaShinysession,therewillbenoneedtoprint()theplot.

Page 97: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AmapusingleafletFinally,weaddamaptothelasttabusingtheleafletpackage.TheleafletpackageisanRinterfacetotheexcellentJavaScriptleafletpackage,whichcanbeusedtobuildawidevarietyofmapsfrommanydifferentsourcesandannotatethemwithdatainanumberofdifferentways.Formoredetailsontheleafletpackage,visitrstudio.github.io/leaflet/.Thecodeisrelativelysimpleandlookslikethefollowing:

output$map=renderLeaflet({#1

mapData%>%#2

filter(year==input$year[2])%>%#3

leaflet()%>%#4

addTiles()%>%#5

setView(lng=0,lat=0,zoom=2)%>%#6

addCircles(lng=~lon,lat=~lat,weight=1,#7

radius=~lifeExp*5000,#8

popup=~paste(country,lifeExp))#9

})

It'snotessentialthatyouunderstandthiscodeatthispoint,andwewillbemakinguseoftheleafletpackageintherestofthebook,butlet'slookatitlinebylinetogetanideaofhowitworks:

Line1:Thisdefinesoutput$mapascontainingaleafletmapsothatShinyknowshowtohandletheoutput.Line2:ThistellsthefunctiontousethemapDatathatwealreadyloadedrightatthetopofthefile(not,inthiscase,thereactivedatareturnedbymapData()).Line3:Thisfiltersthedatasothatonlythemostrecentdatagivenintheselectioncanbeselected.Line4:ThistellsRthatwewanttousealeaflet.Line5:Thisdrawsthebackgroundtothemap—lotsofdifferentmapsareavailable.See?addTilesformorehelponthisfunction.Line6:Thisdefineswhichbitofthemapwearelookingatandhowzoomedinweare.Thiswillfocusonlatitude0andlongitude0,withthemapzoomedmostofthewayout.Lines7to9:Theseaddtheactualdatapoints;here,youcanseethatwegivethelatitudeandlongitudeasone-sidedequations,reducetheweight(penwidth),andgivetheformulatodeterminetheradiusofthecircles(life

Page 98: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

expectancywitha5,000scalersoitshowsattherightsize).Finally,wedefinethepopup,whichiswhatappearswhenyouclickeachcircle(inthiscase,thenameofthecountryandtheactuallifeexpectancy).

Page 99: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AdvancedlayoutfeaturesInthischapter,wehavecoveredthemostsimpleofthelayoutfeaturesinShinywiththehelpofthesidebarLayout(),mainPanel(),andtabsetPanel()functions.Inlaterchapters,wewillbuildlargerandmorecomplexapplications,includingdashboards,andmakeuseofmoreadvancedlayoutfeatures.Itisworthpausingherebrieflytotakeaquicklookattheothertypesoflayoutthatareavailablesothatyoucanthinkaboutthebestwaytoimplementyourownapplicationaswegothroughthenextcoupleofchapters.

ThereareessentiallytwomorebroadtypesoflayoutfunctionthatyoucanuseinShiny.ThefirstusesthelayoutfeaturesofBootstrapandallowsyoutopreciselydefinethelayoutofyourapplicationusingagridlayout.Essentially,BootstrapasksyoutodefinetheUIasaseriesofrows.Eachrowcanbefurthersubdividedintocolumnsofvaryingwidths.

Eachsetofcolumnsonarowhaswidthsthataddupto12.Inthisway,youcanquiteeasilyspecify,forexample,thefirstrowasconsistingofonecolumnofwidth12,andthenthesecondrowasconsistingoftwocolumns,oneofwidth2andoneofwidth10.Thiscreatesaheaderpanelacrossthetopofthescreen,andthenathinoneandathickonetwocolumnsbelow,whichyouarelikelytoputUIandoutputelementsin,respectively.Awholevarietyoflayoutsispossible,andnestingandoffsettingthecolumnsarebothpossible,whichmeansthatwiththerightcode,youcanbuildanygrid-basedlayoutyoucanthinkof.Wewilllookatthecodetoimplementcustomlayoutsinthiswayinmoredetailinlaterchapters.

Ifyoudon'twanttosetupyourUIinthatmuchdetail,Shinyprovideslotsofotherlayoutsthatcanbeveryeasilycalledtolayoutyourapplicationinaparticularway.ThesefunctionsincludenavbarPage(),navList(),verticalLayout(),andsplitLayout().WewilllookatallofthelayoutfunctionsinChapter4,MasteringShiny'sUIFunctions,butit'sworthnotingherethattherearelotsofdifferentwaystocontrolthelayoutofaShinyapplication.

Page 100: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SummaryInthischapter,wehavecoveredalotofground.We'veseenthatShinyapplicationsaregenerallymadeupoftwofiles:server.Randui.R.You'velearnedwhateachpartofthecodedoes,includingsettingupui.Rwiththepositionandtypeofinputsandoutputs,andsettingupserver.Rwiththedataprocessingfunctions,outputs,andanyreactiveobjectsthatarerequired.

Theoptionalexerciseshavegivenyouachancetoexperimentwiththecodefilesinthischapter,varyingtheoutputtypes,usingdifferentwidgets,andreviewingandadjustingtheirreturnvaluesasappropriate.You'velearnedaboutthedefaultlayoutinShiny,sidebarLayout(),aswellastheuseofmainPanel()andtabsetPanel().

You'vealsolearnedaboutreactiveobjectsandwhenyoumightusethem.There'smoreonfinelycontrollingreactivitylaterinthebook.

Inthenextchapter,you'regoingtolearnhowtointegrateShinywithyourowncontentusingHTMLandCSS.

Page 101: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

IntegratingShinywithHTMLSo,webuiltourownapplicationtoexploretheGapminderdata.YoulearnedaboutthebasicsetupofaShinyapplicationandsawalotofthewidgets.Itwillbeimportanttorememberthisbasicstructurebecausewearegoingtocoveralotofdifferentterritoriesinthischapterand,asaconsequence,wewon'thaveasingleapplicationattheend,aswedidinthepreviouschapter,butlotsofbitsandpiecesthatyoucanusetostartbuildingyourowncontent.

Buildingoneapplicationwithallofthesedifferentconceptswouldcreateseveralpagesofcode,anditwouldbedifficulttounderstandwhichpartdoeswhat.Asyougothroughthechapter,youmightwanttorebuildtheGapminderapplication,oranotheroneofyourown(ifyouhaveone),usingeachoftheconcepts.Ifyoudothis,youwillhaveabeautifullystyledandinteractiveapplicationbytheendthatyoureallyunderstand.Or,youmightliketojustbrowsethroughandpickoutthethingsthatyouareparticularlyinterestedin;youshouldbeabletounderstandeachsectiononitsown.Let'sgetstartednow.

Inthischapter,wearegoingtocoverthefollowingareas:

AddingHTMLtonativeShinyapplicationsCustomizingShinyapplications,orwholewebpages,usingHTMLStylingyourShinyapplicationusingCSSIncorporatingShinycontentwithinanotherwebpageHTMLtemplates

Page 102: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

RunningtheapplicationsandcodeForconvenience,Ihavegatheredtogetheralltheapplicationsinthischapter.Thelinktotheliveversions,aswellasthesourcecodeanddata,canbefoundonmywebsiteatchrisbeeley.net/website.Ifyoucan,runtheliveversionfirstandthenbrowsethecodeasyougothrougheachexample.

Page 103: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ShinyandHTMLItmightseemquiteintimidatingtocustomizetheHTMLinaShinyapplication,andyoumayfeelthatbygoingunderthehood,itwouldbeeasytobreaktheapplicationorruinthestyling.YoumaynotwanttobotherrewritingeverywidgetandoutputinHTMLjusttomakeoneminorchangetotheinterface.

Infact,Shinyisveryaccommodating,andyouwillfindthatitwillquitehappilyacceptamixofShinycodeandHTMLcodeproducedbyyouusingShinyhelperfunctionsandtherawHTML,alsowrittenbyyou.So,youcanstylejustonebuttonorcompletelybuildtheinterfacefromscratchandintegrateitwithsomeothercontent.I'llshowyouallofthesemethodsandgivesomehintsaboutthetypeofthingsyoumightliketodowiththem.Let'sstartsimplebyincludingsomecustomHTMLinanotherwisevanillaShinyapplication.

Page 104: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

CustomHTMLlinksinShinyWewillnowmakealittletoyapplicationthatshowsthelifeexpectancyovertimeforthreedifferentcountries,andthatgivesalinktotheWikipediapageforeach.It'snotreallydesignedtolookgoodorbeuseful,butrathertoillustrateseveralthingsthatarepossiblewhenyouwishtoaddsmallamountsofHTMLtoanativeShinyapplication,ratherthanbuildingfromscratchorworkingwithHTMLtemplates(moreonwhichlater).

We'regoingtobuildanapplicationthatallowsyoutoselectfromacoupleofdifferentcountriesandviewthelifeexpectancyovertimeinthatcountry.AcustomHTMLbuttonshowstheWikipediapagefortheselectedcountry.

Page 105: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ui.RLet'stakealookattheui.Rfilefirst:

fluidPage(

tags$head(HTML("<linkhref='http://fonts.googleapis.com/css?family=Jura'

rel='stylesheet'type='text/css'>")),

h2("CustomHTML",style="font-family:'Jura';

color:green;font-size:64px;"),

sidebarLayout(

sidebarPanel(

radioButtons("country","Country",

c("Afghanistan","Bahrain","Cambodia"))

),

mainPanel(

h3("Timeseries"),

HTML("<p><em>Lifeexpectancy</em>overtime</p>"),

plotOutput("plotDisplay"),

htmlOutput("outputLink")

)

)

)

There'saquickmethodofstylingtextinlineinthisexample.First,let'sfetchafontfromGoogleFonts,whichyoucanseebysimplyusingthetags$functiontogenerateanHTML<head>andthenplacingthelinkinside,asshowninthefollowingcode:

tags$head(HTML("<link

href='http://fonts.googleapis.com/css?family=Jura'

rel='stylesheet'type='text/css'>"))

Nowthatwehavethefontavailable,it'sasimplematterofplacingitwithintheapplication.ThetitlePage()argument,whichisoftenusedatthetopofaShinyapplication,hasbeenremovedandreplacedwithh2()becauseh2()willallowyoutoinsertinlinestylingstraightintothefunction,whereastitlePage()willnot.Moreover,althoughtheacceptedargumentsaredifferent,theactualHTMLgeneratedbytitlePage()andh2()isthesame.Totestthisyourself,gototheconsoleandtypetitlePage("Test")andthentryusingh2("Test").

Inbothcases,thesamethingisreturned—<h2>Test</h2>.Thisisareallyuseful

Page 106: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

wayoflearningmoreaboutShinyandhelpingyoutodebugmorecomplexapplicationsthatmakeuseofShinyfunctions,aswellasHTMLandCSS.Sometimes,itcanbenecessarytoruntheapplicationandtheninspecttheHTMLusingtheinspectsourcefunctionavailableinmostwebbrowsers(Chrome,Explorer,Firefox,Safari,andsoon).Runningthefunctiondirectlyintheconsoleisalotquickerandlessconfusing.Havingdonethis,it'sasimplematterofpassingstylinginformationintoh2(),asyouwouldpassinlinestylingintoafontinHTML:

style="font-family:'Jura';color:green;font-size:64px;"

AlsoincludedistheHTML()function,whichmarkstextstringsasHTML,preventingtheHTMLfromescaping,whichwouldotherwiserenderthisonthescreenverbatim.TheothernewpartofthisfileisthehtmlOutput()function.This,inasimilarwaytotheHTML()function,preventsHTMLfromescapingandallowsyoutouseyourownmarkup,butthistimefortextpassedfromserver.R.Here'sthefinalinterface:

Page 107: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

server.RTheserver.Rinthiscaseisquitesimple.First,weloadthetidyverseandthedata(thedatawecreatedinthepreviouschapter),asshowninthefollowingcode:

library(tidyverse)

load("geocodedData.Rdata")

Then,wedefinethereactivepartoftheapplication,asshowninthefollowingcode:

function(input,output){

output$plotDisplay<-renderPlot({

gapminder%>%

filter(country==input$country)%>%

ggplot(aes(x=year,y=lifeExp))+

geom_line()

})

output$outputLink<-renderText({

link="https://en.wikipedia.org/wiki/"

paste0('<formaction="',link,input$country,'">

<inputtype="submit"value="GotoWikipedia">

</form>')

})

}

Thefirstpartofthecodeshouldholdnosurprises,beingafairlysimplelinegraphproducedusingggplot2.Youcanseethefamiliarfilter()functionbeingusedtorestricttheseriestodatafromonecountry.ThesecondpartofthecodeusesrenderText(),whichwehaveusedbeforetoshowtextwithinanoutput.TheonlydifferencehereisthatwearegoingtogenerateourownHTML.Youwillrecallfromtheui.RthatthisoutputneedstobewrappedinhtmlOutput(),nottextOutput(),topreservetheHTML(whichwouldotherwisebeautomaticallyescapedinShiny).

That'sanicegentleintroductiontostartingtomixHTMLintoyourShinyapplications.Now,let'sgototheotherextremeandlookatbuildingyourinterfaceentirelyinHTML.

Page 108: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AminimalHTMLinterfaceNowthatwehavedippedourtoesintoHTML,let'sbuilda(nearly)minimalexampleofaninterfaceentirelyinHTML.TouseyourownHTMLinaShinyapplication,createtheserver.Rfileasyounormallywould.Then,insteadofaui.Rfile,createafoldernamedwwwandplaceafilenamedindex.htmlinsidethisfolder.Thisiswhereyouwilldefineyourinterface.

Page 109: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

index.htmlLet'slookateachchunkofindex.htmlinturn,asshowninthefollowingcode:

<html>

<head>

<title>HTMLminimalexample</title>

<scriptsrc="shared/jquery.js"

type="text/javascript"></script>

<scriptsrc="shared/shiny.js"type="text/javascript"></script>

<linkrel="stylesheet"type="text/css"

href="shared/shiny.css"/>

<styletype="text/css">

body{

background-color:#ecf1ef;

}

#navigation{

position:absolute;

width:300px;

}

#centerdoc{

max-width:600px;

margin-left:350px;

border-left:1pxsolid#c6ec8c;

padding-left:20px;

}

</style>

</head>

The<head>sectioncontainssomeimportantsetupcodeforShiny,loadingtheJavaScriptandjQueryscripts,whichmakeitwork,aswellasastylesheetforShiny.YouwillneedtoaddsomeCSSofyourown,unlessyouwanteveryelementoftheinterfaceandoutputtobedisplayedasabigjumbleatthebottomofthescreen,makingthewholethinglookveryugly.Forsimplicity,I'veaddedsomeverybasicCSSinthe<head>section;youcould,ofcourse,useaseparateCSSfileandaddalinktoit,justasshiny.cssisreferenced.

ThebodyoftheHTMLcontainsalltheinputandoutputelementsthatyouwanttouse,aswellasanyothercontentthatyouwantonthepage.Inthiscase,I'vemixedupaShinyinterfacewithapictureofmycatsbecausenowebpageiscompletewithoutapictureofacat!Havealookatthefollowingcode:

<body>

<h1>MinimalHTMLUI</h1>

<divid="navigation">

<p>

Page 110: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

<label>Titleforgraph:</label><br/>

<textareaname="comment"rows="4"

cols="30">Myfirstgraph</textarea>

</p>

<divclass="attr-colshiny-input-radiogroup"id="graph">

<p>

<label>Whatsortofgraphwouldyoulike?</label><br>

<inputtype="radio"name="graph"value="1"

title="Straightline"checked>Linear<br>

<inputtype="radio"name="graph"value="2"

title="Curve">Quadratic<br>

</p>

</div>

<label>Here'sapictureofmycats</label><br/>

<imgsrc="cat.jpg"alt="Mycats"width="300"height="300">

</div>

<divid="centerdoc">

<divid="textDisplay"class="shiny-text-output"></div>

<br/>

<divid="plotDisplay"class="shiny-plot-output"

style="width:80%;height:400px"></div>

</div>

</body>

</html>

Therearethreemainelements:atitleandtwo<div>sections,onefortheinputsandonefortheoutput.TheUIisdefinedwithinthenavigation<div>,whichisleftaligned.RecreatingShinywidgetsinHTMLisprettysimple,andyoucanalsouseHTMLelementsthatarenotgiveninShiny.InsteadofreplacingthetextInput()widgetwith<inputtype="text">(whichisequivalenttoit),Ihaveinsteadused<textarea>,whichallowsmorecontroloverthesizeandshapeoftheinputarea.

TheradioButtons()widgetcanberecreatedwith<inputtype="radio">.Youcanseethatbothgetanameattribute,whichisreferencedintheserver.Rfileasinput$name(inthiscase,input$commentandinput$graph).Youwillnotethatthereisanother<div>aroundtheradiobuttondefinition,<divclass="attr-colshiny-input-radiogroup"id="graph">.ThisisanecessaryextrawhenusingShinywithHTML,asdiscussedatgoo.gl/Lrx9GB.AnotheradvantageofusingyourownHTMListhatyoucanaddtooltips;Ihaveaddedthesetotheradiobuttonsusingthetitleattribute.

Theoutputregionissetupwithtwo<div>tags:onethatisnamedtextDisplayandpicksupoutput$textDisplay,asdefinedinserver.R,andtheotherthatisnamedplotDisplayandpicksupoutput$plotDisplayfromtheserver.Rfile.Inyourowncode,youwillneedtospecifytheclass(asshowninthepreviousexample)aseithershiny-text-output(fortext),shiny-plot-output(forplots),orshiny-html-output(fortablesoranythingelsethatRwilloutputasHTML).Youwillneedtospecifythe

Page 111: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

heightofplots(inpx,cm,andsoon),andcanoptionallyspecifythewidtheitherinabsoluteorrelative(%)terms.

Justtodemonstratethatyoucanthrowanythingintherethatyoulike,there'sapictureofmycatsunderneaththeUI.Youwill,ofcourse,havesomethingabitmoresophisticatedinmind.Addmore<div>sections,links,pictures,andwhateveryoulike.

Page 112: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

server.RLet'stakeaquicklookattheserver.Rfile,showninthefollowingcode:

function(input,output){

output$textDisplay<-renderText({

paste0("Title:'",input$comment,

"'.Thereare",nchar(input$comment),

"charactersinthis."

)

})

output$plotDisplay<-renderPlot({

par(bg="#ecf1ef")#setthebackgroundcolor

plot(poly(1:100,as.numeric(input$graph)),type="l",

ylab="y",xlab="x")

})

}

Texthandlingisdoneasbefore.You'llnotethattherenderPlot()functionbeginsbysettingthebackgroundcolortothesameasthepageitself(par(bg="#ecf1ef");formoregraphicaloptionsinR,see?par).Youdon'thavetodothis,butthegraph'sbackgroundwillbevisibleasabigwhitesquareifyoudon't.

Theactualplotitselfusesthepoly()commandtoproduceasetofnumbersfromalinearorquadraticfunctionaccordingtotheuserinput(thatis,input$graph).Notetheuseofas.numeric()tocoercethevaluewegetfromtheradiobuttondefinitioninindex.htmlfromastringtoanumber.

ThisisacommonsourceoferrorswhenusingShinycode,andyoumustremembertokeeptrackofhowvariablesarestored,whetheraslists,strings,orothervariabletypes,andeithercoercetheminplace(asdonehere),orcoercethemallinonegousingareactivefunction.

Thelatteroptioncanbeagoodideatomakeyourcodelessfiddlyandbuggybecauseitremovestheneedtokeeptrackofvariabletypesineverysinglefunctionyouwrite.ThereismoreaboutdefiningyourownreactivefunctionsandpassingdataaroundaShinyinstanceinthenextchapter.Thetype="l"argumentreturnsalinegraph,andthexlabandylabargumentsgivelabelstothexandyaxes.

Thefollowingscreenshotshowsthefinishedarticle:

Page 113: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Finishedarticle

Page 114: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

IncludingaShinyapponawebpageThesimplestwaytomixShinyandanexistingwebpageisbyusinganiframe.JustlikewiththeRMarkdowndocumentinthepreviouschapter,itallowsyoutoincorporateanentireShinyapplicationintoanexistingdocument,exceptinthiscase,thedocumentisawebpageratherthanaMarkdowndocument.Theonlyrestrictionisthatyouwillneedtohosttheapplicationsomewhereontheinternetsoyoucanpointtoit.Onceyou'vedonethat,it'sassimpleasjustpointingtotheapplication,likeso:

<iframesrc="https://chrisbeeley.net/shinyapps/shinybook3rdedition/chapter2/widgettypes/"frameborder="0"width="950"height="800"></iframe>

Page 115: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

HTMLtemplatesThedevelopersofShinythemselvesnotedthatalthoughithasalwaysbeenpossibletoproduceentireShinyapplicationsinHTML,itisveryraretofindanyexampleswheresomebodyhasdoneso.ThisisprobablybecauseofShiny'sabilitytoproduceattractiveapplicationsusingpureRcode(anditsabilitytoincorporatesnippetsofHTML),aswellastherelativecomplexityofwritingthewholeinterfaceyourself.Tomakethingssimpler,Shiny0.13addedtheabilitytouseHTMLtemplates.UsinganHTMLtemplate,youcanveryeasilymixtogetherHTMLandShinycode.Therearetwomainwaysofdoingthis:firstlybydefiningthecodeinlinewithintheHTML,andsecondlybydefiningitwiththeui.Rfile.Inbothcases,youwillneedthreefiles—aserver.Rfile,aui.Rfile,andanotherfile,atthesamedirectorylevel(notinawww/folder),whichwillbeHTMLandwhichyoucannameanythingyoulike.Let'scallourstemplate.html.

Page 116: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

InlinetemplatecodeLet'slookfirstattheslightlysimplermethod,whichisincludingthecodeinlinewithintheHTMLtemplate.We'lltakesomeelementsoftheGapminderapplicationinthepreviouschapterandincorporatethemintoanHTMLtemplate.Theserver.Rfileisunchanged,althoughthisversionisalittleshorterthanthepreviousonebecausewehavetakenoutsomeoftheoutputs.Forthesakeofbrevity,we'llagainloadthedatathatwegeneratedinthepreviouschapter.Ifyouwanttoseehowtogeneratethisdata,havealookbackatthepreviouschapter.

Page 117: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

server.RToremindyouoftheserver.Rfile,andtoshowyouwhichbitswehaveretained,let'slookattheserver.Rfilefirst,showninthefollowingcode:

library(tidyverse)

library(gapminder)

load("geocodedData.Rdata")

function(input,output){

theData=reactive({

mapData%>%

filter(year>=input$year[1])

})

output$trend=renderPlot({

thePlot=theData()%>%

group_by(continent,year)%>%

summarise(meanLife=mean(lifeExp))%>%

ggplot(aes(x=year,y=meanLife,group=continent,

colour=continent))+geom_line()+

ggtitle("Graphtoshowlifeexpectancybycontinentovertime")

if(input$linear){

thePlot=thePlot+geom_smooth(method="lm")

}

print(thePlot)

})

}

Therearenosurprisesinthiscode,really;itisjustacut-downversionofthecodefromthepreviouschapter.Youcanseeareactivefunctiontobringbackthedata(theData()),andacalltorenderPlot(),whichproducesalinegraphusingggplot().

Page 118: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ui.Randtemplate.htmlTheui.Risincrediblysimple,andlookslikethis:

htmlTemplate("template.html")

That'sit!YouarejusttellingShinywhattheHTMLfileiscalled.Rememberthatwecalledittemplate.html.Simple.Now,therealworkisdonewiththeHTMLfile.

Let'slookattheHTMLfile'svarioussections.First,thehead:

<html>

<head>

{{headContent()}}

{{bootstrapLib()}}

</head>

Thefirstthingtonoteishowthefilewillbewritten.Essentially,itwillbeHTML,interspersedwithShinycodewrappedindoublecurlybraces.So,thisfirstsectionopensthehtmltagandtheheadtagandthenrunstwofunctions,whicharegiveninsidedoublecurlybraces.YoualwaysneedtoincludeheadContent(),whichplacestheboilerplatecodenecessarytomakethepagework,justaswesawwiththeminimalHTMLwebpagethatwelookedatearlierinthechapter.SomeShinyfunctionsrequireyoutoincludebootstrapLib(),whichloadsvariousBootstrapcomponents.It'snotreallyworthworryingaboutwhetheryouareusingthosecomponentsornot,sinceyoumightaddthemlater,orincludethematfirstandthentakethemaway,andsoon.Justincludeiteverytimeandthenyouwon'tneedtoworry.

Next,wedefinethebodyoftheapplication,asshowninthefollowingcode:

<body>

<h1>MinimalHTMLUI</h1>

<divclass="container-fluid">

<divclass="row">

<divclass="col-sm-4">

<h3>Controlpanel</h3>

{{sliderInput(inputId="year",

label="Yearsincluded",

min=1952,

max=2007,

value=c(1952,2007),

Page 119: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

sep="",

step=5)}}

{{checkboxInput("linear",label="Addtrendline?",

value=FALSE)}}

</div>

<divclass="col-sm-8">

{{plotOutput("trend")}}

<p>Formoreinformationabout<strong>Shiny</strong>lookatthe

<ahref="http://shiny.rstudio.com/articles/">documentation.</a></p>

<hr>

<p>Ifyouwishtowritesomecodeyoumayliketousethepre()functionlikethis:</p>

<pre>checkboxInput("linear",label="Addtrendline?",value=FALSE)</pre>

</div>

</div>

</div>

</body>

</html>

Asyoucansee,theShinycodeisincludedjustasyouwouldseeitinanynormalShinyapplication(indeed,thesearethefunctionsfromChapter2,ShinyFirstSteps),butineachcase,theyarewrappedwithdoublecurlybraces.It'sassimpleasthat.Itispossibletopassvaluesintothetemplatefromtheui.R,likethis:

htmlTemplate("template.html",customStep=10)

ThisvaluecannowbeaccessedfromwithintheShinycodeinthetemplate,likeso:

{{sliderInput(inputId="year",

label="Yearsincluded",

min=1952,

max=2007,

value=c(1952,2007),

sep="",

step=customStep)}}

Page 120: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Definingcodeintheui.RfileTheothermethodofdefininganHTMLtemplateisverysimilar,exceptinthiscase,theShinycodeisdefinedintheui.Rfile.Theserver.Rcodeisunchanged.

Page 121: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ui.RLet'sfirstlookattheui.Rfile,showninthefollowingcode:

htmlTemplate(

"template.html",

slider=sliderInput(inputId="year",

label="Yearsincluded",

min=1952,

max=2007,

value=c(1952,2007),

sep="",

step=5),

checkbox=checkboxInput("linear",label="Addtrendline?",value=FALSE),

thePlot=plotOutput("trend")

)

Asyoucansee,inthiscase,wearedefiningtheinputsintheui.Rfile.ThisisjustlikepassingthevalueofcustomStepinthepreviousexample,exceptthatinthiscasewearepassingwholewidgets,notjustvalues.Thesevaluesarenowreferredtoverysimplyinthetemplate.html,likeso:

...preamble

<divclass="container-fluid">

<divclass="row">

<divclass="col-sm-4">

<h3>Controlpanel</h3>

{{slider}}

{{checkbox}}

</div>

<divclass="col-sm-8">

{{thePlot}}

<p>Formoreinformationabout<strong>Shiny</strong>lookatthe

<ahref="http://shiny.rstudio.com/articles/">documentation.</a></p>

<hr>

...restofHTML

Themethodsareverysimilar.DefininginlineismoreappropriatewhenyourShinycodeisrelativelybrief,asitwasinthisexample.IfyouhavelargeamountsofShinyUIcode,youwillprobablyprefertodefineitinui.RtoavoidclutteringyourHTMLfilewithRcode.

Page 122: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

TakeastepbackandrewindWecoveredquitealotofmaterialinthissection,soit'sworthspendingamomentreviewingwhatwecovered.We'velookedataddingHTMLtoanapplicationthatisotherwisewritteninpureShiny.We'velookedatstylingapplicationswithCSS,aswellasbuildingentireinterfaceswithHTMLusingHTMLtemplates,orbymakingthewholethingfromscratch.

Page 123: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ExerciseIfyouhaven'talreadybeentempted,nowisdefinitelyagoodtimetohaveagoatbuildingyourownapplicationwithyourowndata.ThenextchaptercoversadvancedtopicsinShinyUIdesign,andthoughyouarewelcometoplowon,alittlepracticalexperiencewiththefunctionswillstandyouingoodsteadforthenextchapter.Ifyou'reinterestedinsharingyourcreationsrightaway,feelfreetojumptoChapter9,PersistentStorageandSharingShinyApplications.

HowyougoaboutbuildingyourfirstapplicationwillverymuchdependonyourpreviousexperienceandwhatyouwanttoachievewithShiny,butaswitheverythinginlife,itisbettertostartsimple.Startwiththeminimalexamplegiveninthepreviouschapterandputinsomedatathat'srelevanttoyou.Shinyapplicationscanbehardtodebug(comparedwithinteractiveRsessions,atleast),soinyourearlyforays,keepthingsverysimple.

Forexample,insteadofdrawingagraph,startwithasimplerenderText()callandjustprintthefirstfewvaluesofavariable.ThiswillatleastletyouknowthatyourdataisloadingokayandthattheserverandUIarecommunicatingproperly.AlwaysmakesurethatanycodeyouwriteinR(graphs,tables,datamanagement,andsoon)worksinaplaininteractivesessionbeforeyouputitintoaShinyapplication!

Page 124: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DebuggingProbablythemosthelpfulandsimpledebuggingtechniqueistousecat()toprinttotheRconsole.Therearetwomainreasonswhyyoushoulddothis:

Thefirstistoputinlittlemessagestoyourself—forexample,cat("Thisbranchofcodeexecuted").ThesecondistoprintthepropertiesofRobjectsifyouarehavingproblemsrelatingtodatastructure,size,ortype.Thecat(str(x))phraseisparticularlyuseful,andwillprintalittlesummaryofanykindofRobject,whetheritisalist,adataframe,anumericvector,oranythingelse.

TheotherusefulmethodisastandardmethodofdebugginginR,browser(),whichcanbeputanywhereinyourcode.Assoonasitisexecuted,ithaltstheapplicationandentersdebugmode(see?browser).ThereismoreondebuggingShinyapplicationsinChapter8,CodePatternsinShinyApplications.

Onceyouhavetheapplicationworking,youcanstarttoaddcustomHTMLusingShiny'sbuilt-infunctionsorrewriteui.Rintoindex.html.ThechoiceherereallydependsonhowmuchHTMLyouwanttoinclude.AlthoughintheoryyoucancreateverylargeHTMLinterfacesinShinyusing.htmlfilesreferencedbytheincludeHTML()command,youwillendupwitharatherconfusinglistofmarkupsscatteredacrossdifferentfiles.

Page 125: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Bootstrap3andShinySincethefirsteditionofthisbook,ShinyhasmigratedfromBootstrap2toBootstrap3.Therearenowmanyfunctions—bothwithinShinyandinitspackages(suchasshinydashboardandshinythemes,bothavailableonCRAN)—thatenhancethewayyoucanstyleyourapplicationsstraightfromShiny.Thereismoreonadvancedlayoutfunctions,Bootstrap3,andthepackagestohelpyoutostyleyourapplicationsinChapter4,MasteringShiny'sUIFunctions.

Page 126: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SummaryThischapterhasincorporatedquiteapileoftoolsintoyourShinytoolbox.YoulearnedhowtousecustomHTMLstraightfromaminimalui.RUIsetupandhowtobuildthewholethingfromscratchusingHTMLandCSS.

Inthenextchapter,youaregoingtolearnmoreaboutbuildingaUIwithShiny.Shinyincludesalotofdifferentlayoutfunctions,whichwillallbedescribed,andwewillalsolookatmakingnicetables,usingprogressbars,andmodals,aswellasmakingyourUIreactive.

Page 127: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

MasteringShiny'sUIFunctionsSofarinthisbook,we'vemasteredthebasicsofShinybybuildingourownGapminderdata-explorerapplication,andwe'velookedathowtostyleandextendShinyapplicationsusingHTMLandCSS.Inthischapter,wearegoingtoextendourtoolkitbylearningaboutmoreofShiny'sUIfunctions.Theseallowyoutotakecontrolofthefinedetailsofthewayyourapplicationlooksandbehaves.

Inordertodothis,we'regoingtochangethewaytheUIworksintheGapminderapplicationtomakeitmoreintuitiveandwell-featured.ThefinishedcodeanddataforthisadvancedGapminderapplicationcanbefoundathttps://chrisbeeley.net/website/.

Inthischapter,wewillcoverthefollowingtopics:

UsingShiny'smanylayoutfunctionseffectivelyLearninghowtoshowandhidepartsoftheinterfaceChangingtheinterfacereactivelyProducingbeautifultableswiththeDataTableslibraryShowingprogressbarstousersinlong-runningfunctionsShowingmessageswithmodals

Page 128: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Shiny'slayoutfunctionsTherearequitealotofdifferentlayoutfunctionsinShiny,andunderstandingwhattheyalldocanhelpyoutobuildtheinterfacethatyouwanteasily.It'spossibletocombinealotofthem,too,sowe'llreviewtheformandfunctionofeach,andthenshowalargerexampleattheendthatcombinesthemtogether.TherearethreemaintypesoflayoutfunctionthatShinyoffers.ThefirstiswhatIwouldcallsimplelayoutfunctions.Theseproduceastraightforwardkindoflayout,withoutmuchinthewayofstyling,anditisthesefunctionsthatcanoftenbecombinedtogether.ThenextkindiswhatIwouldcallcomplete.Thisisalayoutfunctionthatoffersalittlestylingandissuitablefordefininganentireapplication.Itwouldthereforeoftenbeusedonitsownwithoutanyothertypeoflayoutfunction.ThelastkindIwouldcallthedo-it-yourselfanditreferstoafunctionthatdoesn'treallydomuchatall,butratherjustdefinesthespaceinwhichyouwillplaceyourwidgets.Thisfunction,ofcourse,isverysuitableforcombiningwithotherfunctionstoproducethesetupyouwant.Let'srevieweachtypeinturn.

Page 129: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SimpleThroughoutthesecodeexamples,we'regoingtohaveaverysimpleserver.Rfile,whichwillnotchange.Itsimplydrawsatableandnothingelse.Wewillthereforealsobreakthehabitoftherestofthisbookandusethesingleapp.Rfilestructurefortheseexamples,sincetheyaresosmall.Withthatinmind,let'slookatthefirstapplication,whichwillbeflowLayout():

server=function(input,output){

output$table=renderTable({

head(iris)

})

}

ui=flowLayout(

sliderInput("slider","Slider",min=1,max=100,value=50),

textInput("text","Text"),

tableOutput("table")

)

shinyApp(ui,server)

InflowLayout,elementsareorderedlefttoright,toptobottom.Resizingthewindowcausestheelementstoreorderthemselvessotheyfit,lefttoright,toptobottom.Downloadthecodeexampleandtryitforyourself.Throughoutthissection,it'sagoodideatodownloadtheexamplesandtrythemout.

ThenextexampleisverticalLayout().Inthisandsubsequentcodeexamples,wewillnotbotherwiththeserverandshinyApp()codesincetheywillneverchange.Wewilljustlookatthevalueforuiineachcase:

ui=verticalLayout(

sliderInput("slider","Slider",min=1,max=100,value=50),

textInput("text","Text"),

tableOutput("table")

)

Asthenamesuggests,itmerelyarrangeselementsvertically.Asmanyasyousupply.Hereitisinaction:

Page 130: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ThefinalsimplefunctionissplitLayout().Ittakesasmanyelementsasyougiveitandarrangesthemonthepagelefttoright.Bydefault,eachisgiventhesamewidthbutyoucanoptionallysetthewidthforeachmanually.Hereisanexample:

ui=splitLayout(

cellWidths=c("20%","20%","60%"),

sliderInput("slider","Slider",min=1,max=100,value=50),

textInput("text","Text"),

tableOutput("table")

)

Inthiscase,wehavesetthewidthstobetteraccommodatethetable(which,asyoucansee,isgiven60%ofthewidth).It'ssuperficiallysimilartoflowLayout(),inthatifyoulayoutanapplicationwithboth,theymaylooksimilaratfirst,butthetwocriticaldifferencesarethatsplitLayout()allowsyoutodefinethewidthofeachwidget,andthatifyouresizethewindow,flowLayout(truetoitsname)willflowontothenextrow,whereassplitLayout()willjustcrampeverythingup,as

Page 131: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

showninthefollowingscreenshot:

SplitLayout

Page 132: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

CompleteNow,wecometothecompletesetupfunctions,thosethatcanbeusedindividuallytomakeawell-styledapplication.First,ofcourse,wehavetheoldfavorite,sidebarLayout().Many,manyShinyapplicationsarewrittenusingthislayoutanditisanattractiveandfunctionalsetup,withawellpanelthathighlightsthecontrolsandalargeareaforoneormoreoutputs.We'vealreadyseenthissetup,butasaquickreviewofthebasicstructurewithoutalltheusualclutter,let'stakealookattheuicode:

ui=fluidPage(

sidebarLayout(

sidebarPanel(

sliderInput("slider","Slider",min=1,max=100,value=50),

textInput("text","Text")),

mainPanel(tableOutput("table"))

)

)

It'sworthnotingthatthislayoutrequirestheuseoffluidPage()tosetitupcorrectly.Thisfunctionisrequiredforthisandanotherlayoutfunction,whichwewillcovershortly,aswellasbeingusefulinitsownright(whichwewillalsocovershortly).

TheothertwocompletelayoutfunctionsarenavbarPOAge()andnavlistPanel().Theyworksimilarlyinthatbothprovidebuttonsforyoutopagethroughsetsofinputandoutput.Let'slookateach.Hereisthesamesetofinputandoutput,puttogetherasanavbar:

Page 133: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Navbar

Thisisoneoftheselectedpages,Inputs.ThetableisviewableontheTablepage,accessedbyclickingtheTablebuttononthebaratthetop.ThisisobviouslynotparticularlygoodUIdesign,it'sjustdonetoillustratehowthefunctionswork.

Thecodeisverysimpleandjustconsistsoftabpanels,likeyouwouldfindintabsetPanel():

ui=navbarPage("Navbardemo",

tabPanel("Inputs",

sliderInput("slider","Slider",

min=1,max=100,value=50),

textInput("text","Text")),

tabPanel("Table",tableOutput("table"))

)

Navlistsworkinaprettysimilarway,exceptthepagesforthebuttonsaregatheredoverontheleft,asshowninthefollowingscreenshot:

Page 134: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Thecodehereisverysimilar,exceptinthiscase,aswiththesidebarLayout()function,acalltofluidPage()isnecessary:

ui=fluidPage(

navlistPanel("Navlistdemo",

tabPanel("Inputs",

sliderInput("slider","Slider",

min=1,max=100,value=50),

textInput("text","Text")),

tabPanel("Table",tableOutput("table"))

)

)

Page 135: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DoityourselfWealreadysawfluidPage()beingusedtosetuptheenvironmentforotherlayoutfunctionstowork.ButthisfunctioncanalsobeusedtobuildaUIfromscratch,usingthefluidRow()function.UsingfluidRow()withinfluidPage()allowsyoutoimplementthestandardbootstrapgridlayout,asdescribedatw3schools.com/bootstrap/bootstrap_grid_system.asp.Essentially,theinterfaceisbuiltuprowbyrowusingthefluidRow()function.Eachrowcanbedividedintosectionsofarbitrarywidthusingthecolumn()function.Thecolumnfunctiontakesanumericargumentspecifyinghowwideitshouldbe.Thetotalofalloftheseargumentsinagivenrowshouldalwaysbe12.So,forexample,arowmightconsistofcolumnsofwidth3and9,andthefollowingrow,perhapswidthsof4,4,and4.Inthiscase,averysimpleimplementationusingfluidRow()mightlooklikethis:

ui=fluidPage(

fluidRow(

column(width=4,

sliderInput("slider","Slider",min=1,max=100,value=50),

textInput("text","Text")),

column(width=8,

tableOutput("table")

)

)

)

Page 136: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

CombininglayoutfunctionsTofinish,let'slookathowtousedifferentlayoutfunctionstogethertoachieveasimpleandflexiblesetupforyourapplication.Therearelotsofdifferentwaysofdoingthis;thisexampleisdesignedjusttoshowyouthatyoucanuseawidevarietyoffunctionstowritequick,simplecode.Intruth,anydesigncanbemadeusingthegridsystem,givenenoughtimeandeffort,butitissometimessimplerjusttouseabuilt-infunction,asyoucansee.Inthisexample,I'veaddedacoupleofgraphstofleshouttheinterfaceabit,butwewon'tbotherlookingatthecodeforthem.They'rejustcreatedusingrenderPlot({plot(runif(10,runif(10))})andassignedtooutput$graph1andoutput$graph2.ThefinalUIcodelookslikethis:

ui=fluidPage(

fluidRow(

column(width=4,

sliderInput("slider","Slider",min=1,max=100,value=50)),

column(width=8,

tableOutput("table")

)

),

splitLayout(

plotOutput("graph1"),plotOutput("graph2")

),

verticalLayout(

textInput("text","Text"),

p("Moredetailshere"),

a(href="https://shiny.rstudio.com/tutorial/","Shinydocumentation")

)

)

Asyoucansee,youcanfreelymixtogethertheselayoutfunctionstotakeadvantageofthebenefitsofeach;fluidRow()togiveprecisecontroloverthewidthofthecolumns,splitLayout()forsimplicity,andverticalLayout()tostackthewidgetsontopofeachother.Thefinalapplicationlookslikethefollowingscreenshot:

Page 137: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present
Page 138: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

StreamliningtheUIbyhidingelementsThisisasimplefunctionthatyouarecertainlygoingtoneedifyoubuildevenamoderatelycomplexapplication.Thoseofyouwhohavebeendoingextracreditexercisesand/orexperimentingwithyourownapplicationswillprobablyhavealreadywishedforthisor,indeed,havealreadyfoundit.

conditionalPanel()allowsyoutoshoworhideUIelementsbasedonotherselectionswithintheUI.Thefunctiontakesacondition(inJavaScript,buttheformandsyntaxwillbefamiliarfrommanylanguages)andaUIelement,anddisplaystheUIonlywhentheconditionistrue.We'regoingtoenhancetheGapminderapplicationtoshowtheoptiontoaddatrendlinetothegraphonlywhenthegraphisshown.Inordertodothis,we'regoingtohavetoknowwhichofthetabpanelsiscurrentlyselected,andinordertodothatwe'regoingtohavetogivethemaname.Let'sdothatnow.

Page 139: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

NamingtabPanelelementsInordertoallowtestingforwhichtabiscurrentlyselected,we'regoingtohavetofirstgivethetabsofthetabbedoutputnames.Thisisdoneasfollows(withthenewcodeinbold):

tabsetPanel(id="theTabs",

tabPanel("Summary",textOutput("summary"),

value="summary"),

tabPanel("Trend",plotOutput("trend"),

value="trend"),

tabPanel("Map",leafletOutput("map"),

p("Mapdataisfromthemostrecentyearintheselectedrange"),

value="map")

)

Asyoucansee,thewholepanelisgivenanID(theTabs)andtheneachtabPanelisalsogivenaname(summary,trend,map).Theyarereferredtointheserver.Rfileverysimplyasinput$theTabs.

Finally,wecanmakeourchangestoui.RtoremovepartsoftheUIbasedontabselection:

conditionalPanel(

condition="input.theTabs=='trend'",

checkboxInput("linear",label="Addtrendline?",

value=FALSE)

),

Asyoucansee,theconditionappearsveryR/Shiny-like,exceptwiththe.operatorfamiliartoJavaScriptusersinplaceof$.ThisisaverysimplebutpowerfulwayofmakingsurethatyourUIisnotclutteredwithirrelevantmaterial.

Page 140: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

BeautifultableswithDataTableLaterversionsofShinyaddedsupporttodrawtablesusingthewonderfulDataTablejQuerylibrary.Thiswillenableyouruserstosearchandsortthroughlargetablesveryeasily.ToseeDataTableinaction,visitthehomepageathttp://datatables.net/orruntheapplicationfeaturedinthischapter.

Thepackagecanbeinstalledusinginstall.packages("DT")andneedstobeloadedinthepreambletotheserver.Randui.Rfilewithlibrary(DT).Oncethisisdone,usingthepackageisquitestraightforward.Therearetwofunctions:oneinserver.R(renderDataTable)andoneinui.R(dataTableOutput).Theyareusedasfollows:

###server.R

output$countryTable=renderDataTable({

mapData%>%

filter(year==2007)%>%

select(-c(lon,lat))

})

###ui.R

tabPanel("Table",dataTableOutput("countryTable"),

value="table")

AnythingthatreturnsadataframeoramatrixcanbeusedwithinrenderDataTable().Outofthebox,itwillproduceattractive,searchable,pageabletables.Inthiscase,thetablelookslikethis:

InpreviousversionsofShiny,therewerenamespaceconflictsbetweenthedatatablefunctionsandthestandardfunctions,withShinydrawingastandard

Page 141: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

tablewithsomeofthesamefunctionnamesastheDTpackage.ThesituationnowisthatShinywillproducetheseJavaScriptdatatablesoutofthebox,butwithoutenablingalloftheoptionsofthefullDTpackage(inparticular,client-sideprocessing).It'sworthwhile,then,tousetheDTpackageandloaditinserver.Randui.R.Let'scustomizethetableusingtheoptionsthatareavailablewiththeDTpackage.Thecodeisasfollows:

datatable(

mapData%>%

filter(year==2007)%>%

select(-c(lon,lat)),

colnames=c("Country","Continent","Year","Lifeexpectancy",

"Population","GPDpercapita"),

caption="Countrydetails",filter="top",

options=list(

pageLength=15,

lengthMenu=c(10,20,50))

)

Thefirstthingtonoticeisthatweneedtowrapthefunctionindatatable().TherenderDataTable()functionwillautomaticallyapplythattoanydataframeormatrixreturnedbyit,butinordertoaddoptionsweneedtoexplicitlyaddit.Youcanseethecolumnnamesbeingmadefriendlierwiththecolnamesargument,acaption,andacolumnfilterbeingaddedatthetopusingfilter='top'.Lastly,therearesomeoptionsthatareaddedfromwithinacalltooptions=list(...),inthiscasechangingthesizeofthetableandtheoptionsforrownumbersgivenforthetable(making10,20,or50rowstheoptionsavailable).Therearemany,manyoptionsavailable,soreadthedocumentationformoredetails:rstudio.github.io/DT/.

Page 142: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ReactiveuserinterfacesAnothertrickyouwilldefinitelywantupyoursleeveatsomepointisareactiveuserinterface.ThisenablesyoutochangeyourUI(forexample,thenumberorcontentofradiobuttons)basedonreactivefunctions.

Forexample,consideranapplicationthatIwroterelatedtosurveyresponsesacrossabroadrangeofhealthservicesindifferentareas.Theservicesarerelatedtoeachotherinquiteacomplexhierarchy,andovertime,differentareasandservicesrespond(orceasetoexist,ormerge,orchangetheirname),whichmeansthatforeachtimeperiodtheusermightbeinterestedin,therewouldbeatotallydifferentsetofareasandservices.Theonlysensiblesolutiontothisproblemistohavetheusertellyouwhichareaanddaterangetheyareinterestedinandthengivethembackthecorrectlistofservicesthathavesurveyresponseswithinthatareaanddaterange.

Theexamplewe'regoingtolookatisalittlesimplerthanthis,justtokeepfromgettingboggeddownintoomuchdetail,buttheprincipleisexactlythesameandyoushouldnotfindthisideatoodifficulttoadapttoyourownUI.Wearegoingtomakeaselector,whichallowstheusertopickoneoftheyearswithintheyearrangethattheyhaveselectedandhavethatyearplottedonthemap,insteadofbeingstuckwiththemostrecentyear.Thechoicewillbeconstrainedbythefactthatthedatawasonlyrecordedeverysevenyears.So,forexample,iftheuserselects1960to1990,theselectorboxwillcontainonlytheyears1962,1967,1972,1977,1982,and1987.

Page 143: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Thereactiveuserinterfaceexample–server.RWhenyouaremakingareactiveuserinterface,thebigdifferenceisthatinsteadofwritingyourUIdefinitioninyourui.Rfile,youplaceitinserver.RandwrapitinrenderUI().Then,allyoudoispointtoitfromyourui.Rfile.

Let'stakealookattherelevantbitoftheserver.Rfile:

output$yearSelectorUI=renderUI({

selectedYears=unique(mapData$year)

selectInput("yearSelector","Selectyear",

selectedYears)

})

Thefirstlinetakesthereactivedatasetthatcontainsonlythedatabetweenthedatesselectedbytheuserandgivesalltheuniquevaluesoftheyearwithinit.Thesecondlineisawidgettypethatwehavenotusedyetthatgeneratesacombobox.Theusualidandlabelargumentsaregiven,followedbythevaluesthatthecomboboxcantake.Thisistakenfromthevariabledefinedinthefirstline.Theoutputitself,thatis,thebitdefinedasoutput$something=renderUI({...}),canbegivenanynameyoulike.ItwillsimplybecalledbywhateverthatnameisinuiOutputwithinui.R,asweshallseeinamoment.Notethattheactualinputthatwearecreating,thatis,thethingthatwillbecalledbyinput$something,hasthenamegivenintheselectInput()function.So,inthiscasetheinputwillbecalledinput$yearSelectorandnotinput$yearSelectorUI.Toavoidconfusion,IhaveadoptedanamingconventionformyuseofrenderUI,whereIgivetheoutput$thesamenameasselectInput(),orwhicheverotherfunctionitis,butwithUIattheend.ThishelpsmenottomixthemupandmeansIcanalwaysremembertheotherifIknowthefirstone.Let'slookatthecorrespondingentryintheui.Rnow.

Page 144: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Thereactiveuserinterfaceexample–ui.RTheui.Rfilemerelyneedstopointtothereactivedefinition,asshowninthefollowinglineofcode(justaddittothelistofwidgetswithinsidebarPanel()):

uiOutput("yearSelectorUI")

Youcannowpointtothevalueofthewidgetintheusualway,asinput$yearSelector.

TherearemoreadvancedthingsyoucandowithareactiveUIusingtheinsertUI()andremoveUI()functions,whichallowyoutoinsertarbitrarycontrolsorsetsofcontrolsandremovecontrols,respectively.Althoughtheyarequitesimpletoactuallyproduce,makinguseofthemisquitetrickybecauseoftheneedtokeeptrackofthenamesgiventoeachinput,aswellaswhichhavebeenaddedandremovedsofar.Asaconsequence,wewillnotlookatanexampleinthisbook;seethedocumentationforasimpleexampleandyoumaywishtobearinmindthatitispossibleshouldyoueverneeditinalargeapplication.

Page 145: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ProgressbarsItisquitecommoninShinyapplications,andinanalyticsgenerally,tohavecomputationsordata-fetchesthattakealongtime.Sometimes,itwillbenecessaryfortheusertowaitforsometimebeforetheiroutputisreturned.Incasessuchasthis,itisagoodpracticetodotwothings:toinformtheuserthattheserverisprocessingtherequestandhasnotsimplycrashedorotherwisefailed,andtogivetheusersomeideaofhowmuchtimehaselapsedsincetheyrequestedtheoutputandhowmuchtimetheyhaveremainingtowait.

ThisisachievedverysimplyinShinyusingthewithProgress()function.Thisfunctiondefaultstomeasuringprogressonascalefrom0to1andproducesaloadingbaratthetopoftheapplicationwiththeinformationfromthemessageanddetailargumentsoftheloadingfunction.

YoucanseeinthefollowingcodethatthewithProgressfunctionisusedtowrapafunction(inthiscase,thefunctionthatdrawsthemap),withmessageanddetailargumentsdescribingwhathashappenedandaninitialvalueof0(value=0,thatis,noprogressyet):

withProgress(message='Pleasewait',

detail='Drawingmap...',value=0,{

...functioncode...

})

Asthecodeissteppedthrough,thevalueofprogresscansteadilybeincreasedfrom0to1(forexample,inafor()loop)usingthefollowing:

incProgress(1/3)

Thethirdtimethisiscalled,thevalueofprogresswillbe1,whichindicatesthatthefunctionhascompleted(althoughothervaluesofprogresscanbeselectedwherenecessary;see?withProgess()).Tosummarize,thefinishedcodelooksasfollows:

withProgress(message='Pleasewait',

detail='Drawingmap...',value=0,{

...functioncode...

incProgress(1/3)

...functioncode...

incProgress(1/3)

Page 146: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

...functioncode...

incProgress(1/3)

...functioncode...

})

It'sassimpleasthat.Again,takealookattheapplicationtoseeitinaction.Ifyouneedtogiveyourusermoredetailedinformationabouthowfartheyarethroughtheprocessing,theincProgress()functionalsotakesmessageanddetailarguments,whichmeansyoucanchangetheinformationbeinggivenbywithProgress()asyoustepthroughthefunction.Forexample,youmaywishtowriteincProgress(1/3,detail="Summarizingdata"),perhapsincProgress(1/3,message="Generatinggraph"),andsoon.

Page 147: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ProgressbarwithshinycssloadersTheshinycssloaderspackagemakesiteveneasiertoallowyourusertoseethatanoutputisloading.ItisavailableonCRANandsocanbeinstalledwiththis:

install.packages(“shinycssloaders”)

Outputsincludinggraphsandtableswillnowshowananimatedbusyiconwhiletheyload.ThecodeisassimpleaswrappinganoutputinwithSpinner(),orevenjustpipingittowithSpinner():

withSpinner(plotOutput(“myplot”))

Or,youcanusethefollowing:

plotOutput(“myplot”)%>%

withSpinner()

Page 148: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ModalsModalsareaUIelementfromBootstrapandarepop-upmessagesthatcantellyourusermoreaboutwhattheapplicationisdoing.Theycanbeusefultogiveauserwarnings,ortoallowtheusertorequestmoreinformationaboutanoutputiftheywishtoknowmore.Youcanwriteamodalverysimply,usingtwofunctionsintheserver.Rfile.ThemodalDialogfunctionproducesthemodal,andtheshowModalfunctionshowsit.Youcanusethemtogetherjustlikethis:

showModal(modalDialog(

title="Warning",

"Thisisawarning"

))

Thiswillgiveusasimpledialogwithatitleandamainsection:

Butwecandomoreinterestingthingsthanthiswithmodaldialogs.Therearetwowaysthatwecanexpandtheirfunctionality.First,becausethemodalDialog()functionwillacceptanyShinyUIelements,notjusttext,youcanaddHTMLelementssuchashorizontalrule,withhr(),andeveninputandoutput.Andsecond,youcangeneratethemodaldialogusingthemodalDialog()functionelsewhere,andmerelypasstheoutputtoshowModal().Theapplicationdoesn'treallydoanythingsensible,butit'sjustforillustration.We'regoingtohaveabuttonthatlaunchesamodaldialog.Themodaldialogwillcontainanactionbuttonandaninstructionnottopressit.Iftheuserdoespressit,afunctionelsewheredecideswhetherwe'realldoomedortheygotawaywithitthistime.Let'shavealookatthecode.We'llstartveryquicklywiththeonelinethatweaddtotheui.Rfiletoshowthebuttonthatmakesthemodaldialog:

actionButton("showModal","Launchloyaltytest")

Page 149: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Thisisthefirsttimethatwe'veseenanactionbutton.ActionbuttonsaresimplyHTMLcontrolsthatstartoffwithavalueof0andincrementby1eachtimethey'repressed.Onedoesn'tnormallyusethisvalue,althoughsometimesitcanbeusefultoknowhowmanytimesthebuttonwaspressed.Instead,theactionbuttonisusedbecausereactivefunctionscanformdependenciesonit,meaningtheywillrunwhenthebuttonispressed.Includingacalltoanactionbutton(byjustwritinginput$showModalononelineofthecode)willcauseanyreactivefunction,whetheritbeanoutputorotherwise,torerunwhenthebuttonispressed.Thereisalsoaspecialfunction,observeEvent({}),thatreactstoeventssuchasbuttonpushes,whichwe'regoingtousenow.ForadetaileddescriptionofhowtouseobserveEvent({})anditscousin,observe({}),seeChapter8,CodePatternsinShinyApplications.Fornow,it'senoughtoknowthatobserveEvent(input$showModal,{...})willruneverytimesomeonepushestheshowmodalbutton.

Havingsetupthebuttontolaunchit,let'sproducethefirstmodal:

observeEvent(input$showModal,{

showModal(modalDialog(

title="Loyaltytest",

actionButton("dontPress","Don'tpressthis")

))

})

Asyoucansee,straightawaywe'vemadethingsmoreinterestingbyincludingaShinyfunctioninsidethemodalratherthanjustsometext.Now,we'regoingtosetupanothermodalifsomeonepressestheactionbuttoninthefirst:

observeEvent(input$dontPress,{

showModal(testOutcome(sample(c(TRUE,FALSE),1)))

})

YoucanseetheshowModal()functionthatacceptsamodaldialogobjectandtheobserveEvent()function,againreactingtoabuttonpush.Butthistime,we'regeneratingthemodalwithafunction,testOutcome().Youcanseealsothatwe'repassingavaluetotestOutcome(),eitherTRUEorFALSE,chosenrandomly.Thisletsthefunctionknowwhethertheuserhasdoomedusallorgotawaywithitthistime.Let'slookatthefunction:

testOutcome=function(chance){

modalDialog(title="Outcome",

Page 150: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ifelse(chance,"You'vedoomedusall!",

"Yougotawaywithitthistime!"))

}

Asyoucansee,thefunctionisverysimpleandcreatesamodaldialogthatdecides,basedonthevaluefedtoit,whetherwe'realldoomed.Hopefully,thatshouldgiveyouagoodgroundinginhowwecanusefunctionstocreatemodals.Ifyou'recomfortablewiththis,exploretheexamplesinthedocumentation;theyuseadvancedconceptsinShiny,suchasreactivevalues(coveredinChapter8,CodePatternsinShinyApplications).

Page 151: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AlternativeShinydesignsAtthetimeofwriting,thereisquiteanexcitingnewdevelopmentintheworldofShinyUI,whichisthatdevelopersarestartingtoprovideShinyinterfacestoUIframeworksotherthanBootstrap.Thefirstexampleofthis,whichwillhopefullyleadtomanymore,isanimplementationoftheMaterialdesignframeworkforShiny.MaterialdesignistheveryflatdesigncreatedbyGooglein2014andfamiliartoanyuseroftheAndroidoperatingsystem.Hereisanexample:

Page 152: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

TheShinypackageitselfisbasedontheopensourceimplementationofMaterialdesign,MaterializeCSS(materializecss.com/),andiscalledshinymaterial.ItisavailableonCRAN(cran.r-project.org/web/packages/shinymaterial/index.html).ThepackageitselffeaturesdifferentfunctionsfromvanillaShiny,material_radio_button()andmaterial_modal(),forexample,buttheprinciplesarethesameandanyShinydevelopershouldfinditeasytousethedifferentfunctionstogiveatotallydifferentfeeltotheirapplication.

Page 153: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SummaryInthischapter,welookedatdifferentwaystomakeyourapplicationgood-lookingandeasytouse.Welookedattherangeoflayoutfunctionsandhowbesttousethem,andwelookedatmakinginputthatshows,hides,andchangesitscontentsinresponsetothestateoftheapplication.Wealsolookedatmakingandcustomizingdatatables,andshowingprogressbarsandmessagestoyouruser,aswellasatotallynewwaythatShinyapplicationscanlookbasedontheMaterialdesignframeworkfromGoogle.

ThenextchapterisallaboutusingJavaScript,allthewayfromusingJavaScriptfromRcodewiththeshinyjspackagetoproducingacomplexapplicationthatusesJavaScripttopassmessagesbackandforthbetweentheShinyserverandtheclient.

Page 154: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

EasyJavaScriptandCustomJavaScriptFunctionsWithShiny,JavaScript,andjQuery,youcanbuildprettymuchanythingyoucanthinkof;moreover,ShinyandjQuerywilldoalotoftheheavylifting,whichmeansthatfairlyminimalamountsofcodewillberequired.Inthischapter,wewillcover:

UsingJavaScripttoreadandwritetotheDOMUsingJavaScripttosendmessagesbetweenclientandserverEasyJavaScriptwiththeshinyjspackageUsingyourownJavaScriptwithextendShinyjsListeningforeventswithJavaScriptUsingJavaScriptlibrarieswithhtmlwidgets

Page 155: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

JavaScriptandShinyTheconnectionbetweenJavaScriptandShinyisanotherreasontorecommendRStudioasanIDEbecauseitperformsbeautifulsyntaxhighlightingonJavaScriptstraightoutofthebox(although,clearly,othertexteditorsandIDEsmaydothisorbeeasilyconfiguredtodoso).

Beforeweproceed,it'sworthreviewingthedifferencebetweenserverandclient-sidecodeandwhatthey'reusedfor.JavaScriptgainedpopularityasaclient-sidelanguage,whichranonwebbrowsersandaddedinteractivitytowebsitesthatwouldotherwisebestaticHTMLandCSSfiles,whichweredownloadedfromservers.

Ithasfoundincreasinguseontheserverside(forexample,withNode.js),butwearegoingtouseitontheclientsideandsowillnotconsiderthisanyfurther.So,inthiscase,JavaScriptisrunningontheclientside.Theserversideinthiscase,ofcourse,isR,andspecificallythecommandsaretobefoundintheserver.Rfile.ShinyandJavaScript(and,byextension,jQuery)can,asserverandclientrespectively,passthingsbackandforthbetweenthemselvesasyouwish.

Also,it'sworthnotingthattherearetwowaysforShinyandJavaScripttointeractwitheachother.

Thefirstisperhapsthesimplestandwillbeconsideredfirst.BecauseShinyandJavaScriptcanbothreadandwritetothewebpage(thatis,totheDocumentObjectModel(DOM),itisquitesimpleforthemtointeractwitheachotheronthewebpage.TheDOMisawayoforganizingobjectsinHTML,XHTML,andXMLdocuments,inwhichelementsarereferencedwithinatreestructure.

Adetaileddiscussioniswelloutsidethescopeofthisbook;sufficetosaythatifyouaregoingtouseJavaScriptwithShinyorHTML,youwillneedtolearnabouttheDOMandhowtogetandsetattributeswithinit.

ThesecondwayinwhichShinyandJavaScriptcaninteractiswhenit'seasierorbettertosendmessagesdirectlybetweentheserverandclient.Althoughintheory,youcouldusethe<inputtype="hidden">tagofHTMLandpassmessageson

Page 156: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

theDOMwithoutshowingthemtotheuser,itwilloftenbeeasiertocutoutthemiddlemanandsendtheinformationdirectly,particularlywhenthemessageiscomplicated(alargeJSONobject,forinstance).

Wewilllookatsendingmessagesdirectlyafterthefirstexample.

First,asawarm-up,wewilllookatusingJavaScripttoreadtheDOMgeneratedbyShinyandperformsomeclient-sideprocessing,beforewritingthechangesbacktotheDOM.

Page 157: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Example1–readingandwritingtheDOMInthisexample,we'regoingtofindoutsomethingaboutthestateoftheapplicationfromtheDOM,grabitwithJavaScript,andwriteitbacktotheDOM.We'lllookatui.RtoputtogetherthepageandthenlookattheJavaScript.Theserver.Rfileisunchanged,sowewillnotdiscussithere.

Page 158: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ui.RWe'regoingtousetheGapminderapplicationwe'vebeenlookingatthroughoutthebook,butaddalittleJavaScriptmagic.We'regoingtoaddabuttonthat,whenclicked,writesthecurrentlyselectedyearsonthesummarytexttab.Let'stakealookatwhatwe'readdingtotheui.Rfile,overinthesidebarPanel()function:

tags$input(type="button",

id="append",

value="Addcurrentinputvalues",

onClick="buttonClick()"),

includeHTML("appendText.js")

Asyoucansee,weusethetags$xxx()functionthatwesawinChapter3,IntegratingShinywithHTML,inordertogenerateabuttonthatwillrunaJavaScriptactionwhenit'sclicked.ItgeneratesthefollowingHTML:

<inputtype="button"id="append"value="Addcurrentinputvalues"

onclick="buttonClick()">

Theotherfunction,whichwealsosawinChapter3,IntegratingShinywithHTML,istheincludeHTML()function.AsdescribedinChapter3,IntegratingShinywithHTML,thisfunctionallowsyoutoincludeHTMLfromafileratherthanclutteringupyourui.Rwithit.JustlikeHTML(),itpreventsShinyfromescapinganyHTMLwithinit,whichisthedefaultbehavior.Inthiscase,wearelinkingtoaJavaScriptfilecalledappendText.js.Now,wejustneedtoaddanelementtowhichtheJavaScriptcanwrite,inmainPanel():

tabPanel("Summary",textOutput("summary"),p(id="selection","Values"))

WenowhaveaparagraphelementwithanIDofselectiontowhichwecanwrite.server.Risunchanged,andsonowlet'slookattheJavaScript.

Page 159: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

appendText.jsTheJavaScriptisverysimpleandlookslikethis:

<scripttype="text/javascript">

functionbuttonClick(){

varelem=document.getElementById('selection');

elem.innerHTML=document.getElementById('year').value;

}

</script>

YoucanseethatwegrabtheelementwiththeIDofselectionandwritethevalueoftheyeartoit.Youwill,Iamsure,wishtoproducesomethingalittlemoresophisticatedthanthis!Nowwehavethebasics,thesecondexampleisabitmorecomplex.Inthisexample,wewillbepassingmessagesdirectlybetweenserver(R)andclient(JavaScript).

Page 160: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Example2–sendingmessagesbetweenclientandserverInthisexample,wearegoingtousetheDOMandmessagestopassinformationbetweentheclientandserver.Theuserwillbeabletoselectanumberusingaslider.Theserverreadsthisinputandthenpicksarandomnumberbetween1andtheuser-suppliednumber.ThisnumberiswrittenbacktothescreenaswellasbeingsentinamessagetoJavaScript.

JavaScriptreceivesthisnumberandproducesadrop-downselectorthatallowstheusertoselectavaluebetween1andtherandomnumberthattheserverpicked.Everytimetheuserselectsadifferentvaluefromthisdropdown,JavaScriptwilldeciderandomlywhetheritthinksthatShinyrules!orwhether,infact,JavaScriptrules!.Thisissentasamessagetotheserver,whichpicksitupandwritesittothescreen.Clearly,thisisnotofmuchuseasarealapplication,butitshoulddemonstratetoyoutheprinciplesofsendingandreceivingmessagesandreadingandwritingtotheDOM.

Itisdefinitelyworthhavingalookattheapplicationlive.Aswithalltheapplications,itcanberunstraightfrommywebsite(chrisbeeley.net/website)wherethesourcecodecanalsobedownloaded.Hereistheapplicationinaction:

Page 161: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Asyoucanseeinthepreviousscreenshot,theuserhaspicked7,theserverhaspicked6outoftherangeofnumbersfrom1to7,JavaScripthasbuiltadrop-downmenuusingthatnumberofoptions,andhasalsodecidedinthiscasethatJavaScriptrules.DonotethatthisapplicationcouldquiteeasilybewritteninpureShiny,and,likemanyexamplesinthisbook,isprovidedforillustrationonly.Itisworthkeepingitsimple,soyoucaneasilyseehoweverythingfitstogetherwithoutworryingaboutunderstandingeverythingJavaScriptisdoing.

Inthiscase,theui.Randserver.Rfilesarebothprettysimpleandshouldbefairlyself-explanatory.MostofthecodeisintheJavaScriptfile.Let'squicklylookattheui.Randserver.Rfilesfirst.

Page 162: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ui.RThecoderunsasfollows:

fluidPage(

#flexiblelayoutfunction

h4(HTML("Thinkofanumber:</br>DoesShinyor</br>JavaScript

rule?")),

sidebarLayout(

sidebarPanel(

#sidebarconfiguration

sliderInput("pickNumber","Pickanumber",

min=1,max=10,value=5),

tags$div(id="output")#tags$XXforholdingdropdown

),

mainPanel(

includeHTML("dropdownDepend.js"),#includeJSfile

textOutput("randomNumber"),

hr(),

textOutput("theMessage")

)

)

)

Theuseofh4(HTML("XXX"))allowsustoshrinkthetitlealittleandaddsomeHTMLlinebreaks(avoidingHTMLescapingwiththeHTMLfunctionasbefore).tags$div(...)producesa<div>elementinwhichtoplacethedrop-downmenu,whichJavaScriptwillbuild.ThemainPanel()calljustcontainsareferencetotheJavaScriptfilethatwillrunonthepage,aplacetoputtherandomnumbertheserverwillpick,ahorizontalline,andamessagefromJavaScriptregardingwhetherJavaScriptorShinyrules.

Page 163: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

server.RTheserver.Rfilerunsasfollows:

function(input,output,session){

output$randomNumber=renderText({

theNumber=sample(1:input$pickNumber,1)

session$sendCustomMessage(type='sendMessage',

message=theNumber)

return(theNumber)

})

output$theMessage=renderText({

return(input$JsMessage)

})

}

Thefirstthingtonotehereistheuseoffunction(input,output,session){...}insteadofthefunction(input,output){...}thatweareusedtoseeing.TheadditionofasessionargumentaddsaconsiderableamountoffunctionalitytoShinyapplications.Inthiscase,itallowsustosendmessagestoJavaScript.Thereismoreonthefunctionalityofthesessionargumentinthenextchapter,Chapter6,Dashboards.

Thefirstfunctionherecarriesouttwotasks.First,ittakesthenumberthattheuserselectedonthesliderandpicksarandomnumberbetween1andthatnumber.ItsendsthatnumberstraighttoJavaScriptusingthesession$sendCustomMessagefunction(whichthesessionargumentwementionedpreviouslyenables).ThesendCustomMessage()functionisdefinedwithinShiny;itisplacedaftersession$inordertotieittothesessiondefinedintheshinyServer(function(input,output,session){...})function.Finally,itreturnsthenumbertoShiny,justlikeinastandardapplication,readytobeplacedintheoutputslot,whichui.Rsetsup.

ThesecondfunctionreceivestheJavaScriptmessage.It'sveryeasytoaccess,theShinyfunctionwithinJavaScriptwritesittothestandardinput$xxxvariablename,whichweareusedtoseeingthroughoutthebook.Asisnowplain,alotoftheworkinthisapplicationisbeingdonewithintheJavaScriptfile.Let'stakealook.

Page 164: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

dropdownDepend.jsThereisquitealotofcodeinthissectiondoingquitealotofdifferentthings,sowe'llstepthrougheachchunkinturn:

<scripttype="text/javascript">

//Shinyfunctiontoreceivemessages

Shiny.addCustomMessageHandler("sendMessage",

function(message){

//callthisbeforemodifyingtheDOM

Shiny.unbindAll();

Thefirstpartcarriesouttwofunctions;Shiny.addCustomMessageHandler("sendMessage",function(message){...})registersthemessage-handlerwithShiny.The"sendMessage"namewasdefinedintheserver.Rfunctioninthesession$sendCustomMessage(type='sendMessage',message=theNumber)call.Thisisthefirststepinreceivingandprocessingmessagesfromtheserver.

ThesecondpartbeginstheprocessofreadingandwritingtotheDOM.WheneveryouaregoingtomodifytheDOMinJavaScript,youshouldcallShiny.unbindAll()firstandthenShiny.bindAll()attheend;wewillcomeacrossthelatterfunctionlaterinthissection:

/*deletethedropdownifitalready

existswhichitwillthesecond

timethisfunctioniscalled*/

//getthedropdownandassigntoelement

varelement=document.getElementById('mySelect');

//ifitalreadyexistsdeleteit

if(element!==null){

element.parentNode.removeChild(element);

}

Inthissection,wechecktoseewhetherthedropdownhasalreadybeendrawn(whichitwillbethesecondtimethisfunctioniscalled),andifithas,wedeleteitinordertoredrawitwiththenewnumberofoptions:

//Createemptyarraytostoretheoptions

vartheNumbers=[];

//addascendingnumbersuptothe

//valueofthemessage

for(vari=1;i<=message;i++){

theNumbers.push(i);

Page 165: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

}

//grabthedivreadytowritetoit

vartheDiv=document.getElementById("output");

Now,wecreateanarrayandfillitwiththenumbersfrom1tothevalueofmessage,whichistherandomnumberthattheserverpickedandpassedtothisfunction:

//createanewdropdown

varselectList=document.createElement("select");

//giveitanameandwriteittothediv

selectList.setAttribute("id","mySelect");

theDiv.appendChild(selectList);

//addtheoptions

for(varn=0;n<theNumbers.length;n++){

varoption=document.createElement("option");

option.setAttribute("value",theNumbers[n]);

option.text=theNumbers[n];

selectList.appendChild(option);

}

Next,wecreatethedrop-downlistandaddtheoptionstoitusingthearrayofnumberscreatedimmediatelybefore:

//addanonchangefunctiontocallshinyRules

//everytimethisinputchanges

selectList.onchange=shinyRules;

//addclasstostylenicelyinBootstrap

selectList.className+="form-control";

//callthiswhenyou'vefinishedmodifyingtheDOM

Shiny.bindAll();

}

);

Finally,weaddononchangepropertytothedropdownsothatitwillcalltheshinyRules()functioneverytimeitischanged,addtheform-controlclasstorenderthedropdownnicelyinBootstrap,andcalltheShiny.bindAll()functionnecessarywhenwehavefinishedwritingtheDOM:

shinyRules=function(){

//definetextarrayandpickrandomelement

vartextArray=['JavaScriptRules!','ShinyRules!'];

varrandomNumber=Math.floor(Math.random()*textArray.length);

//wheneverthisinputchangessendamessagetotheserver

Shiny.onInputChange("JsMessage",textArray[randomNumber]);

}

</script>

Page 166: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ThislastpieceofcodedefinestheshinyRules()function,which,asintheprecedingcode,willbecalledeachtimethedropdownischanged.Itsetsupatextarray,picksarandomelementfromit,andthenusestheShiny.onInputChange(...)functiontosendthiselementtotheserver.Asyoucansee,thefunctiontakestwoargumentsinthiscase:"JsMessage"andtextArray[randomNumber].

Thefirstoftheseargumentsgivesthemessageaname,soitcanbepickedupbytheserver.Rfile.Thisisthepartoftheserver.Rfilethatwesawbeforethatreadsinput$JsMessage,sotheinputisaccessedusingthestandardShinynotationofinput$xxxthatweareusedtoseeing.Ifyougobacktolookattheserver.Rfile,youcanseeacalltorenderText()thatreturnsinput$JsMessage,readytobewrittenstraighttotheoutputpaneloftheinterface.

Page 167: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ShinyjsWe'vealreadyseenthataslongasyouknowJavaScript,usingJavaScriptisprettyeasyinShiny.Theshinyjspackage,availableonCRAN,actuallymakesiteasytouseextrabitsofJavaScriptinyourapplicationbywritingpureRcode.Installitwithinstall.packages("shinyjs")andlet'stakealook.

ShinyjsgivesyouaccesstoquiteafewnicelittleJavaScripttricks,soseethedocumentationformore,butwe'regoingtohavealookatafewwiththehelpoftheGapminderapplication.Thefirstistheabilitytodisableandenablecontrols.Thiscanbeusefultohelpyourusersunderstandhowanapplicationworks.Forexample,inthegapminderapplication,theyearcontroldoesnotdoanythingwhenthemaptabisselected,sincethedatausedisalwaysthemostrecentdataanyway.Wecanhidethecontrol,aswesawinthepreviouschapter,Chapter4,MasteringShiny'sUIFunctions,butsometimeswemayprefertograyoutanddisablethecontrol.

Inordertouseshinyjs,weneedtocalllibrary(shinyjs)inboththeserver.Randui.Rfiles.WealsoneedtoadduseShinyjs()anywherewithinfluidPage()inui.R.Withthisdone,enablinganddisablingcontrolsisverysimpleusingtheenable()anddisable()functionsfromShinyjs.WehavenamedthetabPaneltheTabsandthemaptabmapandthereforewecantestwhetherinput$theTabsisequalto"map".Now,it'sverysimpletoturnthecontrolonoroff:

observe({

if(input$theTabs=="map"){

disable("year")

}else{

enable("year")

}

})

Anothersimpletrickischangingtheformattingoftextortables.WecandothisverysimplyusingthetoggleClass()function,whichaddsandtakesawayaCSSclassto/fromadiv.Allweneedtodoiswrapthetextoutputfromthegapminderui.Rindiv,andgiveitamemorableid("theText"):

div(id="theText",textOutput("summary"))

Page 168: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DefinetheCSSintheheadoftheHTMLusingtags$head():

fluidPage(

tags$head(

tags$style(HTML(".redText{

color:red;

}"

))

),

...)

Addabutton:

checkboxInput("redText","Redtext?")

Andnow,applytothenameddiv("theText")thenamedclass("redText")whenthenamedbutton(input$redText)ispressed:

observe({

toggleClass("theText","redText",input$redText)

})

Wecanalsoallowtheusertoresetsomeorallofthecontrols.Thiscanbeusefuliftheycannotrememberthedefaultsandtheywishtorestoredefaultvaluesforthecontrolswithoutrestartingtheapplication.Thisfunctionrequiresonlyadiv.Wewillplaceadivaroundtheyearslidertoallowtheusertorestoretheirdefaultseasily:

div(id="yearPanel",

sliderInput("year",

"Yearsincluded",

min=1952,

max=2007,

value=c(1952,2007),

sep=""

)

),

Now,wejustneedanactionbuttonfortheusertopress:

actionButton("reset","Resetyear")

Now,weuseobserveEvent()tolistenforthebuttonpush,andreset()toresetthevalueofthenameddiv:

observeEvent(input$reset,{

reset("yearPanel")

})

Page 169: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Thelastexamplewe'regoingtoshowusestheoneventfunction,whichwillrunanypieceofRcodeinresponsetoanevent.Itwillrespondtothefollowingevents:click,dblclick,hover,mousedown,mouseenter,mouseleave,mousemove,mouseout,mouseover,mouseup,keydown,keypress,andkeyup.We'regoingtolistenforthehoverevent,whichreferstowhenthemousepointerisabovesomething.Inordertodoso,wemerelyspecifythetypeofevent,theIDofthecontrol,andthentheRfunctionwewishtorun:

onevent("hover","year",

html("controlList",

input$year,add=FALSE))

Thisfunctionlistensforahoverovertheyearcontrol,andthenexecutesthegivenfunction.ThefunctionlooksforanelementwithanIDof"controlList",andaddsthevalueoftheinputyear.Theadd=FALSEargumentisgivensothepreviousentryisoverwritteneachtime.WeaddtheelementtothetabPanelgraph:

tabPanel("Trend",value="graph",plotOutput("trend"),

p(id="controlList")),

Now,theapplicationhasalittlereadoutofthecurrentlyselectedyearsunderneaththegraph,whichupdatestothenewvaluewheneveryouhoverovertheyearcontrol:

Page 170: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Gapminder

Page 171: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ExtendshinyjsTheshinyjspackagecandomuchmorethanjustgiveyouaccesstocannedJavaScript,usefulthoughthatis.UsingtheextendShinyjs()function,youcanveryeasilyreadRinputandsendittoJavaScript.ItissimplertouseiftheV8packageisinstalled.Ifyoucannotinstallthispackage,thereisaworkaround;consultthedocumentation.

We'regoingtoimprovetheapplicationthatwejustproduced(itwillstillbejustasuseless,ofcourse!)byallowingtheusertochangethesizeandthecolorofthetext.Thefinishedapplicationlooksasfollows:

Finishedapplication

Page 172: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ui.RLet'sstartwiththethingstoaddtotheui.R.Onceagain,weaddaplaceforthetexttolivetothegraphtab:

tabPanel("Trend",plotOutput("trend"),

h3("Userselectionhistory"),

p(id="selection",""))

Then,weaddabuttontoaddthetextandsomecontrolstothesidebar:

actionButton("buttonClick","Addinputs"),

selectInput("color","Textcolour",

c("Red"="red",

"Blue"="blue",

"Black"="black")),

selectInput("size","Textsize",

c("Extremelysmall"="xx-small",

"Verysmall"="x-small",

"Small"="small",

"Medium"="medium",

"Large"="large",

"Extralarge"="x-large",

"Supersize"="xx-large"))

ThelastadditionisareferencetotheJavaScriptfilethatwillmakeeverythinghappen.WeaddthiswiththeextendShinyjs()function.PutitunderneathuseShinyjs(),soyoudon'tloseit:

useShinyjs(),

extendShinyjs(script="appendText.js")

Let'slooknowattheserver.Rcode.

Page 173: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

server.RThecodehereisprettysimple:

observeEvent(input$buttonClick,{

js$buttonClick(input$color,input$size)

})

We'veseentheobserveEvent()functionbefore;itsimplylistensfortheinput$buttonClickactionbutton.Thejs()functionisdoingallthework;itsendsitsargumentstotheshinyjs.buttonClickfunctionwithintheJavaScriptfile(whichwewilllookatnext).Ingeneral,js$foosendsitsargumentstoshinyjs.foointhedefinedJavaScript.

Page 174: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

JavaScriptLastly,let'slookattheJavaScript.Aspreviouslymentioned,shinyjs.buttonClickisafunctionthatcanaccesstheargumentsofjs$buttonClick().Withthatinmind,let'slookatthecode:

shinyjs.buttonClick=function(params){

//boilerplatecode

vardefaultParams={

color:"black",

size:"medium"

};

params=shinyjs.getParams(params,defaultParams);

//restofcode

varelem=document.getElementById('selection');

elem.innerHTML=document.getElementById('year').value;

elem.style.color=params.color;

elem.style.fontSize=params.size;

}

Notethatitisnotnecessarytoincludethe<scripttype="text/javascript">...</script>scripttagaroundtheJavaScriptinthisfile.Thefirstpartisboilerplatecode,andit'sdesignedtohandletheuseofnamedandunnamedlistswithintheRargumentsofthefunctioncall.BothareacceptedbyextendShinyjs(),sothiscodeensuresthattheyplaynicelyasJavaScript.Italsoallowsyoutoadddefaultvalues.YoucanseetheparametersfromRbeingreadintotheparamsvariablewiththeshinyjs.getParamsfunction.

Therestofthecodeisverysimple,merelygrabbingtheselectionelement,addingtexttoit,andchangingthecolorandsizeusingparams.colorandparams.size,bothbroughtthroughfromRandplacedasnamedelementswithinparams.Youwillrecalltheinput$colorandinput$sizevaluesbeingpassedasargumentswithinthejs$buttonClick()function.

Andthat'sitforshinyjs.Averysimple,powerfulwayofusingeithercannedJavaScriptorincorporatingyourownJavaScriptandreadingRinputveryeasily.

Page 175: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

RespondingtoeventsinJavaScriptYoucanlistenforallkindsofeventsinShinyapplications,eitherfromthewindoworfromindividualelements,andrunJavaScriptcodewhentheyoccur.Forexample,youcanlistenforwhenShinymakestheinitialconnectionwiththeclient,andyoucanlistenforwhenShinyisbusyoridle.Youcanlistenforwhenaninputchanges,oranoutputrecalculates.Forafulllist,seethedocumentationatshiny.rstudio.com/articles/js-events.html.Asanexample,we'regoingtomakeaverysimpleprogramthattakesalongtimetodrawagraphandgivesyoualittlealertboxwhenitisfinished.Theprogramissosimplethatwewillusethesingle-fileapp.Rformat.Here,itisreproducedinitsentirety:

ui<-fluidPage(

titlePanel("JavaScriptEvents"),

sidebarLayout(

sidebarPanel(

actionButton("redraw","Redrawplot")

),

mainPanel(

plotOutput("testPlot"),

includeHTML("events.js")

)))

server<-function(input,output){

output$testPlot<-renderPlot({

input$redraw

Sys.sleep(5)

plot(1:10)

})

}

shinyApp(ui=ui,server=server)

Weconstructanactionbuttontorefreshthegraph,setupaverysimpleplot,andestablishadependencybetweentheplotandtheactionbuttonsoitrefresheswhentheactionbuttonispressed.TheJavaScriptfileisaddedusingtheincludeHTML()function,aswesawearlierinthechapter.

TheJavaScriptitselfisverysimple:

<scripttype="text/javascript">

$(document).on('shiny:idle',function(event){

alert('Finished!');

});

</script>

Page 176: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Youcanseethatthefunctionlistensforshiny:idle(whichistriggeredwhenShinyhasfinishedwhatitisdoing)anddisplaysanalerttotheuser.Ifwewished,wecouldjustlistenforthatspecificgraphbeingredrawn;thisisachievedsimplyasfollows:

$('#testPlot').on('shiny:recalculated',function(event){

alert("Finished");

});

YoucanaccessawholerangeofJavaScriptplottinglibrariesstraightfromR,andthereforefromShiny,usingthehtmlWidgetspackage.Let'shavealookatsomeofthethingsthatareavailable.

Page 177: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

htmlwidgetsThehtmlwidgetspackageallowspackagedeveloperstoveryeasilyproducebindingsbetweenJavaScriptvisualizationlibrariesandR.IfyouwishtomakeuseofthehtmlwidgetspackagetoproduceabindingtoyourownfavoriteJavaScriptlibrary,itisarelativelysimpleprocess,thedetailsofwhichcanbefoundathtmlwidgets.org/develop_intro.html.Wewillnotlookattheprocessofproducingyourownbindingsbecausemanypopularlibrariesareavailable,andthereareplentyinthischapterthatdemonstratetheuseofexistinglibraries.Moreover,itrequirescompetencewithJavaScript,whichisnotassumedinthisbook.SufficetosaythatthehtmlwidgetspackagemakesiteasytouseJavaScriptvisualizationlibrariesfromR,includingRMarkdowndocumentsandShinyapplications.

We'vealreadyseenleafletinthisbook.Thispackagemakesuseofthehtmlwidgetspackage.Inthischapter,wewillhavealookatsomeotherusefulpackagesthatmakeuseofhtmlwidgets.Forthesakeofspace,wewilllookonlyatthefunctionalityandsomeexampleapplications,ratherthangoingthroughallofthecode.Theapplicationpicturedistheoneusedinthepreviouseditionofthisbookandallthecodeforthischaptercanbefoundatchrisbeeley.net/website/shinybookV2.html.

Wewilllookatthefollowing:

dygraphsrChartsd3heatmapthreejs

Page 178: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DygraphsThedygraphslibraryinJavaScript(http://dygraphs.com/)isdesignedtoshowtimeseriesandtrenddata.Itsupportszoom,pan,andmouseover,andevensupportsmobiledevicesbyofferingpinchtozoom.ThedygraphsRpackageprovidesahandyinterfacetomanyofthefunctionsofthedygraphslibrary.Itcanbeinstalledusinginstall.packages("dygraphs").

Formoreinformationaboutthedygraphspackage,seethefollowinglink,http://rstudio.github.io/dygraphs/.

Let'stakealookatanexamplegraph:

Page 179: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

GoogleAnalytics

Thereareacoupleofthingsyouneedtomakeanoteofonthisgraph.First,youcanseethemouseovereffectatthetop-rightofthegraph,wherethedateandvaluesofNHSusersandOtherarelisted.Second,thisgraphhasbeensmoothed

Page 180: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

usingarollingaverage.Thenumberofpointstobeaveragedisspecifiedinthewidgetontheleft-handsideofthepage(Selectrollperiod)andisgivenbydefaultinthesmallsquareboxatthebottom-leftofthegraph.Third,thegrayboxatthebottomwiththeselectoroneithersidecanbeusedtoselectdaterangesonthegraph.ThiscanbeusefulinaShinyapplicationasawayofkeepingthedaterangeofallthedataconstantsbutallowingtheusertozoominonthegraphastheychoose.Asyoucansee,thetextunderneaththegraphmakesthisdistinctionclear,reportingthenumberofdaysinthewholedataset(933)aswellasthenumberselectedonthegraphitself(578).Makingagraphuser-friendlyandinteractiveisextremelyeasyusingthedygraphspackage.

Page 181: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

rChartsThesupportinrChartsfordifferentJavaScriptlibrariesisverybroad,andtherearemanypossibilitiesforproducingbeautiful,interactivegraphics.Here,wewilltakealookatjustoneandperusethedocumentationatramnathv.github.io/rCharts/toseethedifferentlibrariesandgraphssupportedbythepackage.

TherChartspackageisnotavailableonCRANbutcanbeinstalledveryeasilyusingthefollowingcode:

install.packages("devtools")require(devtools)install_github("ramnathv/rCharts")

Let'snowtakealookatoneofthemanyplotoutputspossiblewiththispackage:

Plotoutputs

Page 182: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Thisplotisaclusteredbarchartoftheselectedinput(Averagesession/Users/Sessions),showingthenumbersoneachdayandinfivedifferentcountries.ThankstothemagicofD3,theplotisinteractiveoutofthebox.Itsupportsmouseover,asshowninthescreenshot,withJapan'sresultsforWednesdayhighlighted.TheplotcanbechangedfromGroupedtoStacked(thatis,differentdaysgroupedhorizontallyorvertically),andthedaysoftheweekcanbehiddenandshownbyclickingonthematthetopinthelegendofthegraph.

Page 183: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

d3heatmapThed3heatmappackageusesvanillaD3andproducesinteractiveheatmaps.Itcanbeinstalledusinginstall.packages("d3heatmap").

Formoreinformationaboutthed3heatmappackage,seethefollowinglink,http://htmlwidgets.org/showcase_d3heatmap.html.

Hereisanexample:

Heatmap

Mouseovergivestheindividualvalueswithintheheatmap.

Page 184: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

threejsThethreejspackage,asdiscussedatthebeginningofthechapter,canbeusedtoproduce3Dscatterplotsorplotsonglobemappings(includingEarthandcelestialbodies).Itcanbeinstalledusinginstall.packages("threejs").Inordertoproducetheglobeoutputthatisshowninthescreenshot,itisnecessarytoalsoinstallmapsusinginstall.packages("maps").Anexampleisshownhere:

Page 185: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Globe

Page 186: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Thevisualizationiscompletelyinteractiveandcanbespunwithamousedrag.

Page 187: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SummaryInthischapter,weusedJavaScripttoreadandwritetheDOM,andsendmessagesbackandforthwiththeserver.Weexploredhowtogetthemostoutoftheshinyjspackage,aswellashowtolistenforeventswithJavaScript.Lastly,wetalkedaboutthehtmlwidgetspackage,andshowedsomeexamplesofsomeofthegraphicsyoucanproduceusinghtmlwidgets-enabledRpackages.

Inthenextchapter,wewilllookathowtobuilddashboardsinShiny.

Page 188: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DashboardsThischapterisallaboutlayingoutyourShinyapplications.InChapter4,MasteringShiny'sUIFunctions,wealreadylookedatdoingitbyhand,usingHTMLorCSS,andwealreadysawhowtolayoutapplicationsusingtheBootstrapgridsystem.Shiny(anditsassociatedpackages)includesloadsoffunctionsthatallowyoutolayoutyourapplicationsbeautifullyandsimply.Thischaptertakesthecodeandapplicationsyouhavealreadyseenandchangesthemfromtheveryplain,vanilla-lookinglayoutthatthedefaultstylingreturnstoslick,customizablelayouts,culminatinginafull-featureddashboard.

Inthischapter,wewilldothefollowing:

MakeadashboardveryeasilyusingtheflexdashboardtemplateAddiconstoapplicationsFurtherexploreShinyusingtheBootstrapgridsystemtolayoutapplicationsBuildadashboardtohelpyourusersaccessalltheinformationtheyneedfromwithinthesameintuitiveinterface

Page 189: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ApplicationsinthischapterInordertobetterunderstandthelayoutfunctionsinparticular,we'renotgoingtoaddanyfunctionalityinthischapter.We'llstartoffwiththevanillaGapminderapplicationwehavebeenusingthroughoutandwe'llapplydifferenttypesoflayouttoit,soyoucanseehowtheywork.Asweprogress,wewilladdoneortwoextrafeatures.However,wewillmainlyfocusonlookingatthesameapplicationbutwithdifferenttypesoflayoutfunctionsappliedtoit.

Itishighlyrecommendedthatyoudownloadandrunallthecodeinthischapter,soyoucangetabettersenseofhowtheapplicationswork,aswellasseeingtheserver.Rcodeineachcase,whichwon'tberepeatedforeachapplication.Ifyou'renotinfrontofacomputerwhilereadingthissection,hopefullythereareenoughscreenshotsandexplanatorymaterialtokeepyougoinguntilyoucanseetheapplicationsinactionforyourself.

Page 190: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

FlexdashboardsFlexdashboardsareasimpleRMarkdowntemplateandmakelayingoutdashboards(withorwithoutinteractivityfromShiny)verysimple.Formoreinformationaboutflexdashboards,gotormarkdown.rstudio.com/flexdashboard/.CreatingaflexdashboardinRStudioisincrediblyeasy.First,installthepackagewithinstall.packages("flexdashboard").Then,justselectfromFile|NewFile|RMarkdown...|FromTemplate|FlexDashboard|OK:

AswithmostRStudiodocuments,itcomesprefilledwiththeboilerplatecodetomakethestructureofadashboard.Youcanseethestructurestraightawayifyoulike,byclickingKnitinRStudio(orbycallingrmarkdown::render("yourFileName.Rmd")).

Theboilerplatedashboardlookslikethis:

Page 191: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Let'smakeaverysimplestaticdashboardfirsttolearnmoreaboutit,andthenwe'lllookatsomemoreadvancedlayoutfeaturesandaddsomeinteractiveShinyelements.Hereisthefinisheddashboard:

Page 192: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

I'veusedthedefaultlayoutthatisreturnedwhenyouselectaflexdashboardtemplate,whichisstructuredverysimplylikethis,bymodifyingtheheadings:

Column{data-width=650}

-----------------------------------------------------------------------

###Lifeexpectancyovertime

```{r}

*Code*

```

Column{data-width=350}

-----------------------------------------------------------------------

###Lifeexpectancy

```{r}

*Code*

```

###GDPpercapita

```{r}

*Code*

```

Asyoucansee,thedashboardislaidoutincolumns,withthewidthdefinedin{}bracketsateachcolumndefinition.Chunksaredefinedasyou'dexpectinanyRMarkdowndocument,with###asaheadingand```{r}...```wrappingthecode.Flexdashboardwillneatlyarrangetheoutputforyouincolumns.

Simple!Now,let'slookatdoingsomethingabitdifferentwiththelayout,and

Page 193: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

we'lladdsomeShinyatthesametime.ToturnaflexdashboardintoaShinydashboard,justaddruntime:shinytotheoptionsatthetop(thispartofthedocumentiscalledtheYAMLheader).Whilewe'rehere,let'salsolayouttheapplicationwithrows,ratherthancolumns.Simplychangeorientation:columnstoorientation:rows.

So,nowyourheadershouldlooklikethefollowing:

---

title:"Shinygapminder"

runtime:shiny

output:

flexdashboard::flex_dashboard:

orientation:rows

vertical_layout:fill

---

Let'snowdefineacolumnwithasidebarandplaceourcontrolsinitasnormal,asfollows:

```{rsetup,include=FALSE}

library(flexdashboard)

library(leaflet)

```

Column{.sidebar}

-----------------------------------------------------------------------

```{r}

sliderInput("year",

"Yearsincluded",

min=1952,

max=2007,

value=c(1952,2007),

sep="",

step=5

)

checkboxInput("linear",label="Addtrendline?",value=FALSE)

```

Andnow,wecanaccessthosevaluesasnormalintheoutput.Oneoftheoutputvaluesisdefinedasnormal,exceptasarowratherthanacolumn:

Row

-----------------------------------------------------------------------

###Lifeexpectancyovertime

```{r}

renderPlot({

thePlot=mapData%>%

filter(year>=input$year[1],year<=input$year[2])%>%

group_by(continent,year)%>%

summarise(meanLife=mean(lifeExp))%>%

Page 194: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ggplot(aes(x=year,y=meanLife,group=continent,colour=continent))+

geom_line()

if(input$linear){

thePlot=thePlot+geom_smooth(method="lm")

}

print(thePlot)

})

```

Notethat,inthiscase,wecan'tdefineareactiveobjecttofiltertheyearvalues,aswedidbefore,sowefilterbydatewithineachoutputitem(whichisbadcodingpracticeinanormalShinyapplication,ofcourse).We'llputtheotheroutputitemsinatabset,asfollows:

Row{.tabset}

-----------------------------------------------------------------------

###Lifeexpectancy

```{r}

renderLeaflet({

mapData%>%

filter(year==input$year[2])%>%

leaflet()%>%

addTiles()%>%

setView(lng=0,lat=0,zoom=2)%>%

addCircles(lng=~lon,lat=~lat,weight=1,

radius=~lifeExp*5000,

popup=~paste(country,lifeExp))

})

```

###GDPpercapita

```{r}

renderLeaflet({

mapData%>%

filter(year==input$year[2])%>%

leaflet()%>%

addTiles()%>%

setView(lng=0,lat=0,zoom=2)%>%

addCircles(lng=~lon,lat=~lat,weight=1,

radius=~log(gdpPercap)*25000,

popup=~paste(country,gdpPercap))

})

```

Andthat'sit.Prettysimple.Thefinishedarticlelookslikethis:

Page 195: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

It'saprettysmart-lookingdashboard,consideringhowsimpleitistocode.Therearelotsmoreoptionsforflexdashboards,includingtheuseofShinymodules(coveredinChapter8,CodePatternsinShinyApplications)aswellasdifferentmethodsoflayingoutflexdashboards.Visitthelinkgivenpreviouslyformoreinformation.Fortherestofthischapter,wewillbelookingatfullShinyapplications.

Page 196: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SidebarapplicationwithextrastylingAsawarmup,we'llsticktoasimplelayoutwithasidebarfornow.Asweprogressthroughthischapter,we'llchangethelayoutandmakeitmorelikeamoderndashboard.Becausewe'renotdoingtoomuchinthewayoffeaturesorlayoutinthisfirstapplication,we'lladdafewvisualbellsandwhistles.SomeofthemwillbedroppedinlaterversionsoftheapplicationjusttostopthecodeandUIfrombecomingtoocluttered,butyoucanofcoursewriteanapplicationyourselfwithalloftheUIelementsinifyouwishto.Allofthecodeanddatafortheapplicationsinthischapterisavailableatchrisbeeley.net/website/.

Page 197: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AddingiconstoyourUIAswegothroughthevariousUIelementslater,we'regoingtosprinkleafewiconsthroughout,justtogivethepageabitmorevisualinterest.Iconscancomefromtwoiconlibraries,locatedatfontawesome.io/icons/andgetbootstrap.com/components/#glyphicons.Theycanbeaddedsimplyusingtheicon()commandwiththenameoftherequiredicongivenasastring.

Forexample,icon("user")willbydefaultreturniconsfromtheFontAwesomelibrary,andtousetheglyphicons,simplyaddlib="glyphicon"asfollows:

icon=icon("user",lib="glyphicon")

TheycanbeaddeddirectlytoyourUIoronbuttons(includingthebuttonsatthetopoftabpanels).Fromthefullcodeofthisapplication,youcanseethatwehavereplacedtheboringhorizontalrule,whichseparatedourinputwidgets,withaspinningLinuxpenguin(because,woo!Linux!)usingclass="fa-spin".TheclassargumentcomesfromtheuseofCSSclassestovarythecharacteristicsofFontAwesomeicons.Theexamplesaregivenatfontawesome.github.io/Font-Awesome/examples/.YoucanalterthesizeofFontAwesomeiconswithclass="fa-lg"(onethirdlarger),class="fa-2x"(twiceaslarge),class="fa-3x",anduptoclass="fa-5x".Puttingthemtogether,wegetthefollowing:

icon("linux",class="fa-spinfa-3x")

Now,let'slookatstylingyourapplicationveryeasilyusingshinythemes.

Page 198: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

UsingshinythemesLet'sgivethewholeapplicationalickofpaintusingtheshinythemespackage.Ifyouhaven'talreadydoneso,installitwithinstall.packages("shinythemes").Thedocumentation(includingalistoftheavailablethemes)canbefoundatrstudio.github.io/shinythemes/.LoadthepackageandpassathemeintofluidPage():

library(shinythemes)

fluidPage(

theme=shinytheme("darkly"),

...restofUI...

Ifyouwanttochooseyourthemeinteractively,insteadaddthemeSelector()toyourUIdefinition,andalittleinteractivechooserwillappearonyourapp.Onceyou'rehappywithit,usethepreviouscodeformattomakethatthedefaultchoiceinyourapp:

library(shinythemes)

fluidPage(

themeSelector(),

...restofUI...

Enjoyyournewthemeandconsultthedocumentationfortheotheravailablethemesandtheappearanceofeach.

Andhere'sthefinishedapplication,showingthespinningpenguinandtheuserandcalendaricons,aswellasthethemechooserandoneofthethemes:

Page 199: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present
Page 200: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

UsingthegridlayoutInthenextversionoftheapplication,we'regoingtousethefluidRow()functiontoapplyacustomlayouttotheUI.ThisfunctionallowsyoutoimplementthestandardBootstrapgridlayout,aswesawinChapter4,MasteringShiny'sUIFunctions.

Thewidthofthescreenisgivenas12units,andyoucanpassthecolumn()functionsofarbitrarysizeintoafluidRow()instructiontodefineagroupofwidthsaddingupto12.Inthissimpleexample,wewillhavethreecolumnsinthefirstrowandthenoneinthesecondrow.Thefinishedapplicationlookslikethis:

Page 201: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ui.RLet'slookattheui.Rfilenecessarytoachievethis.Theserver.Rfileremainsthesameasinthepreviousexample.We'lltakebreaksaswestepthroughthecodetounderstandwhat'shappening.We'lldefinethetitlealittledifferentlyhere,justtomakethingsabitdifferent.Theactualtitleitselfgoesintheh2()HMTLhelperfunction,andweusestandardinlinemarkuptoselectthefont,color,andsize,asshown.ThetitleisgivenasanargumenttothefluidPage()function;thisgivesthebrowserwindowitstitle(it'sautomaticallysetbytitlePanel(),butwe'renotusingthathere):

fluidPage(

title="Gapminder",

h2("Gapminderexplorer",

style="font-family:'Impact';color:purple;font-size:32px;"),

Now,weaddinarowofUIelementsusingthefluidRow()functionanddefinetwoequalcolumnswithinthisrow.NoticetheuseofwellPanel()aroundsliderInput().Thisplacestheinputinsideapanelandgivesitabetter,moredefinedappearancenexttotheotherUIelements,aswellasfillingthehorizontalwidthofthecolumn:

fluidRow(

column(6,

wellPanel(

sliderInput("year",

"Yearsincluded",

min=1952,

max=2007,

value=c(1952,2007),

sep="",

step=5

))

),

column(6,

p("Mapdataisfromthemostrecentyearintheselectedrange",

style="text-align:center;"))

Next,weaddahorizontalruletobreakthescreenupabitandthetwooutputitems,boththemselvesplacedwithinfluidRow():

hr(),

fluidRow(

Page 202: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

column(6,plotOutput("trend")),

column(6,leafletOutput("map"))

),

Andaddonemorefluidrow,toplaceacheckboxwhereyoucanchooseifyouwantatrendlineandthetextualsummary,bothplacedheresotheyareunderneaththerelevantgraph:

fluidRow(

column(6,

checkboxInput("linear",label="Addtrendline?",

value=FALSE),

textOutput("summary")

)

)

Page 203: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

FulldashboardThiswillbethemostfull-featuredapplicationinthischapterandhasthelongestserver.Rfile.

Ideally,downloadtheapplicationcodeavailableatchrisbeeley.net/website/andrunitonyourmachine,orvisitahostedversion,alsoonthesite.Thereisquiteabitofnewfunctionalityinthisapplication,soit'sagoodideatoexploreitnow.

Ifyoucan'tdothis,therefollowsabriefoutlineofthenewfunctionalityintheapplication:

Notificationsinthetop-rightoftheinterfaceLargefriendlyicons(informationboxes)forkeyfigureswithicons(calendar,person,piechart,Shinyversion,andsoon)Agauge

Thefinisheddashboardlookslikethis:

We'llstartbylookingatthecodeforeachoftheseadditionsandthenmoveontolookathowthewholeUIisputtogetherusingtheshinydashboardpackage.

Page 204: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

NotificationsTheabilitytocreatenotificationsispartofalargeramountoffunctionalitywithinshinydashboard,whichallowsyoutocreatemessages,tasks,andnotificationsintheheaderofyourdashboard.Formoredetails,visitrstudio.github.io/shinydashboard/structure.html.

Inthisexample,we'lljustaddnotifications.Thecodeisverysimilartotheothertwotypesofcontent.StaticnotificationscanbeproducedwiththenotificationItem()functionasfollows(withtheoptionalstatusandcolorargumentsnotusedhere):

notificationItem(text="3userstoday",icon("users"))

Inordertoproducecontentdynamically,weneedtodoabitmorework.Ontheserver.Rside,thecodeisasfollows.Itallowsthenotificationcontenttoberendereddynamicallyandcalledintheui.RfilewithdropdownMenuOutput("notifications"):

output$notifications<-renderMenu({

countries=length(unique(theData()$country))

continents=length(unique(theData()$continent))

notifData=data.frame("number"=c(countries,continents),

"text"=c("countries","continents"),

"icon"=c("flag","globe"))

notifs<-apply(notifData,1,function(row){

notificationItem(text=paste0(row[["number"]],row[["text"]]),

icon=icon(row[["icon"]]))

})

dropdownMenu(type="notifications",.list=notifs)

})

Thevaluesneedfirsttobeplacedwithinadataframe,asshown.Thedynamicelementisgivenbycountriesandcontinents,definedasthenumberofcountriesandcontinents,respectively.Textdescribingwhatthevaluerepresentsandaniconarealsoaddedtothedataframe.Thefinalnotifsvalueisproducedusingafunctionthat'sgivenasanexampleinthehelpfiles,asyoucanseeititerateovertherowsofthedataframeandchangethenotificationsintothecorrectvalue.Asyoucansee,thedataframethatweproducedisprocessedrow-wisewiththe

Page 205: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

appropriatevaluesfortextandiconbeingproduced(text="142countries",icon="flag",andtext="5continents",icon="globe").Finally,theyaregiventodropdownMenu()astheargumentto.list.Noticethatwealsodefinethetypeastype="notifications".

Havingdoneallthis,theactualnotificationsarepassedintotheheaderintheui.Rfilequitesimply,likethis:

header<-dashboardHeader(title="Gapminder",

dropdownMenuOutput("notifications"))

Thislooksalittledifferenttotheusualstructurethatwehaveencountered,whichisbecause,unlikestandardShinyinterfaces,Shinydashboardsareconstructedfromthreeseparatesections:dashboardHeader(),dashboardSidebar(),anddashboardBody().WewilllookindetailattheconstructionofaShinydashboardinthesectiononui.Rlater.

Page 206: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

InfoboxesWehavealreadyseenhowtouseiconsearlierinthischapter,butshinydashboardmakesanicefeatureofitbyexpandingandcoloringiconstodrawattentiontokeypiecesofinformation.Aninfoboxcanbedrawnstaticallyasfollows:

infoBox(width=3,"Shinyversion","1.1.0",

icon=icon("desktop"))

Asyoucansee,thewidthcanbeset(usingthe12spanrulefromthestandardBootstrapfunctionswesawearlierinthischapter)withatitle(Shinyversion)andvalue(1.1.0)(althoughyoumayoftenwishtopassanumber).ThisfunctionisplacedwithindashboardBody()intheui.Rfile.Formoreinformationontheargumentsofthisfunction,type?infoBoxintotheconsole.

Althoughyoumaysometimeswishtohardcodeinfoboxesinthisway(toshowversionnumbersofanapplication,asinthiscase),inthemajorityofcases,youaregoingtoproducethiscontentdynamically.Inthiscase,youwillasalwaysneedtodosomepreparationonserver.Rfirst.Hereisthecodeforthefirstinfobox:

output$infoYears<-renderInfoBox({

infoBox(

"Years",input$year[2]-input$year[1],

icon=icon("calendar",lib="font-awesome"),

color="blue",

fill=ifelse(input$year[2]<2007,

TRUE,FALSE)

)

})

Thefirsticonisthenumberofdayswithinthespecifiedrange.Thefirstargumentgivestheiconatitle,Years,andthesecondgivesitavalue(thenumberofyears,calculatedbysubtractingthefirstyearfromthesecond).Youcanalsoselectthecoloroftheboxandwhethertheright-handportion(whichcontainsthetext,asopposedtotheicon)isfilled(asolidcolor)ornot.

Asyoucansee,herewearedecidingthefillofthevalueportionoftheicondynamically.Whenthelargestyearintherangeislowerthan2007,theiconwillbefilled.Ifitisn't,itwon't.See?ifelseforhelpwithifelse().

Page 207: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Theotherdynamicinfoboxesaresetupinthesameway,asfollows:

output$infoLifeExp<-renderInfoBox({

infoLifeExp=theData()%>%

filter(year==2007)%>%

group_by(continent)%>%

filter(continent==input$continent)%>%

pull(lifeExp)%>%

mean()%>%

round(0)

infoBox(

"LifeExp.(2007)",infoLifeExp,

icon=icon("user"),

color="purple",

fill=ifelse(infoLifeExp>60,

TRUE,FALSE)

)

})

output$infoGdpPercap<-renderInfoBox({

infoGDP=theData()%>%

filter(year==2007)%>%

group_by(continent)%>%

filter(continent==input$continent)%>%

pull(gdpPercap)%>%

mean()%>%

round(0)

infoBox("GDPpercapita",

infoGDP,

icon=icon("usd"),

color="green",

fill=ifelse(infoGDP>5000,

TRUE,FALSE)

)

})

Page 208: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ui.RTheui.Rfiletodisplaydynamicinfoboxesissimilartothefunctionwealreadysawtodisplaystaticinfoboxes,exceptnowthefunctionisinfoBoxOutput().Puttingallfourinfoboxestogether,wenowgetthefollowing:

fluidRow(

infoBoxOutput(width=3,"infoYears"),

infoBoxOutput(width=3,"infoLifeExp"),

infoBoxOutput(width=3,"infoGdpPercap"),

infoBox(width=3,"Shinyversion","1.1.0",

icon=icon("desktop")))

Aselsewhere,ineachcaseinfoBoxOutput()isgivenastring(infoYears),whichreferstothenameofthecorrespondingoutputelement(output$infoYears).

Page 209: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

GoogleChartsgaugeThegaugewithGDPpercapitaisfromtheexcellentGoogleChartsAPI.Moreinformationonthiscanbefoundatdevelopers.google.com/chart/.Fortunatelyforus,thereisanRpackagetointerfacewithGoogleCharts,sothereisnoneedtogetourhandsdirtywithadifferentAPI.ThepackageisonCRANandcanbeinstalledwithinstall.packages("googleVis").

Installandloaditnow.Thecodeisasfollows:

output$gauge=renderGvis({

infoGDP=theData()%>%

filter(year==2007)%>%

group_by(continent)%>%

filter(continent==input$continent)%>%

pull(gdpPercap)%>%

mean()%>%

round(0)

df=data.frame(Label="GDP",Value=infoGDP)

gvisGauge(df,

options=list(min=0,max=50000,

greenFrom=5000,greenTo=50000,

yellowFrom=5000,yellowTo=25000,

redFrom=0,redTo=5000))

})

Adataframeisproduced,withthefirstcolumnbeingthelabelforthegauge,andthesecondthevalueofthegauge.Ifyourequiremorethanonegauge,simplyincludemultiplerows.Inthiscase,wewilljustuseonerow.Thegaugeisdrawnverysimplybypassingthedataframeandalistofoptions,whicharefairlyself-explanatory,givingtheminimumandmaximumforthegauge,aswellasthelimitswherethegaugeisgreen,yellow,andred,ifdesired.Thegaugeisdrawnverysimplyinui.RusinghtmlOutput("gauge").

Page 210: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ResizingtheGooglechartSofar,sosimple.However,thereisaproblem!Googlevisualizationcharts,unlikenativeRvisualizations,arenotautomaticallyresizedwhenthebrowserwindowchanges.We'regoingtofixthisproblemverysimply,usingsomevaluesthatwecanextractfromthesessionargumentoffunction(input,output,session){...}.Shinymakeslotsofthingsavailableinthisvariable,andoneofthemostusefuloftheseissession$clientData.Thistellsyoulotsofthingsaboutyouruser'sbrowser,suchasthepixelratio,aswellastheheightandwidthofindividualoutputelementswithintheapplication.Formoreontheusesofthesessionargument,seeshiny.rstudio.com/reference/shiny/1.0.2/session.html.Inourcase,allweneedtodoisestablishadependencyonsomethingwithinthisclientdata,whichwillchangewheneverthebrowserwindowresizes.

Inthiscase,output_trend_widthisperfect.Thisisthewidthofthelineplotshowinglifeexpectancyovertime.Thesevariablesarenamed,forexample,output$clientData$output_nameOfOutput_width.Whenthebrowserisresized,thispropertywillchange.We'renotreallyworriedaboutheightbecausethereisn'tanythingtobumpagainstthegaugebelowit,onlytotheleftandright.Thecodetodrawthegaugethereforebecomesasfollows:

output$gauge<-renderGvis({

#dependenceonsizeofplotstodetectaresize

session$clientData$output_trend_width

[...asbefore...]

})

Changingthewidthofthebrowserwindowwillnowredrawthegauge,whichwillmakeittherightsizeagain.

Page 211: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ui.RHavingexaminedallthenewelements,wecanhavealookathowShinydashboardsareputtogether.Aswasbrieflymentionedpreviously,Shinydashboardsarecomposedofthreepieces;dashboardHeader(),dashboardSidebar(),anddashboardBody().Theycanbeputtogetherlikethis:

dashboardPage(

dashboardHeader([...]),

dashboardSidebar([...]),

dashboardBody([...])

)

Or,theycanbeputtogetherlikethis:

#producecomponents

header<-dashboardHeader([...])

sidebar<-dashboardSidebar([...])

body<-dashboardBody([...])

#assemble

dashboardPage(header,sidebar,body)

Personally,Ihaveastrongpreferenceforthelatterformat,sinceitseemstometomakethecodesimplerandeasiertoread(nottomentionwithlessindentation),butyoumayprefertheotherway.

Wealreadysawtheheaderpartoftheapplicationpreviously;thisisreproducedinthefollowingcodeforconvenience.Notealsothat,unlikeinmanyShinyapplications,itisnecessarytoloadseveralpackagesintheui.Rfilebecausetherearespecialfunctionswithinthosepackages,whichgetcalledwiththefile(forexample,dashboardHeader(),leafletOutput(),andothers).Thetopoftheui.Rfilethereforelooksasfollows:

library(shinydashboard)

library(leaflet)

header=dashboardHeader(title="Gapminder",

dropdownMenuOutput("notifications"))

Thesidebarcancontaininputwidgets,asistypicalinShinyapplications,butalsobuttonstoselectdifferenttabsofthedashboard,eachofwhichcanbesetuptohavedifferentoutputelementsonit.Inthiscase,wehavetwotabs:themainonecontainsthegraphsandiconswehavespentmostofthissectiondiscussing,

Page 212: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

andthemaptabcontainingtheinteractiveleafletmap.

Thecodeisasfollows:

sidebar<-dashboardSidebar(

sidebarMenu(

menuItem("Dashboard",tabName="dashboard",

icon=icon("dashboard")),

menuItem("Map",icon=icon("globe"),tabName="map",

badgeLabel="beta",badgeColor="red"),

Thefirsttwoitemsaretabbuttonsthatwillallowustopresentdifferentsetsofoutputelementstousers.Eachisgivenatitle(DashboardandMap),aname(dashboardandmaps),andanicon(dashboardandglobe).Theseconditemcangiveusersextrainformationaboutthetab—inthisexample,showingthattheoutputelementsonthattabarestillinbeta,usingthebadgeLabelandbadgeColorarguments,givingaredbetainthiscase.

Therestofthesidebarsetupisfamiliarfrompreviousincarnationsofthisapplication,asfollows:

menuItem("Map",icon=icon("globe"),tabName="map",

badgeLabel="beta",badgeColor="red"),

sliderInput("year",

"Yearsincluded",

min=1952,

max=2007,

value=c(1952,2007),

sep="",

step=5

),

selectInput("continent","Selectcontinent",

choices=c("Africa","Americas","Asia",

"Europe","Oceania"))

I'veaddeda"continent"selector,whichtheinfoboxesandgaugerespondto,showingtheaveragelifeexpectancyandGDPpercapitafortheselectedcontinent.Finally,dashboardBodyissetupusingatabItems(tabItem(),tabItem())structure:

body=dashboardBody(

tabItems(

tabItem(tabName="dashboard",

fluidRow(

infoBoxOutput(width=3,"infoYears"),

infoBoxOutput(width=3,"infoLifeExp"),

infoBoxOutput(width=3,"infoGdpPercap"),

infoBox(width=3,"Shinyversion","1.1.0",

icon=icon("desktop"))),

Page 213: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

fluidRow(

box(width=10,plotOutput("trend"),

checkboxInput("linear",

label="Addtrendline?",

value=FALSE)),

box(width=2,htmlOutput("gauge"))

)

),

tabItem(tabName="map",

box(width=12,leafletOutput("map"),

p("Mapdataisfromthemostrecentyearintheselectedrange"))

)

)

)

Eachtabitemwillbepassedintohere;inthiscase,wehavetwo,aswesawinthepreviouscode-dashboardandmap.Nowyoucanputanythingyoulikeinit.Inthiscase,wehaveafluidrowwithfourinfoboxesofwidthof3(thetotalwidthbeing12,ofcourse).Thefirstthreearethedynamicinfoboxesthatwesetupintheserver.Rfile,andthethirdisastaticversion.Thecodeforthestaticversion,too,isfeaturedearlierinthissection.Wefinishthetabitemwithanotherfluidrow.Notetheuseofthebox()functionthatdrawswhiteboxesaroundtheelementsofadashboard.

Wefinishwiththefinaltab,map,which,ascanbeseen,containsjustoneboxwiththemapinandacommentaboutthedatainthemap.

Page 214: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SummaryInthischapter,weexploredmanydifferentwaysoflayingoutthesameapplications.WelookedatbothstaticandShiny-basedinteractiveflexdashboards.Startingwiththestandardsidebarlayout,welookedataddingiconsandusingtheshinythemespackagetoquicklystyleavanillaapplication.Weexploredthefunctionalityoftheshinydashboardpackage,whichallowsyoutoproducetabbedoutputsections;addintasks,notifications,andmessagesforyourusers;showlargefriendlyiconswithkeyinformationon;andprovideanattractiveandprofessional-lookingdefaultappearance.

Thekeytomakingthemostofthematerialinthischapter,aswellasofShinygenerally,istorememberthatyoucancombinethetoolsthatShinygivesyouinalotofdifferentways,dependingonyourneedsandyourskillset.There'snothingtostopyoufromusingtheshinydashboardpackagewithsomehighlycustomizedHTMLinoneofthetabsifyouneedtoverypreciselybuildaparticularkindofinterface.Somedevelopers,whohavemoreexperiencewithJavaScriptthanwithR,mayprefertoworkwiththeGoogleChartsAPIinJavaScriptanduseShinyasjustadataworkhorse,servingdataorstatisticsstraighttotheJavaScriptfunction.Thinkaboutwhatyouneed,andtherewillusuallybeacoupleofwaystoachieveit.Thesolutionyoupickwillbebasedpartlyonproducinganapplicationthatissimple,clean,andeasytomaintainanddebug.

Inthenextchapter,wearegoingtolookatgettingthemostoutofShinybyusingcustomURLstrings,producinginteractiveplots,addingpasswords,downloadinganduploadingdata,andmore.

Page 215: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

PowerShinyInthischapter,wearegoingtolearnmanypowerfulfeaturesofShiny.Wewillstartwithanimatingplots.Afterthat,wewilldiscusshowtoreadclientinformationandgetrequestsinShiny.Nowadays,tellingastoryaboutthedataininteractiveandreportingwaysisindemand.So,wewillgothroughgraphicsandreport-generation,andhowtodownloadthemusingknitr.Downloadinganduploadingisalsoaninterestingpartofanyapplication,whichwewillseeusingsomeexamples.Bookmarkingthestateoftheappisanadd-ontoregeneratetheoutputontheapp.Wewillseeademonstrationofthefastdevelopmentofappsusingwidgetsandgadgets.Attheendofthechapter,wewilllookathowtoauthenticatetheappusingapassword.

Inthischapter,wewillcoverthefollowingtopics:

AnimationReadingclientinformationandGETrequestsinShinyCustominterfacesfromGETstringsDownloadinggraphicsandreportsDownloadablereportswithknitrDownloadinganduploadingdataBookmarkingInteractiveplotsInteractingwithtablesLinkinginteractivewidgetsShinygadgetsAddingapassword

Page 216: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AnimationAnimationissurprisinglyeasy.ThesliderInput()function,whichprovidesanHTMLwidgetthatallowsustoselectanumberalongaline,hasanoptionalanimationfunctionthatwillincrementavariablebyasetamounteverytimeaspecifiedunitoftimeelapses.Thisallowsyoutoveryeasilyproduceagraphicthatisanimated.

Inthefollowingexample,wearegoingtolookatthemonthlygraphandplotalineartrendlinethroughthefirst20%ofthedata(0-20%ofthedata).Then,wearegoingtoincrementthepercentagevaluethatselectstheportionofthedataby5%andplotalinearthroughthatportionofdata(5-25%ofthedata).Then,incrementby10-30%andplotanotherline,andsoon.

Thesliderinputissetupasfollows,withanID,label,minimumvalue,maximumvalue,initialvalue,stepbetweenvalues,andtheanimationoptions,givingthedelayinmillisecondsandwhethertheanimationshouldloop:

sliderInput("animation","Trendovertime",

min=0,max=80,value=0,step=5,

animate=animationOptions(interval=1000,

loop=TRUE))

Havingsetthisup,theanimatedgraphcodeisprettysimple,lookingverymuchlikethemonthlygraphdataexceptwiththelinearsmoothbasedonasubsetofthedatainsteadofthewholedataset.Thegraphissetupasbeforeandthenasubsetofthedataisproducedonwhichthelinearsmoothcanbebased:

groupByDate<-group_by(passData(),YearMonth,networkDomain)%>%

summarise(meanSession=mean(sessionDuration,na.rm=TRUE),

users=sum(users),

newUsers=sum(newUsers),sessions=sum(sessions))

groupByDate$Date<-as.Date(paste0(groupByDate$YearMonth,"01"),

format="%Y%m%d")

smoothData<-groupByDate[groupByDate$Date%in%

quantile(groupByDate$Date,

input$animation/100,

type=1):quantile(groupByDate$Date,

(input$animation+20)/100,

type=1),]

Page 217: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Wewon'tgettoodistractedbythiscode,butessentially,itteststoseewhichofthewholedaterangefallsinarangedefinedbypercentagequantilesbasedonthesliderInput()values.Takealookat?quantileformoreinformation.

Finally,thelinearsmoothisdrawnwithanextradataargumenttotellggplot2tobasethelineonlyonthesmallersmoothDataobjectandnotthewholerange:

ggplot(groupByDate,aes_string(x="Date",

y=input$outputRequired,

group="networkDomain",

colour="networkDomain"))+geom_line()+

geom_smooth(data=smoothData,

method="lm",colour="black")

Notbadforafewlinesofcode.Wehavebothggplot2andShinytothankforhoweasythisis.

Page 218: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ReadingclientinformationandGETrequestsinShinyShinyincludessomeveryusefulfunctionalitythatallowsyoutoreadinformationfromaclient'swebbrowser,suchasinformationfromtheURL(includingGETsearchrequests)andthesizeofplotsinpixels.

Allyouneedtodo,asbefore,isrunshinyServer()withasessionargument.Thiscauses,amongotherthings,anobjecttobecreatedthatholdsinformationaboutaclient'ssession,namedsession$clientData.

Theexactcontentofthisobjectwilldependonwhatisopenonthescreen.Thefollowingobjectswillalwaysexist:

url_hostname#hostname,e.g.localhostorchrisbeeley.net

url_pathname=#path,e.g./or/shiny

url_port=#portnumber(8100forlocalhost,canoptionally

#changewhenhosting,seechapter5)

url_protocol=#highlylikelytobehttp:

url_search=#thetextafterthe"?"intheURL.Inthe

following

#examplethiswillread"?person=NHS&smooth=yes".

Differentoutputtypeswillyielddifferentinformation.Plotswillgivethefollowinginformation,amongotherreturnvalues:

output_myplot_height=#inpixels

output_myplot_width=#inpixels

Therearemanyapplicationstowhichthisinformationcanbeput,suchasgivingdifferentUIsordefaultsettingstousersfromdifferentdomains,orconfiguringgraphsandotheroutputbasedontheirsize(forexample,foruserswhoareusingmobiledevicesor32"monitors).We'regoingtolookatperhapsthemostobviousandpowerfuluseofclientdata:thesearchstring.

Page 219: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

CustominterfacesfromGETstringsInthisexample,we'regoingtoproduceURLsthatallowShinytoconfigureitselfwhentheuserlandsonthepagetosavethemfromhavingtosetuptheirpreferenceseachtime.Wewillmakeuseoftwovariables:onespecifiesthatauserisonlyinterestedindatafromtheNHSnetworkdomainandtheotherspecifiesthattheuserwantsasmoothinglinepresentontheirtrendgraph.Userswhorequestasmoothinglinewillalsobetakenstraighttothetrendlinetab.

AswellastheworkwiththeGETquery,theonlyextrabitwewillneedhereisafunctiontochangetheselectedpanelfromtabsetPanel().Thisisdone,unsurprisingly,usingupdateTabsetPanel().

CateringtothesedifferentneedsisveryeasilydonebycreatingURLsthatencodethepreferencesandgivingthemtothedifferentusers.Tosimplifythecode,wewillpretendthat,iftheyarepassedatall,thecorrectnumberofsearchtermsisalwayspassedinthecorrectorder.ThisisareasonableassumptionifyouwritetheURLsyourself.Inareal-worldexample,theURLsaremostlikelygoingtobegeneratedprogrammaticallyfromaUI.Correctlyparsingthemisnottoochallenging,butitisnotreallythefocusofthediscussionhere.ThefollowingarethetwoURLswewillgiveout:

feedbacksite.nhs.uk/shiny?person=NHS&smooth=yesfeedbacksite.nhs.uk/shiny?person=other&smooth=no

Asinthepreviousexample,thecodeiswrappedinobserve(),andthefirstportionofthecodereturnsthesearchtermsfromtheURLasanamedlist:

observe({

searchString<-parseQueryString(session$clientData$url_search)

...

Havingdonethis,wecanthencheckthatsearchStringexists(incaseotheruserslandfromthedefaultURL)and,ifitdoes,wecanchangethesettingsaccordingly.TheupdateTabsetPanel()commandusesalotoftheconceptswealreadysawwhenwereadthetabthatwasselected.Thefunctiontakesasessionargument,aninputIdargument(thenameofthepanel),andaselectedargument

Page 220: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

(thenameofthetab):

#updateinputsaccordingtoquerystring

if(length(searchString)>0){#ifthesearchStringexists

#dealwithfirstquerywhichindicatestheaudience

if(searchString[[1]]=="nhs"){#forNHSusersdothefollowing

updateCheckboxGroupInput(session,"domainShow",

choices=list("NHSusers"="nhs.uk",

"Other"="Other"),selected=c("nhs.uk"))

}

#dotheywantasmooth?

if(searchString[[2]]=="yes"){

updateTabsetPanel(session,"theTabs",selected="trend")

updateCheckboxInput(session,inputId="smooth",

value=TRUE)

}

}

})

Thisisclearlyaverypowerfulwaytomaketheexperiencebetterforyouruserscompletelytransparently.Youmaywishtospendabitoftimesettingupawebinterfaceinwhateverlanguageyoulike(PHP,JavaScript,andsoon)andcorrectlyparsingtheURLsthatyougeneratewithinShiny.Ifyouneedtohandlevaryinglengthsandnamesoflists,youwillneedafewextracommands:

names(theList):Givesyouthenameofeachreturnvaluelength(unlist(theList)):Tellsyouhowlongthelistis

Page 221: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DownloadinggraphicsandreportsTheoptiontodownloadgraphicsandreportscanbeaddedeasilyusingdownloadHandler().Essentially,downloadHandler()hastwoargumentsthatbothcontainfunctions:onetodefinethepathtowhichthedownloadshouldgo,andonethatdefineswhatistobedownloaded.

Thefirstthingweneedtodoistakeanyfunctionsthatareusedeitherinthedownloadgraphicrequestorthereportandmakethemreactivefunctions,whichcanbecalledfromanywhereratherthaninstructionstodrawagraphwithinacalltorenderPlot().Theeffectofthis,ofcourse,isthatweonlyhaveonefunctiontowriteandmaintainratherthanoneinsidethedownloadgraphicfunction,oneinsidethedownloadreportfunction,andsoon.Thisisachievedverysimply:

trendGraph<-reactive({

...restoffunctionthatwasinsiderenderPlot

})

Thegraphcannoweasilybeprintedwithinthetrendtab:

output$trend<-renderPlot({

trendGraph()

})

We'llgothroughthefollowingcodefromserver.Rstepbystep:

output$downloadData.trend<-downloadHandler(

filename<-function(){

paste("Trend_plot",Sys.Date(),".png",sep="")

},

Thisisthefilenamefunction,andasyoucansee,itproducesfilenameTrend_plot_XX_.pngwhereXXisthecurrentdate:

content<-function(file){

png(file,width=980,height=400,

units="px",pointsize=12,

bg="white",res=NA)

trend.plot<-trendGraph()

print(trend.plot)

dev.off()

},

Thisisthecontentfunction,andasyoucansee,itopensapngdevice(?png),calls

Page 222: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

areactivefunctionnamedmyTrend(),whichdrawsthegraph,printstothedevice,andcloseswithacalltodev.off().YoucansetupthetrendGraph()functionsimply;inthiscase,itisjustlikethefunctionthatdrawsthegraphitself,exceptinsteadofbeingwrappedinrenderPlot()toindicatethatitisaShinyoutputitisjustdefinedasareactivefunction.

Finally,thefollowingisgiventotellShinywhattypeoffiletoexpect:

contentType='image/png')

Addingthedownloadbuttontotheui.Rfileissimple;thedownloadButton()functiontakesthenameofthedownloadhandlerasdefinedinserver.Randalabelforthebutton:

tabPanel("Trend",plotOutput("trend"),

downloadButton("downloadData.trend","Downloadgraphic")

Asyoucansee,Ihaveaddedthebuttonunderneaththegraph,sousersknowwhattheyaredownloading.

Page 223: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DownloadablereportswithknitrThissamefunctioncanveryeasilyallowyouruserstoproducecustomreportsinHTML,pdf,orMSWordreadytobedownloadedtotheirmachines,usingtheknitrpackage(http://yihui.name/knitr/).knitrisauser-contributedpackagethatallowsreportstobegenerateddynamicallyfromamixtureofastaticreportformatsinterleavedwiththeoutputfromofR.

So,forexample,titlesandtextcanbefixed,buteachtimethereportisrun,adifferentoutputwillbeproducedwithinthedocumentdependingonthestateofthedatawhentheoutputisgenerated.knitrcanbeusedwiththeRMarkdownformat.HereisthesimpleRMarkdowndocumentwithintheGoogleAnalyticsapplication:

#Summaryreport

##Textsummary

Thisreportsummarisesdatabetween`rstrftime(input$dateRange[1],

format="%d%B%Y")`and`rstrftime(input$dateRange[2],

format="%d%B%Y")`.

##Trendgraph

```{rfig.width=7,fig.height=6,echo=FALSE}

trendGraph()

```

Ascanbeseen,thedocumentisamixofstaticheadingsandtext,inlineRoutput(givenas`r"print("somthing")`),andgraphicaloutput.ThetrendGraph()function,ofcourse,isthesametrendGraph()functionthatwesawinthedownloadgraphicscode.

Thecodetodownloadthereportisasfollows(withtheRMarkdowndocumentinthesamefolderasserver.RandnamedReport.Rmd):

output$downloadDoc<-

downloadHandler(filename="Report.html",

content=function(file){

knit2html("Report.Rmd",envir=environment())

#copydocumentto'file'

file.copy("Report.html",file,

overwrite=TRUE)

}

)

Page 224: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Addingabuttontodownloadthegraphisthesameasforthedownloadinggraphfunction;thefollowingshouldbeplacedinui.RwithinthesidebarPanel()function:

downloadButton("downloadDoc","Downloadreport")

Page 225: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DownloadinganduploadingdataDownloadingdataisdoneinasimilarfashion,whichlookslikethefollowingdownloadHandler()call:

output$downloadData<-downloadHandler(

filename=function(){

"myData.csv"

}

content=function(file){

write.csv(passData(),file)

}

)

UploadingdataisachievedusingthefileInput()function.Inthefollowingexample,wewillassumethattheuserwishestouploadacomma-separatedspreadsheet(.csv)file.Thebuttonisaddedtoui.Rinthefollowingmanner:

fileInput("uploadFile","UploadyourownCSVfile")

Thisbuttonallowsausertoselecttheirown.csvfile,anditalsomakesavarietyofobjectsbasedontheID(inthiscase,input$uploadFile$)availablefromserver.R.Themostusefulisinput$uploadFile$datapath,whichisapathtothefileitselfandcanbeturnedintoadataframeusingread.csv():

userData<-read.csv(input$uploadFile$datapath)

Thereareotherbitsofinformationaboutthefileavailable.Takealookat?fileInputformoredetails.

Page 226: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

BookmarkingInternetusersarefamiliarwiththetermbookmarking.Ifwearesurfingasiteandthinkit'ssomethingimportantthatwe'dliketovisitagain,weusuallybookmarkit.HowaboutthebookmarkingaShinyapp?AstheShinyapphasdatarepresentationandinput/outputinteractions,savingthisstateusingbookmarkingandthenreproducingitwillrequiresomecodingexpertise.

Inthissection,wearegoingtofocusonhowtobookmarkthestateofaShinyapp.WewillseecodingmodificationsinthebasicstructureoftheShinyappneededtoincorporatethebookmarkingfeature.Wewillexplorebookmarkingastate,andsomeexceptionalcasesandhowtodealwiththem.

Page 227: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

BookmarkingstateThestateofanapplicationcanbedefinedasthestateofinputandoutputatagiventime.InShinyapps,thestateoftheinputandoutputcanbetheinputintheinputboxandtheoutputintheoutputboxoragraphataparticulartime.Here,ouraimistosaveastateatagiventimeandrestoreit.AsofnowwehavelearnedaboutthestructureofShinyapps.Shinyappscanbeasinglefile(UIandServerfiletogether)ormultiplefiles(UI,Severorglobalfilesseparately).Andtherecanbeappswheretheflowofinputandoutputcanbestraightforwardornotstraightforward.Astraightforwardcontrolflowofanappcanbeconsideredastheappthathasadeterministicoutputforaninputandvice-versa.Inthissection,wewilllearntoprogramthebookmarkingfeaturesforthestateofappswithastraightforwardcontrolflow.

Themethodsofbookmarkingcanbeclassifiedintotwocategories:

BookmarkingbyEncodingthestateintoaURLBookmarkingbysavingthestatetotheserver

Inboththemethods,thebasicconceptistopreservethestateoftheapplicationataparticulartime.Thedifferenceliesinhowtosavethestate.Let'sdiscussboththemethodsindetail.

Page 228: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

EncodingthestateintoaURLInthismethodofbookmarkingthestate,thestateoftheappisembeddedintoaURL.Aswehavediscussed,thestateoftheapplicationmeanstheinputandoutputvaluesataparticulartime.So,theinputandoutputvaluesareembeddedintheappforatimeinstance.TheinputandoutputvaluescanbeseenintheURLitself.AswearefamiliarwiththecodingofShinyapps,thedifferenceswithbookmarkingarethattheUIhastobereturnedasavalueofafunctionwithasingleargumentandenableBookmarking()hastobecalled.WhenwediscussedthedifferentstylesofcodingaShinyappinsinglefileormultiplefiles,welearnedweneedtounderstandhowtoimplementtherequirements-implementingUIwithasingleargumentfunctionandusingenableBookmarking().

Page 229: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Single-fileapplicationSingle-fileappshaveUIandservercodeinthesamefile.Forsuchacodingstyle,theappskeletoncanbegivenasfollows:

ui<-function(request){#UIcode}

server<-function(input,output,session){#ServerCode}

shinyApp(ui,server,enableBookmarking="url")

WecanseethattheUIcodeisreturnedasafunctionratherthanfluidpageoranyotherUIelement.Andinthelastlineofcode,theenableBookmarkingargumentissetto"url".TherestofthecodeissimilartoShinyapps.Let'sdevelopanappwiththeprecedingskeletonthatfindsthesquareofanumber.StartingwithUI,thereisatextInput()boxforgettingtheinput,verbatimTextOutput()forshowingoutput,andbookmarkButton()forbookmarking:

ui<-function(request){

fluidPage(

textInput("inptxt","EnterNumber"),

verbatimTextOutput("outsquare"),

bookmarkButton())

}

Intheservercode,wehavetocalculatethesquareoftheinputtednumberandsenditfordisplay.WecanseeinthefollowingcodethatrenderText()isfirstconvertingtheinputtedtextintoanumberandthencalculatingthesquare:

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

output$outsquare<-renderText({

(as.numeric(input$inptxt)*as.numeric(input$inptxt))

})}

Inthelast,wehavetocallshinyApp()inwhichwearepassingtheenableBookmarkingargumentas"url":

shinyApp(ui,server,enableBookmarking="url")

Let'shavealookatoutputofthecode:

Page 230: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Wecanseethatintheapp,theinputis2andtheoutputvalueis4.ThebookmarkwindowshowsthelinkedURLwithsomevaluesthatareencodingtheinput/output,http://127.0.0.1:4255/?_inputs_&inptxt=%222%22.

SinglefileShinyapplicationscanalsobereturnedbyafunction.Let'srecreatethesquareapplicationusingfunction:

App<-function(){

ui<-function(request){

fluidPage(

textInput("inptxt","EnterNumber"),

verbatimTextOutput("outsquare"),

bookmarkButton()

)

}

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

output$outsquare<-renderText({

(as.numeric(input$inptxt)*as.numeric(input$inptxt))

})

}

shinyApp(ui,server,enableBookmarking="url")

}

Toruntheapp,copythecodeintoanRScriptfile,selectallcode,andrunit.Afterthat,wecanexecutethecodeusingApp()inconsoleorRScript.enableBookmark()canalsobesetatthebeginningoftheappcode.

Now,wearereadytodevelopourapplicationformultiplefiles.

Page 231: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Multiple-fileapplicationInShinyapplicationswhereUIandservercodesarekeptinseparatefiles,enableBookmarking()hastobekeptintheglobal.rfile.Therestofthethingsarethesame.Forredevelopingthesquared-numberappinamultiple-filepattern,wehavetocopytheUIcodeandpasteitintotheui.rfileandservercodeintheserver.rfilewithenableBookmarking(store="url")intheglobal.rfile.Wewillgetthesameoutputaswegotinthesingle-fileimplementation.

Page 232: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

BookmarkingbysavingthestatetotheserverInthismethod,theonlymodificationintermsofcodingistochangetheenableBookmarkingargumenttotheserver.Let'srecreatethesquare-calculationapplicationusingsavingstatetotheserver:

ui<-function(request){

fluidPage(

textInput("inptxt","EnterNumber"),

verbatimTextOutput("outsquare"),

bookmarkButton()

)

}

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

output$outsquare<-renderText({

(as.numeric(input$inptxt)*as.numeric(input$inptxt))

})

}

shinyApp(ui,server,enableBookmarking="server")#savingtotheserver

Howdoesitmakeadifferenceinprocessing?SavingstatetotheservermethodsavesthestateoftheapplicationontheserverinsteadofembeddingthestatesintoaURL.Shinyprovidestwoversionsofservers.OneistheopensourceShinyserver,andtheotherisShinyserverpro.InShinyserver,thestateoftheapplicationissavedinthe/var/lib/shiny-server/bookmarkssubdirectory.RStudioConnectalsostoresthebookmarkstatein/var/lib/rstudio_connect/bookmarks.WeusuallyexperimentwithourapplicationsondesktopversionsofRstudio.Insuchcases,thestateissavedintheshiny_bookmarks/subdirectory.

Theadvantageofusingsavingstateintheserveristhatfilescanalsobebookmarked,whichisnotpossiblewithbookmarkingwithencoding.LargefilesarenotsupportedbybookmarkingwithaURL.Tosavestateontheserver,thehostingenvironmentmustbesupported.

Asofnowwehavediscussedbookmarkingstatefortheappshavingstraightforwardflow.Butifappsdon'thavestraightforwardflows,weneedtotakesomeextrameasurestodealwithsuchsituations.Inasimilarway,ifappshaverandom-numbergenerationandusethattogenerateoutput,thenthesemethodologieswon'twork.

Page 233: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Forsuchapplicationswithcomplexstate,useofcallbackfunctionsisneeded.ShinyhasprovidedonBookmark(),andonRestore()toachievecallbackfunctions.Thesecallbackfunctionstakeoneargument,namedstate.Wecanusestate$valuetosaveandretrievevaluestobebookmarked.

Let'sdevelopanapplicationthatgeneratesarandomnumberandaddsittotheinputtednumber.HereistheUIcodeforgettingtheinputnumberusingtextInput().IthasoneactionButton()fortriggeringtheeventoftheaddition,andbookmarkButton()forbookmarking:

ui<-function(request){

fluidPage(

sidebarPanel(

textInput("txt","Number"),

actionButton("add","Add"),

bookmarkButton()

),

mainPanel(

h4("SumofRandomNumberandInputedNumber:",textOutput("result"))

)

)

}

Intheservercode,wecanseethattheresultvariableisinitiatedtozeroandarandom-numbergenerator,runif(),hasbeenused.onBookmark()isusedtosavetheresultvalueinthestate$valuesobject.AndonRestore()isusingthesamestateobjecttorestorethebookmarkedvalue:

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

vals<-reactiveValues(result=0)

#Savevaluesinstate$valuesforbookmark

onBookmark(function(state){

state$values$currentresult<-vals$result

})

#Readvaluesfromstate$valueswhenwerestore

onRestore(function(state){

vals$result<-state$values$currentresult

})

#Excludetheaddbuttonfrombookmarking

setBookmarkExclude("add")

observeEvent(input$add,{

vals$result<-vals$result+floor(runif(1))+as.numeric(input$txt)

})

output$result<-renderText({

vals$result

})

}

shinyApp(ui,server,enableBookmarking="url")

Page 234: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

So,wehavelearnedhowtobookmarktheShinyappstateinasimple,straightforwardflowaswellasincomplexstates.WealsolearnedinwhichconditionsencodingwithaURListobeusedandwhenasaveontheservercanbeadvantageous.

Page 235: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

InteractiveplotsToexplorecomplexpatternsindata,simplyputtingdataintoastaticgraphisn'tparticularlyuseful.Inthebigdataera,interactiveplotsdemandalotoftime.Rhascomeupwithveryelegantinteractiveoptions:

clickdouble-clickhoverbrushzoomin/outselectionofarea

plotOutput(),likefunction,providesoptionstoenablethesepropertiestomakeplotsmoreinteractive.Let'sexploreplotOutput()anduseitinourapp.HereisthesyntaxforplotOutput():

plotOutput(outputID,width,height,click=NULL,dbclick=NULL,hover=NULL,hoverDelay=NULL,hoverDelayType=NULL,brush=NULL,clickId=NULL,inline=FALSE)

Let'sdevelopanapplicationthatexplorestheirisdatasetandusessomeinteractivefeaturesofplotting:

library(shiny)

shinyApp(

#---------------Uistart--------------------------------

ui=basicPage(fluidRow(

column(width=4,

plotOutput("plot",height=300,

click="plot_click",

hover=hoverOpts(id="plot_hover",delayType="throttle"),

brush=brushOpts(id="plot_brush")

),

h4("Clickedpoints"),

tableOutput("plot_clickedpoints")

),

column(width=4,verbatimTextOutput("plot_hoverinfo")

)

)),

server=function(input,output,session){

output$plot<-renderPlot({

plot(iris$Sepal.Length,iris$Sepal.Width)

})

Page 236: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

output$plot_clickedpoints<-renderTable({

#Forbasegraphics,weneedtospecifycolumns,thoughforggplot2,

#it'susuallynotnecessary.

res<-nearPoints(iris,input$plot_click,"Sepal.Length","Sepal.Width")

if(nrow(res)==0)

return()

res

})

output$plot_hoverinfo<-renderPrint({

cat("Hover(throttled):\n")

str(input$plot_hover)

})

}

)

Inthiscode,wecanseethatplotOutput()hastheclickandhoverproperties.Theclickpropertyspecifiesthatitwilldetectaclickeventontheplot.hoverwilldetectthepointer'sposition.

Inthefollowingoutput,thepositionofpointeriscapturedanddetailsaredisplayedinthehoverwindowanddataforthepointisinthetable:

Page 237: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ggplotandplotly,likeRlibraries,arefullofverygoodinteractiveplottingfunctions.ThesefunctionsuseD3.jstoproduceinteractiveplotsandgraphs.Aswehavealreadydiscussedggplot2,wewillnotelaborateonithere.

plotlyisalsoveryeasytouse.Ifplotlyisnotinstalledonyoursystem,youcaninstallitusinginstall.package("plotly").Let'slookatanexamplewithplotly:

library(plotly)

plot_ly(iris,x=iris$Sepal.Length,y=iris$Sepal.Width,text=paste("iris$Sepal.Width:",iris$Sepal.Width),

mode="markers",color=iris$Sepal.Width,size=iris$Sepal.Width)

Inthefirstlineofcode,theplotlylibraryisinvokedwhichfacilitatestheuseofplot_ly().Inplot_ly(),thefirstargumentisthenameofthedataset,thesecondisthexaxis,andthethirdistheyaxis.Theoutputcanbeseeninthefollowingscreenshot;bydefault,itsupportshoverandclickevents:

Page 238: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

InteractivetablesIntheprecedingexampleapplication,wesawhowtomakeourplotinteractive.Nowit'stimetomaketablesinteractive.Interactiveplotsmeanwecanhavefreedominselectingrows/columns/cellsandshortingcolumns.

DTisapackagewithDTlibrarythathelpsustomaketablesmoreinteractive.Let'sseeasmallclient-sideexampleofDataTableswithShiny:

library(shiny)

library(DT)

shinyApp(

ui=fluidPage(DTOutput('tbl')),

server=function(input,output){

output$tbl=renderDT(

iris,options=list(lengthChange=FALSE)

)

})

Intheprecedingcode,DTOutput()isforoutputtingthetableonUI,andontheserversidewehaveusedrenderDT()tosendthedataintotheUIfromtheirisdataset.Theoutputcanbeseenhere:

Page 239: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Wecanseeintheprecedingscreenshotthatwecanselectrowsusingamousepointer.Inthisway,interactivefunctionalitycanbeaddedtotables.

DTsupportsbothserver-sideandclient-sideprocessing;thedefaultisserver-side,butclient-sidecanbesetbycallingDT::renderDT()withaserver=FALSEargument.Ifthedatasetisrelativelysmall,useserver=FALSE,otherwiseitwillbetooslowtorenderthetableinthewebbrowser,andthetablewillnotbeveryresponsive,foralargedataset.Examplecode:

DT::renderDataTable(iris,server=FALSE)

Formoredetailshttps://rstudio.github.io/DT/linkcanbefollowed.

Page 240: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

RowselectionRowselectionisthedefaultindatatable(...,).Wecantoggletheselectionbyclickingontherow.Itcanalsobedisabledbysettingthedatatable(...,selection='none')property.The'selection'modecanalsobesetto'single'or'multiple'.Bydefault,themultipleselectionmodeisset.

Page 241: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ColumnselectionTochangethedefaultmoderowselectiontocolumn,weneedtosetthetargetascolumnindatatableasdatatable(...,selection=list(target='column')).Toselectrowandcolumnsimultaneously,thetargetcanbesetas"row+column".

Page 242: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

CellSelectionToenablecellselection,thevalueoftargetmustbesettocell.

Page 243: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

LinkinginteractivewidgetsShinyhasanumberofwidgetsthatcanbelinkedinourapplications.Forreferringtothewidgetgallerygotohttps://shiny.rstudio.com/gallery/widget-gallery.html.Here,youcanfindwidgetswithsampleoutputandaseecodebutton.Havealookatasnapshotofthesite:

Forbetterunderstanding,wewillbuildanapplicationwithaShinydashboardandintegratewidgetsintoourapp.Let'sdevelopourappstepbystep:

1. Developabasicdashboard.2. CopythecodeintoanRScriptfile.3. Iftheshinydashboardpackageisnotinstalled,installit.4. Executethecodebyclickingontherunappbutton:

##app.R##

library(shiny)

library(shinydashboard)

ui<-dashboardPage(

dashboardHeader(),

dashboardSidebar(),

dashboardBody()

Page 244: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

)

server<-function(input,output){}

shinyApp(ui,server)

Hereistheoutput:

Now,let'sintegratethewidgetintoourbasicdashboard:

1. Gotohttps://shiny.rstudio.com/gallery/widget-gallery.html.2. Let'sintegratetheFileinputwidgetintoourapp.SoclickonFileinputto

seethecode.3. CopythecodefromtheUIfileandpasteitintothedashboardbody()dashboard

UIfiles:

dashboardBody(

fileInput("file",label=h3("Fileinput")),

hr(),

fluidRow(column(4,

verbatimTextOutput("value")))

)

4. CopythecodefortheserverfileoftheFileinputwidgetandpasteintheservercodeofourdashboard:

server<-function(input,output){

output$value<-renderPrint({

str(input$file)

Page 245: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

})

}

5. Ourfile-uploadmanagerappisready.Thecompletecodecanbeseenhere:

##app.R##

library(shiny)

library(shinydashboard)

ui<-dashboardPage(

dashboardHeader(),

dashboardSidebar(),

dashboardBody(fileInput("file",label=h3("Fileinput")),

hr(),

fluidRow(column(4,verbatimTextOutput("value"))))

)

server<-function(input,output){

output$value<-renderPrint({

str(input$file)

})

}

shinyApp(ui,server)

Hereistheoutput:

Fromtheprecedingscreenshot,wecanseethattheFileinputwidgethasbeenintegratedintoourapplication,andafterclickingontheBrowse...button,anyfilecanbeuploaded.

Page 246: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ShinygadgetsSofar,wehaveseenhowtopresentdatawithShinyappsfortheenduser.Nowit'stimetodevelopgadgetsforRcoders.ThemaindifferencebetweenShinyappsandShinygadgetsisthatappsaredeployedonservers,suchasshinyapps.iooradeployableserver,butgadgetsaretobecalledfromthecodefromRScript.Atthesametime,ShinygadgetscanberegisteredwithRStudioasadd-ins.

Shinygadgetshavebeendevelopedtomakerepeatabletaskseasilydoable,suchasimportingdataintherightformats,cleaningdata,manipulating,orvisualization.Nowlet'sseehowtowriteShinygadgets:

library(shiny)

library(miniUI)

newGadget<-function(inputVal1,inputVal2){

ui<-miniPage(

gadgetTitleBar("NewGadget"),#titleofGadget

miniContentPanel(

#layout,inputs,outputs

)

)

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

#Definereactiveexpressions,outputs,etc.

#WhentheDonebuttonisclicked,returnavalue

observeEvent(input$done,{

returnValue<-...

stopApp(returnValue)

})

}

runGadget(ui,server)

}

Fromthegadgetsskeleton,wecanseethatitissimilartoShinyapps.ThepackagingoftheUIandserverlogicisdonedifferentlyingadgets.Shinyappsaregenerallykeptintheapp'sdirectorywiththeserverandUIfiles,butShinygadgetsaredefinedinsidearegularfunction.

Aswecanseefromtheskeleton,westillhavetheUIandserverconstruct,butthey'reallwrappedinaregularfunction.Andhencethefunction'sinputValue1andinputValue2argumentscanbeaccessedlocally,andreturnvaluesfromtheserver

Page 247: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

constructcanbethereturnvalueofthegadget.

Againinskeleton,UIhasminiPageinsteadoffluidpage,andminiContentPanelinplaceofsidelayout.Thisisbecausethegadget'soutputwillopeninaseparateRStudioViewerpaneinsteadofawebpage.TheMiniUIconstructisusedtomakeoptimaluseofavailablespace.

Let'sdevelopaShinygadgettoplotthedatapassedasanargument,detecttheclickevent,andshowthedata:

library(shiny)

library(miniUI)

library(ggplot2)

click_gadget<-function(data,xvar,yvar){

ui<-miniPage(

gadgetTitleBar("Dragtoselectpoints"),

miniContentPanel(

plotOutput("plot",height="100%",click="plot_click")

)

)

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

#Rendertheplot

output$plot<-renderPlot({

#Plotthedatawithx/yvarsindicatedbythecaller.

ggplot(data,aes_string(xvar,yvar))+geom_point()

})

#HandletheDonebuttonbeingpressed.

observeEvent(input$done,{

#Returnthebrushedpoints.See?shiny::brushedPoints.

stopApp(clickOpts(data,input$plot_click))

})

}

runGadget(ui,server)

}

Toexecutethiscode,firstselectalltheprecedingcodeinRScriptandexecuteit,thenrunclick_gadget(iris,"Sepal.Length","Sepal.Width").Here,theirisdatasethasbeenused,butitcanbechangedtoanydataset:

Page 248: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Atthesametime,iftheplotisclickedandtheDonebuttonispressed,wecanseethedataoftheinputteddataset.

Page 249: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AddingapasswordSofar,wehavelearnedhowtodevelopaShinyapplication.Sincetheapplicationisexposingsomuchdatatotheoutsideworld,itneedstobeprotectedbyunauthorizedmeans.Forthat,wecanprovidepasswordauthentication.Shinyprovidesacontrolforachievingthistask,calledpasswordInput(https://shiny.rstudio.com/reference/shiny/latest/passwordInput.html):

passwordInput(inputId,label,value="",width=NULL,placeholder=NULL)

Let'sseeanexamplewithpasswordInput:

ui<-fluidPage(

passwordInput("password","Password:"),

actionButton("go","Go"),

verbatimTextOutput("value")

)

server<-function(input,output){

output$value<-renderText({

req(input$go)

isolate(input$password)

})

}

Hereistheoutput:

Intheprecedingapplication,theUIsectionhaspasswordInput(),whichconvertstheenteredtextintodotsandtheinputtedvalueisstoredinapasswordvariablethatcanfurtherbeusedinreactiveprocesses.ThecodecanbecopiedandpastedintoRScriptandexecutedasasimpleShinyapplication.

Page 250: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SummaryInthischapter,welearnedaboutRShiny'sadvancedfeatures.Animation,graphics,reportdevelopment,andusingknitrarewonderfulprofessional-levelpresentationfeatures;usingthese,anybodycansharetheirresultsandtellthestoryaboutthedatainhand.WealsodiscussedanddemonstratedthefeatureofbookmarkingtheShinyapp'sstatewithdifferentlevelsofcomplexity.Interactiveplotsandtablesarenewwaystoplaywithdataandfindingnewwaysofdynamicpresentation.Widgetsarelikecookbooksandcanbeusedtospeeduptheapp-developmentprocess.WecannowalsocodeforRusersanddevelopersbydevelopinggadgets.Addingapasswordtoourappcangiveusextracontrolonrestrictingthedataaccessedbyendusers.Inthischapter,westudiedmostofthelatestadvancedfeaturesofpresentation,codesharing,andauthentication.

Page 251: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

CodePatternsinShinyApplicationsAsyourShinyapplicationsbecomelargerandmorecomplex,itisimportanttowriteclear,readable,andmaintainablecode.Insomecases,itisalsonecessarytomodularizeyourcode.ThischaptercoversvariousaspectsofwritinganddebuggingShinyapplications,functions,andmodules.WewillalsolookatfeaturesthatrelatetothecontrolofreactivitywithinyourapplicationandhowtospeedupShinyapplications.

Inthischapter,wewillcoverthefollowingtopics:

ReactivityinRShinyControllingspecificinputwiththeisolate()functionRunningreactivefunctionsovertimeEventhandlingusingobserveEventFunctionsandModulesShinytestDebuggingHandlingerrors(includingvalidate()andreq())ProfilingRcodeDebounceandthrottle

Page 252: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ReactivityinRShinyRShinyusesareactiveprogrammingcodingpattern,whichmakesapplicationsresponsive.Inreactiveprogramming,therearebasicallythreeelements:

ReactiveSourceReactiveEndpointReactiveConductor

ThecombinationoftheseelementsiswhatmakesaShinyappmoreresponsive.Let'shavealookinmoredetailathowtheywork:

ReactiveSource:ThereactivesourceistheinputobjectingtheShinyapp.IttakestheinputfromtheuserandkeepsitintheInputobject.TheInputobjectisassociatedwithanyUIelement,withwhichtheuserinteractsandprovidesinput.Itcanbeaninputbox,anactionbutton,aninteractivetableorplot,oranyotherUIcomponent.Forexample,ifwetakeinputfromatextboxnamedtxtboxintheUIcode,wecansaythatinput$txtboxisthereactivesource.

ReactiveEndpoint:ThereactiveendpointistheoutputobjectinaShinyapp.ItacceptsavalueandputsthatintheoutputcomponentsoftheUI.TheoutputcomponentscanbeanyUIelementthatisusedtodisplaythedatainanyformat.Theoutputobjectisoutput.Forexample,ifwewanttoputthedataintoaplotnamedhist_plotintheUIfile,thenoutput$hist_plotwillbethereactiveendpoint.

Asimpleapplicationcancontainonlythesetwoelements:thesourceandtheendpoint.Let'stakealookatanexampleofanapplicationthatusuallyappearswheneverwestartanewShinyapplication:

library(shiny)

#DefineUIforapplicationthatdrawsahistogram

ui<-fluidPage(

#Applicationtitle

titlePanel("OldFaithfulGeyserData"),

#Sidebarwithasliderinputfornumberofbins

sidebarLayout(

sidebarPanel(

sliderInput("bins",

"Numberofbins:",

Page 253: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

min=1,

max=50,

value=30)

),

#Showaplotofthegenerateddistribution

mainPanel(

plotOutput("distPlot")

)

)

)

#Defineserverlogicrequiredtodrawahistogram

server<-function(input,output){

output$distPlot<-renderPlot({

#generatebinsbasedoninput$binsfromui.R

x<-faithful[,2]

bins<-seq(min(x),max(x),length.out=input$bins+1)

#drawthehistogramwiththespecifiednumberofbins

hist(x,breaks=bins,col='darkgray',border='white')

})

}

#Runtheapplication

shinyApp(ui=ui,server=server)

Yougetthefollowingoutput:

IntheUIsectionoftheprecedingcode,sliderInputistheinputcomponentnamedbins.Intheservercodesection,input$binsisthereactivesource.Similarly,plotOutput("distPlot")istheoutputcomponentontheUI.Asthevalueofinput$binschanges,thisplotalsochanges.Thisishowreactivityworks.Intheserver

Page 254: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

section,output$distPlotisthereactiveendpoint.Thisisrepresentedhere:

However,withmorecomplexapps,thereactivesourceandendpointscanformdifferentcombinations.Imaginethatagraphistobebuiltusingtwoinputvalues.Inthiscase,theflowdiagramwouldbeasfollows:

ReactiveConductor:Sofar,wehaveseenthatthesourceisdirectlyconnectedtotheendpoint.Theremaybesituationswherethereisamiddleelementbetweenthesetwo.Thismiddleelementiscalledareactiveconductor.

Reactiveconductorsareusuallyusedtoencapsulateslowoperationsorcatchdata.FromShiny'sofficialwebsite,https://shiny.rstudio.com/articles/reactivity-overview.htmltocalculateanumberandinverseofitintheFibonaccisequenceforthe

Page 255: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

nthelementofasingleapplication,whichcanbeverytime-consuming.Thissituationisshowninthecode:

#CalculatenthnumberinFibonaccisequence

fib<-function(n)ifelse(n<3,1,fib(n-1)+fib(n-2))

server<-function(input,output){

output$nthValue<-renderText({fib(as.numeric(input$n))})

output$nthValueInv<-renderText({1/fib(as.numeric(input$n))})

}

Theflowdiagramwouldbeasfollows:

Insuchsituations,amiddlelayertocatchtheresultscanbeaddedtoreducethetimetakenbythisprocess.Thatiscalledareactiveconductor.Theprecedingcodecanbemodifiedusingareactiveconductor,asfollows:

fib<-function(n)ifelse(n<3,1,fib(n-1)+fib(n-2))

server<-function(input,output){

currentFib<-reactive({fib(as.numeric(input$n))})

output$nthValue<-renderText({currentFib()})

output$nthValueInv<-renderText({1/currentFib()})

}

Nowtheflowdiagramwilllookasfollows:

Page 256: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Upuntilnow,wehavediscussedthreeelements:thereactivesource,thereactiveconductor,andthereactiveendpoints.Thesearethegeneraltermsusedtodescribereactiveprogrammingelements.InRShiny,thereactivesourceisknownasthereactivevalue,thereactiveendpointistheobserver,andthereactiveconductoristhereactiveexpression.Therearetwofundamentaldifferencesbetweentheobserverandreactiveconductor'sfunctionality.Thefirstisthattheobserverrespondstoeventflushingbutreactiveexpressionsdon't.Thesecondisthatreactiveexpressionscanreturnvaluesbuttheobservercan't.

Page 257: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AcloserlookatreactivitySofar,wehavediscussedreactiveprogrammingandhowShinyimplementsitsfeatures.We'llnowtakeacloserlookathowthisworks.RShinyusesapullmechanisminsteadofapushmechanism.Thismeanswhenevertheoutputsensesthatthereisachangeininput,itpullsthenewvaluesfromtheinput.Inpushmechanisms,outputvaluesarepushedforeveryinputchange.Pullmechanismsarealsoknownaslazy-evaluationmechanisms.Thissimplymeansthattheyarenotlikeinputtooutputelectricitytransfers,butmorelikepigeon-carriermethods.

Shinyimplementsreactivitywithtwospecialobjectclasses:

Reactivevalues,which,aswehaveseen,canbeprintedasinput$valueObserver,whichcanbeprintedasoutput$output_val

Wheneveranobserverusesareactivevalue,itcreatesareactivecontextwiththevalue.Thecontextcanbeanyexpressionthatisrunifthereisanychangeinthevalue.Here,theexpressionreferstocallback.Ifmultipleobserversareusingthesamevalue,thatsinglevaluecanholdmultiplecontexts:

Page 258: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Fromtheprecedingdiagram,seehowcontextworksbylookingatthebasiccommunicationbetweenreactivevaluesandobservers.Supposethattheinputvaluechangesto60,sowegetinput$=60.Inthiscase,acontextwithanewvaluewillbecreated.Theobserversensesthatnewvalueandaskstheserverforcallback.Theserverfindsthecontextwiththenewvalueandflushesittotheobserver:

Page 259: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Inagraphicalrepresentation,thereactivesourcecanonlybeaparentandthesourceendcanonlybeachild,whereasaconductorcanbeaparentandachild.

Page 260: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Controllingspecificinputwiththeisolate()functionTheremaybesituationswhentheobserverorconductorwantstoreadthevalueofanexpressionbutavoiddependency.Supposewewanttoimportsomedataorperformsomecalculations,butonlyafterabuttonhasbeenclicked.

Let'stakealookatthisexample:

library(shiny)

#DefineUIforapplicationthatdrawsahistogram

ui<-fluidPage(

#Applicationtitle

titlePanel("OldFaithfulGeyserData"),

#Sidebarwithasliderinputfornumberofbins

sidebarLayout(

sidebarPanel(

sliderInput("bins",

"Numberofbins:",

min=1,

max=50,

value=30)

),

#Showaplotofthegenerateddistribution

mainPanel(

actionButton("goButton","Go!"),

plotOutput("distPlot")

)

)

)

#Defineserverlogicrequiredtodrawahistogram

Intheserverfile,wecanseethatoutput$distPlotisdependentoninput$goButton.Wheneverthebuttonisclicked,theplotgetsexecuted.However,whenwewrapinput$binsinisolate(),thistellsShinythattheobserverorreactiveexpressionshouldnotbedependentonanyreactiveobject:

server<-function(input,output){

output$distPlot<-renderPlot({

#generatebinsbasedoninput$binsfromui.R

x<-faithful[,2]

#bins<-seq(min(x),max(x),length.out=input$bins+1)

#Takeadependencyoninput$goButton

input$goButton

dist<-isolate(bins<-seq(min(x),max(x),length.out=input$bins+1))

hist(dist,breaks=bins,col='darkgray',border='white')

#drawthehistogramwiththespecifiednumberofbins

#hist(x,breaks=bins,col='darkgray',border='white')

Page 261: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

})

}

#Runtheapplication

shinyApp(ui=ui,server=server)

Theflowgraphlooksasfollows:

Inthecode,wecanpreventtheplotbeingshownthefirsttimewithouttheclickbuttonbeingpressedbyapplyingconditionstoit.Inisolate(),notonlyreactivebutalsoreactiveexpressionscanbeincluded.Itisalsopossibletoincludemultiplestatementsinanisolateblock.

Page 262: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Runningreactivefunctionsovertime(executionscheduling)ThecoreoftheShinyapplicationisthereactiveengine,whichtellsShinywhentoexecuteeachcomponent.Wearenowfamiliarwiththereactiveflowofvariouscomponents.Reactiveobservershaveaflagthatindicateswhethertheyhavebeeninvalidated.Wheneverthevaluesoftheinputobjectchange,allofthedescendantsinthatgraphareinvalidated.Suchinvalidatedobserversarealsocalleddirtyorclean.Alongwiththis,thearrowsintheflowdiagramthathavebeenfollowedareremoved.

Let'sdiscussanexampleofasinglereactivesourceandendpoint:

server<-function(input,output){

output$Plot_output<-renderPlot({

hist(rnorm(input$User_input))

})

}

Theflowdiagramisasfollows:

Assoonastheinputvalueschange,allthedescendantsareinvalidatedandaflusheventistriggered:

Page 263: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Thisisrepresentedinthefollowingdiagram,inwhichtheoutputobjectisshownindarkgrey.Whenthishappens,alltheinvalidatedobserversarere-executed.Iftheoutputobjectre-executes,itaccessesthereactivevalue.Thismakestheoutputobjectdependentontheinput:

Fromtheprecedinggraph,wecanseethatoutput$Plot_outisrequestingforinput.Onceitgetsinput,theinvalidatingflagisclearedandtheoutputisplacedontheUI:

Page 264: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present
Page 265: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Event-handlingusingobserveEventandeventReactiveSofar,wehavelookedathowreactivityworksinShinyapplications.Wehavelearnedhowtouseobserve()andisolate().Wewillnowlookinmoredetailatevent-handling.Aneventcanbedefinedasareactivevalueoranexpressionthattriggersothercalculations.Forexample,sometimeswewantsomeactionstohappenonlyaftertheactionbuttonisclicked.

Wehavealreadylearnedtohandleeventsusingobserve()andisolate().Therearetwomoremethods:

observeEvent

eventReactive

Thesetwoprovidestraightforwardwaysofhandlingevents:

observeEvent:Ifwewanttoperformanactioninresponsetoanevent,observeEventisuseful.Thesyntaxisasfollows:

observeEvent(eventExpr,handlerExpr,event.env=parent.frame(),

event.quoted=FALSE,handler.env=parent.frame(),

handler.quoted=FALSE,label=NULL,suspended=FALSE,priority=

0,

domain=getDefaultReactiveDomain(),autoDestroy=TRUE,

ignoreNULL=TRUE,ignoreInit=FALSE,once=FALSE)

Thefirstargumentistheeventtoberespondedtoandthesecondisthefunctiontobecalledwhentheeventoccurs.TherestoftheparametersareoptionalandanexplanationcanbeseeninnextsectionofeventReactive.

eventReactive:eventReactiveisusedtocalculateavaluethatonlygetsupdatedwhenaresponsetoaneventisneeded.Thesyntaxisgivenhere:

eventReactive(eventExpr,valueExpr,event.env=parent.frame(),

event.quoted=FALSE,value.env=parent.frame(),value.quoted=

FALSE,

label=NULL,domain=getDefaultReactiveDomain(),ignoreNULL=

Page 266: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

TRUE,

ignoreInit=FALSE)

Here,thefirstargumentistheeventtobedetectedandthesecondisthevalueexpression.Therestoftheargumentsareexplainedhere:

event.env:Theparentenvironmentfortheeventexpression.Bydefault,theparentenvironmentisthecallingenvironment.event.quoted:AlogicalexpressiontotellwhethereventExpisquoted.handler.envandhandler.quoted:Thesameasevent.envandevent.quoted,withrespecttothehandler.Thelabelisthenamegiventotheobserverorthereactive.Suspended:Alogicalexpressionforidentifyingwhethertheobserverissuspended.Priority:Avaluethatidentifiesthepriorityoftheobserver.autoDestroy:Anotherlogicalexpression.Ifitistrue,theobserverwillbedestroyedafterthedomainhasended.ignoreNULL:Alogicalparameteraswell.Ifitistrue,theactionistobetriggeredforthevalueisNULL.ignoreInit:Falsebydefault.IfitisTRUE,andobserveEventisfirstcreatedorinitialized,handlerExpr(secondargument)isignored.valueExpr:AnexpressionthatreturnsthevalueofeventReactive.value.envis:TheparentenvironmentforvalueExpr.value.quoted:CheckswhethervalueExprisquotedornot.

library(shiny):

shinyApp(

ui=fluidPage(

column(4,

numericInput("x","Value",1),

actionButton("button","Show")

),

column(8,tableOutput("table"))

),

Intheprecedingcode,thereisoneinputboxandanactionbuttonontheUI.Thefollowingisthecodeoftheserversection.Here,wecanseethatobserveEventishandlingtheevent,showingtheinputvalues,andeventReactiveiscalculatingtheheadrowsfromtheirisdatasetswithagivenvalueofx:

server=function(input,output){

observeEvent(input$button,{

cat("Showing",input$x,"rows\n")

})

Page 267: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

df<-eventReactive(input$button,{

head(iris,input$x)

})

output$table<-renderTable({

df()

})

}

)

Youwillgetthefollowingoutput:

Page 268: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

FunctionsandmodulesWehavenowgonethroughagoodnumberofShinyapplicationsthatarefocusedondifferenttopics.Imaginethatwenowhavetodevelopafully-fledgedenterpriseapplicationwithvariousfunctionalitiesasaShinyapplication.Astheapplicationgrows,sowillthenumberoflinesofcodeanditscomplexity.Insituationssuchasthese,applicationscanbecomeunmanageable.Wemayalsoberewritingthesamekindofcoderepeatedly,therebyincreasingthedevelopmenttime.Additionally,variablesneedtobescoped,whichlimitsthereusabilityofnames.Toeliminatetheseobstacles,wecanusemodularization.

Modularizationisnothingbuttheuseofseparatingmodulesaccordingtotheirfunctionality.Modulescanbedefinedasasetofinstructionsthatarewrittentoaccomplishatask.Rprogrammingisdevelopedaroundmodules.Werepeatedlycallfunctionsforalmostanytaskwewanttoperform.Thismeansthatwedon'thavetowritemorecode,asisrequiredinprogramminglanguagessuchasC,C++,orJava.WecanusethisprogrammingparadigmwithShinyaswell.

Sofar,wehavecodedUIandserverfunctionsintheShinyapplication,withanumberofcomponentsandinputandoutputelements.Wewillnowtrytomodifytheseinasimplercodingpatternwithmodules.

Wecanorganizethecodeintotwosections,basedontwofunctions:

ForcreatingUIelementsForloadingserverlogic

Wealsohavetosticktosomenamingconventionssothatthecodecanbeidentifiedeasily.TheUImodulescanbesuffixedwithInput,Output,orUI.Beforegoingintotoomuchdetail,let'sstartbyobservingthesimpleapplicationcodethatisavailablewheneverwestarttheShinyapplication,RStudio.Thisisgivenhere:

#

#ThisisaShinywebapplication.Youcanruntheapplicationbyclicking

#the'RunApp'buttonabove.

#

#FindoutmoreaboutbuildingapplicationswithShinyhere:

Page 269: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

#

#http://shiny.rstudio.com/

#

library(shiny)

#DefineUIforapplicationthatdrawsahistogram

ui<-fluidPage(

#Applicationtitle

titlePanel("OldFaithfulGeyserData"),

#Sidebarwithasliderinputfornumberofbins

sidebarLayout(

sidebarPanel(

sliderInput("bins",

"Numberofbins:",

min=1,

max=50,

value=30)

),

#Showaplotofthegenerateddistribution

mainPanel(

plotOutput("distPlot")

)

)

)

#Defineserverlogicrequiredtodrawahistogram

server<-function(input,output){

output$distPlot<-renderPlot({

#generatebinsbasedoninput$binsfromui.R

x<-faithful[,2]

bins<-seq(min(x),max(x),length.out=input$bins+1)

#drawthehistogramwiththespecifiednumberofbins

hist(x,breaks=bins,col='darkgray',border='white')

})

}

#Runtheapplication

shinyApp(ui=ui,server=server)

WecanseethatthiscodefromRStudioissimplywrittenwithoutmodularization.Let'sdiscussindetailhowwecanmodularizetheUIandServercodeofthisapplication:

UICodemodularization:Intheprecedingcode,oneoftheelementsoftheUIsectionissliderInput.Atthemoment,thereisonlyonesliderInputbox,buttheremightbemore,meaningwewouldhavetowritethesamecodeagainandagainifwedidn'tusemodularization.Let'sdevelopamoduleforthis.FortheUImodule,weneedtogiveanametothefunction,suchasSliderbarInput.WealsoneedtogiveanIDtoeachinputelementthatweareusing.Inthefunctionargument,therefore,wewilladdoneIDparameter,whichwillbeusedtocreateanamespaceusingNS().Rightnow,

Page 270: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

weonlyhaveoneinputelement,butinthefuturewemaywanttoaddmultipleelements.WewillusetagList().TheUImodulewillnowlookasfollows:

SliderbarInput<-function(id){

ns<-NS(id)

tagList(

sliderInput(ns("bins"),

"Numberofbins:",

min=1,

max=50,

value=30)

)

}

WehavenowseparatedtheinputcodefromtheUIcode.WehavetocallthiscodefrominsidetheUIwheneverwewanttoputinasliderbar.Inthefollowingcode,wecanseethatSliderbarInput("Simplesliderbar")hasbeencalled.Thiswillcalltotheprecedingcode."Simplesliderbar"istheIDgiventosliderInput:

ui<-fluidPage(

#Applicationtitle

titlePanel("OldFaithfulGeyserData"),

#Sidebarwithasliderinputfornumberofbins

sidebarLayout(

sidebarPanel(

SliderbarInput("Simplesliderbar")#calltofunction

),

#Showaplotofthegenerateddistribution

mainPanel(

plotOutput("distPlot")

)

)

)

ServerCodemodularization:Intheserversectionoftheoriginalcode,wearedevelopingacalculationtorenderaplot.Wewilldevelopamoduletoperformthistask.Ourfirsttaskistogiveanametothefunction,suchasSliderbar.Intheservermodule,thefunctionhastohavethreearguments:Input,Output,andSession.Therestcanbetheinputparameterstheuserwantstoadd.Afterthat,wewillwriteallthecalculationcodeinthisfunction.Ournewmodulewilllookasfollows:

Page 271: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

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

#generatebinsbasedoninput$binsfromui.R

x<-faithful[,2]

bins<-seq(min(x),max(x),length.out=input$bins+1)

#drawthehistogramwiththespecifiednumberofbins

hist(x,breaks=bins,col='darkgray',border='white')

}

WenowhavetocalltheprecedingcodefromtheusingcallModule()servercode.Here,wewillpassthefunctiontobecalledandthelabelorIDoftheinputelement.Theservercodewilllookasfollows:

server<-function(input,output){

output$distPlot<-renderPlot({

callModule(Sliderbar,"Simplesliderbar")

#SimplesliderbariscomingfromUI

})

}

Bydoingthis,wehaverecreatedtheapplication.However,wehavetodecidewherewecandefineourmodules.Oneoptionistokeepourmodulesinthepreambleofasinglefileapplicationorinafilethatissourcedinthepreambleofasinglefile.Anotheroptionistoputthemodulesinaglobal.rfile,orafilethatissourcedintheglobalfile.Alternatively,wecanwrapamoduleinapackagethatisloadedbytheapplication.

Theadvantageofusingmodularizationisthatitmakesthecodereusable.

Page 272: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ShinytestLet'ssaythattheShinyapplicationwehavedevelopedrunswellonourmachineforsomeinput,butforothersitdoesnotgivethedesiredoutputoritgetsstucksomewhereandthrowserrors.Inthesoftwaredevelopmentprocess,testingisoneofthemostimportanttasks.AShinyapplicationmightstopworkingduetoanyofthefollowingreasons:

TheversionofShinyandtheversionofthepackagesmaydifferAmodificationintheapplicationcodeleadstothewronginputforanyotherreactivecodeThedataformatmayhavechanged

Theremaybecountlessreasonsthatcauseustocomeacrosserrorsandcausetheapplicationtostopworking.Doingtestingmanuallycanbetime-consumingandinefficientbecauseyouhavetoconsiderawiderangeofusecases.Forthisreason,Shinyhastheshinytestpackageforautomatictesting.Itcanbeinstalledasfollows(https://www.rdocumentation.org/packages/devtools/versions/1.13.6/topics/install_github):

library(devtools)

install_github("rstudio/shinytest")

Tocarryoutatest,followthesesteps:

1. RunrecordTest()tolaunchtheappinatestrecorder(https://rstudio.github.io/shinytest/reference/recordTest.html):

library(shinytest)

#Launchthetargetapp(replacewiththecorrectpath)

recordTest("path/to/app")

Inthetestrecorder,wecanfindalistofrecordedevents.Theseeventsareinteractionsmadebytheuser.Wecanalsotakesnapshotsofthestateoftheappbyclickingontakesnapontheright-handsidewindowoftherecorder.

2. Quitthetestrecorderandfindthetestscriptinthe.Rfileinthetest/

Page 273: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

subdirectory.Thisholdscodelikethefollowing:

app<-ShinyDriver$new("..")

app$snapshotInit("mytest")

app$snapshot()

app$setInputs(checkGroup=c("1","2"))

app$setInputs(checkGroup=c("1","2","3"))

app$setInputs(action="click")

app$snapshot()

Here,wetrythepossibleusecaseinputandfiguringerrors.Foramorein-depthunderstandingoftheworkingsoftheshinytestpackage,refertohttps://rstudio.github.io/shinytest/articles/shinytest.html.

Page 274: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DebuggingDebuggingaShinyappisnotthesameasdebuggingcodeinotherprogramminglanguages,suchasC,C++,orJava,wherethecontrolflowlookslinear.BecauseRShinyisreactive,itrunsonawebserveraswellasaShinyframework.Thatmakesithardertodebug.

Ifwegetanerrororanundesirableoutput,wecanapplybreakpointsatthesuspectedlineofcode.Thiscanbedonebyclickingontheleftsideofthecodewherethelinenumberisgiven,whichmakesareddotappear:

Afterrunningthecode,Shinywillstopexecutionatthebreakpointandwecanstepintothecodeandtakealookatthecurrentvariablevalues.SettingabreakpointispossiblewithRStudio.

Sometimes,applyingabreakpointdoesn'twork,sowehavetochangetheinputandobservetheoutput.Wecanthenapplyabreakpointagaintotrytodiagnosetheproblem.Wecanenabletheshowcasemodeandseewhichpartofthecodeisexecuting:

shiny::runApp(display.mode="showcase")

Toexaminethereactive,wecanenableshiny.reclogandobservethereactivelogs:

options(shiny.reactlog=TRUE)

Page 275: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Thiswillgiveusanideaabouthowthereactivesareworking.Formoredetaileddebugging,wecanapplyaprintstatementinsuspectedplacestounderstandtheflowoftheapplicationandthebehaviorofthecode.Inordertotracetheleveloftheclientorserverarchitecture,weneedtosettheshiny.tracemodetoon.ThiswillprovideatraceoftheappintheJSONfile.

Thebrowser()statementcanalsobeusedfordebugging.Itactsasbreakpointandcanbeaddedanywhereinthecode.

Debuggingwiththeprecedingmethodologiesissufficienttorunanapplication,buttherearemanyothermethods,whichareoutsidethescopeofthisbook.Afterdebugging,thenextstepistohandletheerrorsthataredetected.

Page 276: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Handlingerrors(includingvalidate()andreq())Areyougettinganerrormessageinredonyourscreen?Areyouoryouruserabletounderstandthatmessage?Theanswerstosuchquestionscanbevalidationerrorsusingvalidate()andreq().

Page 277: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ValidateThisisdesignedtoleadtheuserthroughtheUIoftheShinyapp.Imaginethatwehaveasituationwhereweneedtoplotagraphbasedonsomevaluesofalistboxanditthrowsuparedmessage.Thislooksstressfultotheuser.Weneedtoprovideaprecautionarymessagetomakesurethereaderentersavalidinput.validateisawayofcheckingtheinputandprovidingamessage,usingneed.Inthefollowingcode,wecanseethatvalidateischeckingforaphonenumber.Iftheinputisanemptystring,itwillgiveamessage:

server<-function(input,output){

Phon_Number<-reactive({

validate(

need(input$PN!="","ProvidePhonenumber")

)

get(input$data,'package:datasets')

})

Page 278: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Handlingmissinginputwithreq()Sometimes,wemightseeanerrorwhenourgraphneedstobeupdateddynamicallybecausethedataisunavailablewhiletheapplicationisloading.Itisalsopossiblethatthedataisnotavailableforacertaininputandtheelementtriestorendertheoutput.Inthissituation,wewouldseeanerrormessage.

Tohandlethis,wecanusereq().req()istheshortformofrequire.Thisisusefulforcheckingpreconditions.Wheneverweneedtowriteareactiveelement,wecanencloseitinreq().Thiswillmakesurethattheoutputishalteduntilthevaluesareavailable.

Page 279: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ProfilingRcodeInthebigdataera,wherewemighthavepetabytesofdata,maintainingtheperformanceofapplicationsiscrucial.Theapplicationperformancemightgodownbecauseofdata-loadingoperationsorcalculations.Todetectsuchoperations,wehaveapackagecalledprofvis.Thistellsushowmuchtimealineofcodetakestoexecute.Installthepackageasfollows:

install.packages("profvis")

RStudiohasprovidedsupportfortheprofvispackage.Let'stakealookathowtouseit:

library(profvis)

profvis({

plot(iris$Sepal.Length,iris$Sepal.Width)

plot(cars$speed,cars$dist)

})

profvisenclosesthecodetobeanalyzed.Inthefollowingscreenshot,wecanseetheoutput.Foreachlineofcode,wecanseethememoryusagewiththetimetaken:

Page 280: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present
Page 281: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DebounceandthrottleDebounceandthrottleareusedtoslowdownareactiveexpression.Forexample,supposeweareusingtheinvalidationcheckforareactiveexpressionanderrorindicationsarepromptedunnecessarily.Wecanusedebounceandthrottletomakeexpressionssuchastheseslowdownandwaitforintermediateexpressionstocompletetheircalculations.Thesyntaxesofbothoftheseareasfollows:

debounce(r,millis,priority=100,domain=getDefaultReactiveDomain())

throttle(r,millis,priority=100,domain=getDefaultReactiveDomain())

Here,risthereactiveexpressionthatinvalidatestoooften.millisisthetimewindowusedbydebounce/throttle,andprioritysetstheobserver'spriority.Forexample,ifwewanttoadddebouncetoanexpression,wecandoitasfollows:

plot_iris<-plot(iris$Sepal.Length,iris$Sepal.Width))%>%debounce(1000)

Formoredetailvisitehttps://shiny.rstudio.com/reference/shiny/1.0.0/debounce.html.Letshaveanexample

##OnlyrunexamplesininteractiveRsessions

if(interactive()){

options(device.ask.default=FALSE)

library(shiny)

library(magrittr)

ui<-fluidPage(

plotOutput("plot",click=clickOpts("hover")),

helpText("Quicklyclickontheplotabove,whilewatchingtheresulttablebelow:"),

tableOutput("result")

)

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

hover<-reactive({

if(is.null(input$hover))

list(x=NA,y=NA)

else

input$hover

})

hover_d<-hover%>%debounce(1000)

hover_t<-hover%>%throttle(1000)

output$plot<-renderPlot({

plot(iris)

})

output$result<-renderTable({

data.frame(

mode=c("raw","throttle","debounce"),

x=c(hover()$x,hover_t()$x,hover_d()$x),

Page 282: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

y=c(hover()$y,hover_t()$y,hover_d()$y)

)

})

}

shinyApp(ui,server)

}

Youwillgetthefollowingoutput:

Resulttable

Page 283: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SummaryInthischapter,welearnedaboutthereactivityofRShiny.Welearnedindetailhowreactivesource,endpoint,andconductorwork,andhowtocontrolspecificinputwithisolate().Wehavealsoscheduledthereactiveoffunctions.Afterthat,weusedobserveEventandeventReactiveforevent-handling,andlearnedhowtomakeourcodemoremodular.Afterdevelopingourapplication,wecarriedouttestingusingShinytest,debugging,anderror-handling.Ontopofallthis,wediscussedhowtoimprovetheperformanceofourShinycodeusingprofiling.

Page 284: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

PersistentStorageandSharingShinyApplicationsHavingmadeallofthosewonderfullyintuitiveandpowerfulapplications,youarequitenaturallygoingtowanttoshowthemoff.YoumaywishtosharethemwithcolleaguesormembersoftheworldwideRcommunity.Youmaywishtosharethemwithindividualsinyourdepartmentorfieldwho,whilenotRusers,canhandlealittlebitofefforttogetanapplicationworking.Oryoumaywishtosharethemtransparentlyandfreelywiththewholeworldbyhostingthemonaserver.Shinyoffersquitealotofapproachestosharingapplications,andyou'llbegladtohearthateventhemostcomplexshouldnotbetootaxing,withtherighthardwareandOSonyourserver.

Inthischapter,wewilltakealookatthefollowing:

SharingoverGitHubAnintroductiontoGitusingGitandGitHubwithinRStudioSharingapplicationsusingGitSharingusing.zipand.tarShinyapps.io

ShinyServerRunningShinyinAWSandGoogleCloudScoping,loading,andreusingdatainShinyapplicationsTemporarydatainput/outputPermanentdatafunctionsDatabasesSQLinjectionDatabaseswiththepoolpackage

ThereareafewwaysofsharingwithRusersrunningtheShinypackagewithinRsummarizedinthefollowingsections.

Page 285: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SharingoverGitHubByfar,theeasiestwaytoshareyourcreationswithfellowRusersisoverGitHub(github.com).Ofcourse,otherRuserscanalsousealltheothermethodsinthischapter,butthisisprobablythemostfrictionlessmethod(shortofhostingtheapplication)forbothyouandtheenduser.

Page 286: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

AnintroductiontoGitYouwillnodoubthaveheardofGit(git-scm.com—theversion-controlsystemthathascollaborativesharingfeaturesatGitHub),evenifyouhaveneverusedit.Gitisaversion-controlsystemthatcanbeusedlocallyonyourcomputer,orinordertogetthebestoutofit,theversion-controlrepositoryonyourcomputercanbesyncedonlineatGitHub.HostingofopensourcecodeatGitHubisfree,andtherearepaidoptionsforclosedsourcecode.Ifyouhaven'talreadyusedaversioncontrol,thisisanexcellentreasontostart.Itisalittleintimidatingfornewcomers,butovertime,theresourcesandtutorialsonthesitehaveimprovedandperhapsonedayofhead-scratchingawaitsyou.TrustmethatonedayIwillbepaidbackhundredfold.TheProGitbookcanbedownloadedforfreefromtheGitsiteatgit-scm.com/book/en/v2.Thereisalsoawonderfulinteractivetutorial(try.github.io)ontheGitsite.Asadie-hardLinuxenthusiast,itpainsmetoadmitit,butIactuallyfoundlearningonWindowseasierbecausetheyprovideawonderfulGUItogetyoustarted(alsoonOSX).ThisdoesnotmeanthatyouneedtouseWindowsorshouldsticktoWindows;IhappilydroppedtheGUIandwenttotheterminalinLinuxonceI'dfoundmyfeetabit.

It'salsoworthnotingthattherearesomegreatGUIsforLinuxaswell,soyoucancheckyourpackage-managementsystem.Ididn'tfindanythatsupportedbeginnerssowellastheofficialWindowsorOSXversions,though.GithasalistofGUIsatgit-scm.com/downloads/guis.NotethatsomeofthesesupportGitHubandotherssupportGititself.ThelistincludestheWindows,OSX,andLinuxGUIs.

Finally,RStudioitselfactuallysupportsGitandGitHub,andonceyou'veinstalledGitandsetupyouraccount,youcanprettymuchrunthewholeshowfromwithinRStudioitself.

Page 287: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

UsingGitandGitHubwithinRstudioToinstallGit,simplygototheURLmentionedearlieranddownloadthe.exefileforWindows,oronUbuntu,runthefollowingcommand:

sudoapt-getinstallgit

ForotherflavorsofLinux,checkthepackage-managementsystem.HavinginstalledGit,younowneedtosetupanewprojectwithinRStudio.Aversion-controlwithGit(orSVN,adifferentversion-controlsystem,whichwewillnotconsiderhere)isonlypossiblewhenweuseaprojectwithinRStudio.

Page 288: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ProjectsinRStudio(h3)UsingprojectsinRStudioisagoodwaytoorganizeyourwork.EachprojecthasitsownworkingdirectorywithaseparateRsession,workspace,consoleinputhistory,andopeneditortabs(amongotherthings).Eachtimeaprojectisopened,eachofthesewillbesettothevaluecurrentlyassociatedwiththeproject,ineffectlaunchinganewRsession,loadingthedataandconsolehistorysincethelasttimetheprojectwasused(iftheyareselectedasthedefaultbehaviororindividuallyforthisproject),settingtheworkingdirectorytotheoneassociatedwiththeproject,andsoon.Thisallowsyoutoswitchinandoutofdifferentprojectseitherasyouworkorwhenyoupickupworkthenextday.Tosetupanewproject,gotoFile|NewProjectinRStudio.SelecteitherNewDirectoryifthisisacompletelynewsetofcodeandfilesthatyouwanttocreateanewfolderfor,orExistingDirectoryifyouhavealreadystartedandjustwanttopointtheprojecttoadirectorythatyouhavealreadycreated.Onceyouhaveaprojectsetup,gotoTools|Versioncontrol|ProjectSetup....Thefollowingmenuwillappear:

Page 289: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

MakesurethattheGit/SVNtabontheleft-handsideofthepageisselectedandusetheversion-controlsystemcontrolontheright-handsideofthepagetoselectGit/SVN,ifyouprefer,butthiswillonlyappearifyouhaveinstalledit,andthiswillnotbecoveredinthischapter.YoumayneedtoreopentheprojectatthispointbygoingtoFile|Recentprojects.Youwillneedtoconfiguretheremoteconnectionbetweenyourlocal.gitrepositoryandtheGitHubaccountyourself.GotoyourGitHubaccount,andgotoRepositories|New.Giveitanameanddescription,andselectCreaterepository.Havingdonethis,someinstructionswillappearonthescreenthatwillhelpyoutosetupaconnectionbetweenthisremoterepositoryandthelocalversiononyourmachine.Atthetimeofwriting,thesimplestwayofdoingthisisthethirdboxdown.Keeptheseinstructionsasyouwillneedthemlater,butfornow,weneedtoconfigureRStudioalittlefurther.GototheTools|Globaloptions,andselecttheGit/SVNtab.Thefollowingmenuwillappear:

Page 290: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

CheckwhethertheGitexecutableissetupcorrectlyinthefirstline.IfyoualreadyhaveanSSHRSAkey,itshouldbedisplayedinthebottomline.Ifnot,clickonCreateRSAKey,andyouwillbeguidedtocreateone.IfyouhavenotpreviouslypairedyourRSAkeywithyourGitHubaccount(whichyouwouldnothavedoneifthisisyourfirstexperiencewithGitHub),clickonViewpublickeyabovethethirdline,andthencopytheresultingtextintoyourGitHubaccountbygoingtoyouraccountsettings.Thiscanbeachievedbyclickingon

Page 291: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

youruserportraitatthetop-rightcorneroftheGitHubwebpage.Next,clickonSettings,andthenclickontheleft-handsideofthescreenandselectSSHkeys,andfinally,clickonAddSSHkey,pasteyourkey,andclickonAddkey.Havingdonethis,youwillneedtocommityourcodetoGit,thatis,tothelocalcopyonyourmachine.ThisisveryeasyinRStudio.SelecttheGittabintheEnvironmentpaneinRStudio(bydefault,it'sthetop-righttabonthescreen),asshowninthefollowingscreenshot:

Selecttheelementsthatyouwanttocommitbyclickingontheboxestothefarleftofthescreenshot.ThiswillbeanythingthatyouwanttocommittoGitforyourfirstsubmissionandanythingthathaschangedforsubsequentsubmissions.ClickonCommitinthemenubar,whichisvisibleinthescreenshot.Youwillbepromptedtoreviewthechangesinanewwindowaswellasinstructedtowriteacommitmessageinthetop-rightcornerofthiswindow.Youcannotcommitwithoutamessage.Foryourfirstcommit,youmightliketowriteFirstcommitofbetaversion,andthenforsubsequentcommits,youmightmakecommentssuchasFixedjQuerybugandAddeddashboardelements,dependingonthechangesyouhavemade.Finally,topushtoGitHubforthefirsttime,selectMore|ShellintheGittab.Thiswillopenaterminalwindow.RemembertheterminalcommandsthattheGitHubwebpagegaveuswhenwesetupthenewrepositoryandthetwo-linerItoldyoutokeeptrackof?Thisiswhereweneedthem.Linebyline,copy

Page 292: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

thetwo-linerfromthewebpage.ThiswillsetuptheconnectionbetweenRStudioandGitHub.Fromnowon,youcanpushyourcode(thatis,uploadittoGitHub)bycommittingandclickingonthePushbuttonintheGittabmenubar.ThisisaverybriefintroductiontoGit,GitHub,andRStudio,andisdesignedtogetyoustarted.Thereismuchmoretolearnabouthowtousethesetoolsefficiently,andyouareadvisedtotakealookattheonlinedocumentationforallthreeinordertolearnhowtomakethisprocessevensimplerandmorepowerful.

Page 293: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SharingapplicationsusingGitWeneedtoconsultthewebsitesmentionedearlierformoredetailsofeachofthesesteps.Onceyou'vesetyourGitversioncontrolandpairedwithanonlinerepositoryatGitHub,youcanveryeasilyshareyourcreationswithanyonerunningtheRandShinypackageusingtherunGitHub()command,whichtakesthenameoftherepositoryandtheusernameasmandatoryarguments:

runGitHub("GoogleAnalytics2ndEdition","ChrisBeeley")

Codeanddataarebothautomaticallydownloadedandrun.IfyouareusingRStudioandwanttolaunchyourownexternalbrowser,asopposedtousingtheonethatisbuilt-in,youneedtoaddlaunch.browser=TRUE.Ifyoudon'twantorneedversioncontrol,anddon'tneeddatatobeincludedinthedownload,asimpleroptionistouseGist,whichisalsohostedatGitHubatgist.github.com.UsingGistissimplyamatterofvisitingtheURL,settingupanaccount,pastingyourcodeintoit,andgivingtheserver.Randui.Rfilesthecorrectfilenames.YouwillthenhaveaURL,usingwhichyoucanshowyourcodetoothers.RunningthiscodefromtheShinypackageisjustamatterofusingrunGist()withtheURLorevenusingtheuniquenumericidentifierfromtheURL.

library(shiny):

runGist("https://gist.github.com/ChrisBeeley/a2f1d88dfedcd2e1cb59")

runGist("a2f1d88dfedcd2e1cb59")

Page 294: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Sharingusing.zipand.tarProbablythenextmostfrictionlessmethodofdistributingaShinyapplicationtoRusersisbyhostingeithera.zipor.tarfileofyourapplication,eitherovertheweborFTP.Youwillneedsomewheretohostthefile,andthenuserscanruntheapplicationusingrunUrl(),asfollows:

runUrl("http://www.myserver/shinyapps/myshinyapp.zip")

NotethatthisURLisnotreal.Youneedtoreplaceitwiththeaddressofyourownfile.

Ofcourse,youcandistributea.zipfileanywayyoulike—yourusersneedtoonlyunzipandthenuserunApp()fromwithinthedirectory,justasyoudowhentestingtheapplication.YoucanemailthefileanddistributeitonaUSBdriveforanymethodthatyouchoose.Thedisadvantagesofthismethodarethatyourusershavetounzipthefilethemselves(althoughthisisunlikelytoconfusemanyRusers),andanychangesmadetotheapplicationwillalsoneedtobedistributedmanually.

Page 295: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SharingwiththeworldInmostcases,anyseriousworkthatyoudowithShinywillatsomepointneedtobesharedwithanonR-user,whetherit'sanontechnicalcolleagueinyourdepartmentorthewholeoftheinternet.Inthiscase,abitmoreofthelegworkfallstoyou,butyoushouldstillbepleasantlysurprisedabouthowsimpletheprocessis.Therearetwooptionshere:setupyourownserverorgetapaidaccountwithRStudiotodoitforyou.

Page 296: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Shinyapps.ioShinyapps.ioisRStudio'spaidhostingforShinyapplications.Atthetimeofwriting,thereisatieredpricingstructure,dependingonthenumberofapplicationsyouwishtodeploy,whetheryouneedtheauthenticationofusers,thenumberofhoursyourapplicationswillrunpermonth,andsoon.Youcansetupafreeaccountthat,atthetimeofwriting,allowsfiveapplicationsand25hoursofapplicationruntimeamonth.Thisiswelcome;however,itisonlysuitableforverysmall-scaleuse;asingletweetofyourapplicationonthe#rstatshashtagislikelytobringenoughtraffictoyoursitetouseallofthe25hoursinaveryshorttime.Indeed,Ihavebeenlinkedtomanyshinyapps.ioapplications,whichindicatethattheaccounthasexceededtheallocatedhoursthismonthand,therefore,doesnotwork.

Bewarned:ifyouwanttheworldtoseeyourapplication,youeitherneedtogetapaidaccountorrunyourownserver(whichisexplainedlater).Usingthisservicedoes,ofcourse,entailcopyingyourcodeand/ordatatoathirdparty,soifthisisaproblemforyou,youwillneedtotakealookathostingyourselfonaserver.

IfyouareusingRStudio,itisveryeasytogetanapplicationonshinyapps.WheneveryouhaveaShinyapplication(thatis,aserver.Rorui.Rfile)open,youwillfindalittlePublishiconintheupper-rightcorneroftheeditor,asshowninthefollowingscreenshot:

Page 297: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Youwillbepromptedtoinstallvariousthings,dependingonyourOSandtheconfigurationofyourRinstallation.OnLinux,youwillprobablysaveyourselfabitofconfigurationifyouinstallthedevelopmentversionofR(r-base-devonUbuntu,availablethroughtheRmetapackageonFedora;forotherdistributionsoroperatingsystems,refertotherelevantdocumentation).

Foralloperatingsystems,youwillbepromptedtoinstallvariousRpackages.UsersofLinuxmayhaveproblemsconfiguringsomeofthesepackages;youmayneedtoinstalllibcurl-devandopenssl-dev(ortheirequivalentforyourdistro).InWindows,inmyexperience,thewholeoperation,rightfromthevanillainstallationofR,iscompletelyseamlessandeverythingwillbeinstalledandconfiguredcorrectly.

Then,youwillbepromptedtogotoyourshinyapps.ioaccountandlogin,whereyoucanauthenticateRStudio.YoucannowpublishitstraightfromRStudio:

1. Pressthebuttonhighlightedintheprecedingscreenshot,selectthefilestobeuploaded(forexample,thecodeanddatafiles),andclickonPublish

Page 298: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

2. Itwilllaunchabrowserforyou,soyoucanseetheapplicationforyourselfandcopythelinkthatneedstobeshared

3. Ifyouforgetthelink,justlogintoshinyapps.io—thelinkisavailablefromyourlistofapplicationsinthemenu

Page 299: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Shinyapps.iowithoutRStudioIt'snotnecessarytouseRStudiotouseshinyapps.io,it'sjustabiteasier.Youneedtofollowthesesteps:

1. Ifyou'rehappierinanotherIDE,youjustneedtoensurethatyouhavethelatestversionofdevtoolsinstalled:

install.packages('devtools')

2. Installshinyapps:

install_github('rstudio/shinyapps')

3. Loadshinyapps:

library(shinyapps)

4. Logintoyourshinyapps.ioaccount,copytheauthorizetokencommandfromthetokensmenu(tokenmarkedwithXshere),andrunitinyourRsession(notethatthisonlyhastobedoneonceoneachcomputer):

shinyapps::setAccountInfo(name='chrisbeeley',

token='XXXXXXXXXXXXXXXXXXXXXXXX',

secret='XXXXXXXXXXXXXXXXXXXX')

5. Setyourworkingdirectorytothefolderthatholdsyourapplication:

setwd("~/myShinyApp")

6. Deploy:

deployApp()

MoredetailsareavailableonRStudio'spagesatshiny.rstudio.com/articles/shinyapps.html.

Page 300: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

ShinyserverIfyouwanttohosttheapplicationsyourself,ShinyServerisavailableforLinux.Again,therearepaidandfreeoptions.ShinyServeristotallyfreeandopensource,whichisagreatcredittoRstudio.Thepaidversionhasanumberofbenefits.Themainonesaretheprovisionofsupportandextrafeatures,particularlyauthentication(LDAP/PAM/GoogleaccountsandrunningoverSSLtoencryptdatatoandfromtheserver).ItalsoallowsyoutousemultipleRprocessestoserveoneapplication,supportsmultipleversionsofRonthesameserver,andprovidesanadmindashboardthathelpsserveradministratorstomonitorserverload,concurrentconnections,andsoon.

BinariesareavailableforUbuntu,RedHat,CentOS,andSUSEEnterprise;forotherdistributions,itispossibletobuildfromthesource.Thefreeversionis,inmyexperience,stableandwell-featured.Installationdetailscanbefoundatrstudio.com/products/shiny/download-server/.

Followtheinstructionsmentionedpreviouslytoinstall,andusingthedefaultconfiguration,youshouldbeabletonavigatetoatestShinyapplicationbygoingtochrisbeeley.net:3838/shiny/01_hello/inawebbrowser(replacethedomainwithyourownURL).InorderforShinyServertowork,youneedtoopentherelevantport(inthiscase,thedefaultconfiguration,3838)onyourfirewall.Bydefault,applicationsarerunfromfileslocatedwithin/srv/shiny-server.Youcanincludedirectorieswithinthisfoldertoorganizeyourapplications.Theadministrator'sguide,whichislinkedtoandfromthedownloadpage,includesdetailsofhowtoconfigureShinyServer.

YoumaywishtochangetheportthroughwhichShinyservercommunicates(again,openingthisportonyourfirewall),changethelocationofapplicationfiles,oraddseverallocationstoapplicationfiles,orsomethingelseentirely.Thecompletedetailsareavailableinthedocumentation.InstallationonUbuntuisembarrassinglyeasy;evenwithmylimitedknowledgeofrunningLinuxservers,Ihaditupandrunningonmypersonalserverinlessthananhour.It'srunquitehappilyeversince.Mileagewithotherdistributionswillvary,althoughjudgingfromforumandblogposts,peoplehavesuccessfullyrunitonavarietyofdistributions.Dependingonwhatyouaredoingwithyourapplication,onething

Page 301: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

tobecarefulofisdirectoryownershipandpermissions.

Forexample,oneofmyapplicationsproducesPDFfilesfordownload.ThisrequiresmakingShinytheownerofthedirectorywithintheapplicationfolder,whichhousesthetemporaryfilesthatareproducedfordownloadandmakingthedirectorywritable.Inacorporateenvironment,youmayalsofindthattheportShinyusesisblockedbythefirewall—changingtoadifferentportissimplyamatterofeditingtheconfigurationfileasdetailedontheShinyserverwebpagegivenpreviously.IfyouareinacorporateenvironmentrunningWindows,it'sworthnotingthattheopenversionrunsfineonanUbuntuservervirtualizedonWindows,inmyexperience.Icouldn'tspeakforthepaidversion,andI'msureRStudiowouldbehappytoadviseyouifyouwerethinkingaboutpayingforalicense.

Page 302: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

RunningShinyapponAmazonAWSWehavethoroughlydiscussedhowtodevelopShinyapps.Nowit'stimetodiscussdeployingtheShinyapponAmazonAWS.Thedeploymentoftheapplicationisnecessarytomakeitavailableforusers.TodeployitonAmazonAWS,wehavetofollowthesesteps:

1. RegisterwithAmazonAWSandoptforEC2.Amazonprovidesafreesubscriptionforwhichtheuserhastoprovidecreditcarddetails.Suchschemesaresubjecttochangeaspercompanypolicy.

2. Logintoyouraccount,gotoAWSservice,andthentocomputeandfindEC2.ClickonEC2andadashboardwillappear.ClickonLaunchInstanceanditwilldiverttochooseAmazonMachineImage(AMI).SupposewehavechosentheUbuntuserver.Nowit'stimetochoosetheinstancetype,whichcanbet2.small,t2.micro,t2.large,andmore.Clickonthelaunchbuttonandanotherwindowwillcomeforreviewlaunch.Reviewandclickonlaunch.

WecanalsoconfiguresecuritybyConfigureSecurityGroup.InthisSSHrowcanbechangetoMYIP.Clickonaddrule,andaddacustomTCPrule.Underportrange,changeitto3838,whichistheportforShinyserver.

Afterthis,clickonreviewandlaunchandyouwillgetadialogueboxforgeneratingaprivatekey.Here,wehavetogiveanametothekeyandclicktodownloadthekeypair.Afterthat,wewillgetthe.pemfile.Saveitsecurely.ClickonlaunchandgettheEC2instancerunningsuccessfully.CopytheIPaddressavailableundertheDNS(IPv4).

3. AccesstheEC2thatwecreated.Downloadputty,andconvertthe.pemfileintoppk.ClickonPuttygen,thenFiletab,andloadtheprivatekey.Navigateto.pemandimportit.Savetheprivatekeywithanametoyourdesiredlocation.Afterdoingallthis,wehaveour.ppkfile.Openputty,andinthehostnamebox,entertheIPaddressoftheEC2instance.NavigatetoAuthfor

Page 303: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

authenticationandimporttheppkkeythatwecreated.ClickonOpenandenteryourcredentials.

4. DownloadWinSCP,typetheEC2IP,andclickonadvance.UnderSSHAuthentication,entertheprivatekeyandclickonOk.EnternameasIPaddressandusernameandpassword.ClickYesinthedialogueboxthatappears.

5. Gototheroot.Gotothepromptandtypesudo-i,thenwewillgetthe#symbol.Runthefollowingcommands:

sudoapt-getupdate

sudoapt-getinstallr-base

sudoapt-getinstallr-base-dev

sudosu - -c"R-e\"install.packages('shiny',repos='http://cran.rstudio.com/')\""

ToinstallShinyserver,runthefollowingcommand:

wgethttps://download3.rstudio.org/ubuntu-12.04/x86_64/shiny-

server-1.4.4.807-amd64.deb

sudodpkg-ishiny-server-1.4.4.807-amd64.deb

6. Wecanseethefoldershiny-serverinthe/srv/shiny-server/path.Executethefollowingcommands:

sudochmod777/srv/shiny-server

sudomkdir/srv/shiny-server/Myapp_components

Intheprecedingcommand,theMyapp_componentsfolderiscreatedtosavethevariousshinyappcomponents,suchasserver.Randui.R.

7. AswehavealreadyinstalledandconfiguredwinSCPandcreatedtheMyapp_componentsfolder,wearereadytosendthecomponentstotheEC2instance.Configuretheshiny-server.conffile,whichislocatedin/etc/shiny-server/.Executethefollowingcommand:

sudochmod777/etc/shiny-server

Nowwecancopyconfigfileontothelocalsystem,editit,andsaveitback.

8. GototheAmazonconsoleandfindtherunningEC2instance.CopythepublicDNS,ec2-34-215-115-68.us-west-2.compute.amazonaws.com,appenditwith

Page 304: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

3838/Myapp_components,andpastethisinyourbrowser'sURLbar.PressEnterandyourappshouldstartrunning.

Page 305: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Scoping,loading,andreusingdatainShinyapplicationsAlthoughloadingandreusingdatainShinyapplicationsiscoveredinthischapter,becauseitislikelythatthesefeatureswouldbeusedinashinyapps.io-hostedapplication,muchofitalsoappliestolocally-runShinyapplications.Ifyouuseshinyapps.io,itwillexpectyourapplicationtobeportable,thatis,toavoiddependenceonwritingpermanentchangestothelocalfilesystem.Thisisbecausetheapplicationmightbemovedtoanotherserverforload-balancingpurposes,renderingchangestothepreviouslocalfilesysteminaccessible.Youcanwritetemporaryfileswhileauserisconnectedtotheapplication(forexample,iftheuseruploadstheirowndata,thiscanbesavedtemporarily),butanychangesmadewillbelostwhentheuserexits.

DependingontheenvironmentinwhichyouarerunningandthetaskyouarecarryingoutwithyourShinyapplication,itisusuallyagoodpracticeinmostcasestomakeallShinyapplicationsportable.Bymakingtheapplicationportable,youcannotonlyseamlesslyswitchtoshinyapps.io(evenifitisjusttoshareabetaversionwithcolleaguesusingafreeaccount),butitalsomeansthattheapplicationisportableacrossothercontexts;forexample,ifyoudistributeitviaa.zipfile,changeyourcomputer,ormigratetheserveronwhichyourunShinyServer.Itisimportant,therefore,tounderstandthescopingofdatawithinShinyapplicationsaswellasthemeansofgettingdatainandout,bothtemporarilyandpermanently.

Page 306: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Temporarydatainput/outputTherearethreelevelsofscopingwithinthetemporary,portablepartofaShinyapplication:

Thelowestlevelisdatathatisread-onlywithineachindividualinstanceofaShinyapplication.Thislevelisquiteusefulifauserwantsafreshcopyofdataeachtimetheyvisittheapplication(ifdataneedstobeevenfresherthanthis,itcanbeplacedinareactivefunction).AnydataloadedaftertheshinyServer()functionwillbescopedlikethis.Notethatthisdataisonlyavailablefromtheserver.Rfileandnotfromtheui.Rfile,whichisloadedfirst.Thenextlevelupisdatathatisavailabletoallinstancesoftheapplication(again,justwithinserver.R).Thiscanbeusefulifthereisaverylargedatasetthatneedstobeloadedorthatneedssignificantprocessing;thiscanthenbedonethefirsttimetheapplicationspinsup,sousersdonothavetowaitforit.AnydataloadedbeforetheshinyServer()functionwillbescopedinthisway.Lastly,itispossibletomakedataavailabletoui.Randserver.Racrossallfunctionsbyloadingitinafilecalledglobal.R.Itisn'tveryoftenthatyouwouldwanttodothis;Ineverhave,butyoumayfinditusefulifyouwishtoconfigureyourUIusingdatabutdon'twantorneedtheextracodeandprocessingtimeadynamicUIwouldnecessitate.

RememberthatitisveryeasytogetdatainandoutofShinysessions(thatis,temporarily)usingthefileInput()anddownloadHandler()functions.

Page 307: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

PersistentdatastorageIndatascienceproductdevelopment,oneofthemostimportantstepsistobringdatafromvarioussourcesandkeepitonstoragesystems.Mostly,data-storagemanagementfordatascienceprojectsisdonewithadatawarehouse.Nowadays,varioustechnologieshavebeendevelopedtostoreandprocessvarioustypesofdata,whichcanbestructured,semi-structured,orunstructured.UsingHadoop,HDFS,Hive,MongoDB,SQLite,orMySQL-liketoolsandtechnologiesarecoupleduptodevelopanecosystemtomakeforeasyavailabilityandfastprocessingofdata.

Innormalsoftware,thedatasourcesareusuallyRDBMSandmeanttodealwithonlinetransactionalrequirements.Butindatascienceprojects,thescenariosarequitedifferent.Here,generallyhistoricaldataisusedtopresentgraphsorgeneratereports.AndsinceShinyisalsoconsideredatooltopresentdata,itislesslikelytoexpectthatitsappswillacceptdatafromusersallthetime.Butthiscasealsoneedstobeconsidered.Inthissection,wewilldiscussthepersistentdata-storageoptionsavailablewithshinyappsandinwhatsituationstheyaregoingtobeused.

Asofnow,whateverShinyappswehavedevelopedareusinginbuiltdata.Suchdataiskeptlocallywheretheappresides.Forverysmalldata,thistechniquecanworkforsometime.Butasthedatagrows,theappwillbeunmanageable.Insuchscenarios,weneedtolookforotheroptionsthatcanhandlethegrowingdemandofdata.Today'sworldhassurpassedthebigdatalimits.So,whataretheoptionsavailable?

Let'sdiscusssomeofthepersistentdata-storageoptionsavailable:

Localfilesystem:Thisisaveryeasywaytostoredatawheretheappresides.Ifwehaveconfiguredtheshinyserverin-houseforthedeploymentoftheapp,wecantakesomememorytosavethedataacceptedfromuserorgeneratedduringtheexecution.Withthismethod,datacanbesavedandaccessedveryfast.Supposewewanttosavedataintoadataframeandkeepaddingdataintothistable.Wecanfollowsomeeasystepsand

Page 308: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

developourapp:

1. WithanewRscriptfile,createadataframe:

NewDF<-data.frame("Sn","Name","Age")

Aftertheexecutionoftheprecedingcode,NewDFdataframewillbereadytouse.

NowifwewanttoadddatatothisNewDF,wehavetowritethefollowingsimplecode:

#insertdatainfirstrow.

NewDF[1,]<-c(1,"Rahul",25)

#insertdatainsecondrow

NewDF[2,]<-c(2,"Sumit",26)

2. IntheNewDF[1,]code,thefirstpartofthesubscripthastherownumberandthesecondcolumnnumber.NewDF[1,]isreferringtothefirstrowandallthecolumns.Similarly,NewDF[2,]referstothesecondrowandallthecolumns.Inthisway,datacanbeadded,modified,anddeletedwiththehelpoftheshinyapp.Andatthesametime,dataisresidingonapersistentstorage.Thisisoneofthemostimportantmethods,becausewhicheverecosystemisfollowedfordata-warehousing,somepartofthedatahastobekeptonShinylocalstorageforprocessing.

Dropbox:Dropboxisaverypopularstoragesystemavailableremotely.Itsupportsavarietyoffileformats.rdrop2isapackagetoaccessDropboxfromR.Itprovidesfunctionsforlistingfiles,copying,moving,anddeleting.ToaccessDropbox,wehavetofirstcreateanaccount.Thebasicsubscriptionisfreeandprovides2GBspaceforuse.Pleasevisithttps://www.dropbox.com/individualforabasicsubscription.TousedatafromDropbox,weneedtogothroughtheauthenticationprocessfirst:

library(rdrop2)

drop_auth()

Afterexecutingtheprecedingcode,itwilllaunchthebrowserandaskforyourDropboxaccountdetails.Wehavetologintoouraccount.Oncethisprocessisdone,closethebrowserandcompletetheauthenticationfromR.Thecredentialscanbeautomatically

Page 309: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

cachedandusedinfuture.Wecanalsosavethetokenusingthefollowingcode:

token<-drop_auth()

saveRDS(token,file="token.rds")

Wecanalsoretrieveouraccountinformationusingthedrop_acc()%>%data.frame()command.MostofthecommandstoaccessDropboxfromRstartwithdrop_likedrop_acc().Fordirectory-listing,drop_dir()canbeused.IfyouwanttouploadafiletoDropbox,wecanusethefollowingcode:

write.csv(newFile,"newfile.csv")

drop_upload("newfile.csv")

Inasimilarway,drop_create(),drop_download(),drop_delete(),drop_move(),anddrop_copy()canalsobeused.AllthesediscussedfunctionscanbeusedwithRShinyapps.

AmazonAWSS3:Apopularplatformforfilehosting.Itkeepsfilesinbuckets.aws.s3isthepackageprovidedwithRtoaccessAWSS3.Theaws.s3packageisnotavailableonCRAN.Thefollowingcodecanbeuseforinstallation:

#lateststableversion

install.packages("aws.s3",repos=c("cloudyr"=

"http://cloudyr.github.io/drat"))

#onwindowsyoumayneed:

install.packages("aws.s3",repos=c("cloudyr"=

"http://cloudyr.github.io/drat"),INSTALL_opts="--no-multiarch")

Tousethispackage,weneedtocreateanaccountwithAmazonAWSforS3.Afreeaccountcanalsobecreatedwithlimitedaccessforoneyear.Oncewegetregistered,wecangeneratekeypairsontheIAMManagementwindowwiththeheadingaccesskey.Youcanalsovisithttps://github.com/cloudyr/aws.signature/formoredetaileddescriptionsofthecredentials.ItcanalsobedonethroughRusingthefollowingcode:

Sys.setenv("AWS_ACCESS_KEY_ID"="mykey",

"AWS_SECRET_ACCESS_KEY"="mysecretkey",

"AWS_DEFAULT_REGION"="us-east-1",

"AWS_SESSION_TOKEN"="mytoken")

Aftersettingcredentials,wecanaccessbucketsusingthefollowingcode:

Page 310: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

"library("aws.s3")

bucketlist()

Wecanalsoaccesspublicly-listedbuckets:

bucketlist()get_bucket(bucket='1000genomes')

TogetalistofalltheobjectsintheprivateS3bucket,thefollowingcodeisuseful:

#specifykeys

get_bucket(

bucket='my_bucket',

key=YOUR_AWS_ACCESS_KEY,

secret=YOUR_AWS_SECRET_ACCESS_KEY

)

#specifykeysasenvironmentvariables

Sys.setenv("AWS_ACCESS_KEY_ID"="mykey",

"AWS_SECRET_ACCESS_KEY"="mysecretkey")

get_bucket("my_bucket")

Theaws.s3packagehasmanyfunctions.Someofthemareasfollows:

bucketlist():Providesadataframeofusers'buckets.get_bucket():Providesalistanddataframe,respectively,ofobjectsinagivenbucket.get_bucket_df():Providesalistanddataframe,respectively,ofobjectsinagivenbucket.object_exists():Providesalogicaloutputforwhetheranobjectexists.s3read_using():ProvidesagenericinterfaceforreadingfromS3objectsusingauser-definedfunction.get_object():ReturnsarawvectorrepresentationofanS3object.s3connection():ProvidesabinaryreadableconnectiontostreamanS3objectintoR.SQLite:Alightweightdatabaseengineavailablepublicly.Itsupportsstructureddata-management.Wecancreatetablesandperformupdate,deletion,andinsertionoperationsonit.Italsosupportstransactionmanagement.

ToembedSQLiteintoR,theRSQLitepackageneedstobeinstalled.ItisavailableonCRAN:

install.packages("RSQLite")

AconnectiontoSQLitecanbecreatedusingthefollowingcommand:

Page 311: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

library(DBI)

con<-dbConnect(RSQLite::SQLite(),":memory:")

dbListTables(con)

Usingtheprecedingconnectionobject,con,wecanwritethedatasetinSQLite,asshowninthefollowingsnippet:

dbWriteTable(con,"iris",iris)

dbListTables(con)

Tofetchthecolumnsofthetable:

dbListFields(con,"iris")

Andtofetchtheentiretable:

dbReadTable(con,"iris")

Afterusingoftheconnection,wemustcloseitusingdbDisconnect(con):

MySQL:MySQLisaverypopularRDBMSdatabase-managementtoolavailablepublicly.ItissimilartoSQLitebutmorepowerful.Itcanbehostedlocallyorremotely.WecanusetheRMySQLpackagetointeractwithMySQLandR.ThepackagecanbedownloadedfromCRAN:

install.packages("RMySQL")

ToinstallintheLinuxplatformorOSX,youneedtheMariaDBConnector.RMySQLactsasaninterfacebetweenRandMySQL:

library(RMySQL)

library(DBI)

con<-dbConnect(RMySQL::MySQL(),group="my-db")

Inthefollowingcode,dbConnect()isthefunctiontoestablishaconnectionwiththeMySQLdatabasefromR.TheconobjectcannowbeusedtoperformvariousoperationsonDatabase.Let'sseesomeofthem:

dbListTables(con)

Theprecedingcodeliststhetablesinthedatabase.TowriteatablefromRintoMySQL,usethefollowingcode:

dbWriteTable(con,"iris",iris)

dbListTables(con)

Page 312: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Wecanalsofetchtheentiretablefromthedatabaseasfollows:

#Youcanfetchallresults:

res<-dbSendQuery(con,"SELECT*FROMiris")

dbFetch(res)

Todisconnecttheconnection,usethefollowingcode.

dbDisconnect(con)

GoogleSheets:Googlesheetsisalsoagoodoptionforstoringdata.Itispersistentandaccessiblefromanywhere.Googlesheetscanbeaccessedusingatitle,key,orURL.Datacanbeeasilyextractedoredited.Wecancreate,delete,rename,copy,anduploadGooglesheets.Wecanalsouploadlocally-generatedspreadsheetsintoGooglesheetsandviceversa.

TouseGooglesheetsfromR,wecanusethegooglesheetspackage.Itisdevelopedtobeusedwiththe%>%pipeoperator.Itusesthedplyrpackageinternally.ItcanbedownloadedfromCRAN:

install.packages("googlesheets")

Withthispackage,ademosheetforpracticeisavailable,namedGapminder.Let'susesomecodetoplaywiththissheet:

gs_gap()%>%

gs_copy(to="Gapminder")

Thiscodeisforthecopyingofthesheet.Toviewthesheetinthebrowser:

gap%>%gs_browse()

gap%>%gs_browse(ws="Europe")

Toreadallthedataintheworksheet,wecanusethefollowingcode:

africa<-gs_read(gap)

glimpse(africa)

Africa

Wecanalsotargetspecificcells:

gap%>%gs_read(ws=2,range="A1:D8")

Wecanalsocreatenewspreadsheets:

Page 313: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

giris_ss<-gs_new("iris",input=head(iris,3),trim=TRUE)

WecanexploremoreaboutgooglesheetsandRathttps://github.com/jennybc/googlesheets#install-googlesheets.

Page 314: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DatabaseusingDplyr,DBI,andPOOLInthissection,wewilllearntousethedplyrpackagetoaccessdatafromdatabasesources.WewillalsoseehowtohookuptoanexternaldatabaseusingtheDBIpackage.ThePoolpackageisalsoanimportanttopictomanageconnectionsandpreventleakstomanageperformance.

dplyr:Apopulardata-manipulationpackageforinternalandexternaldatabases.ItinternallyworksasSQL.Itprovidesavarietyoffunctionsfordatamanipulation:

filter()

select()

arrange()

rename()

distinct()

mutate()

transmute()

summarise()

sample_n()

sample_frac()

Let'sseeanexampleusingsomeofthesefunctionswiththeirisdataset:

library(dplyr)

iris%>%filter(Sepal.Length>4&Sepal.Length<5)

Intheprecedingcode,thefilterfunctionhasbeenusedtofiltertherowsoftheirisdataset,whichhasvaluesbetween4and5.Wecanalsoselectonlycertaincolumns,usingselect():

iris%>%select(Sepal.Length)

Forselectingdistinctvalues,wecanusedistinct():

iris%>%distinct()

Page 315: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Wecanalsousethesefunctionsincombination.Thecodeshownhereisfirstfilteringthedataandthenapplyingselect():

iris%>%filter(Sepal.Length>4&Sepal.Length<5)%>%select(Sepal.Length)

Inthisway,wecangetrideofusingRandSQLseparatelyusingdplyr.

DBI:AcommoninterfacebetweenRandDBMS.Italsoprovidesavarietyoffunctionsforsupportingthefollowingfunctions:

ConnectinganddisconnectingtotheDBMSCreatingstatementsandexecutingintheDBMSExtractingresultsfromstatementsException-handlingTransactionmanagement

dbGetQuery()isaconvenientwayofexecutingquerieswithaconnectionobject.Ittakestwoargumentsimportantlyconnectiontodatabaseandquery:

dbGetQuery(conn,"SELECT*FROMCityLIMIT5;")

Pool:WiththeDBIpackage,therearesomeproblemswithconnection-managementandperformance.Wehavetocreateanddestroyconnectionsasandwhennecessary.Otherwise,therewillbeanaccumulationofleakedconnections.Thisleakedconnectionholdsresourcesthatmusthavebeenfreed.Becauseofthisapp,theperformancegoesdown.Fordealingwithsuchproblems,poolpackageisavailable.Itprovidesanextralayerofabstractionwhileestablishingaconnection.Usingthispackage,wecancreateanobjectwithareferencetothedatabase.Thisobjectiscalledpool.Thismakesusavoiddirectlyfetchingthedatabase.Also,thispoolobjectcanholdanumberofconnectionstothedatabase.Wheneverwearequeryingthedatabase,weareactuallyqueryingtothepoolthatholdstherunningandwaitingconnections.

Thepoolcanprovideuswithidleconnectionsthatwerepreviouslyfetchedorwithanewone.Oncetheconnectionisended,thegarbage-collectionprocessmakesfreeallresourcesheldbytheconnection.So,inthecontextoftheShinyapp,wedon'thavetoworryaboutendingtheconnection.

ThepoolpackageisavailableonGitHubandcanbedownloadedasfollows:

devtools::install_github("rstudio/pool")

Page 316: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Let'sseetheskeletonofaShinyappwithpool:

library(shiny)

library(DBI)

library(pool)

pool<-dbPool(

drv=RMySQL::MySQL(),

dbname="Database_Name",

host="Host_link",

username="username",

password="password"

)

ui<-fluidPage(

#--------Uistuff----------------------

)

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

#----ServerStuff-------------------

}

shinyApp(ui,server)

WithsqlInterpolate(),wecancreateaquerythatcanbetheinputtodbGetQuery().InsqlInterpolate,wecanseethreeparametersinthefunction:pool,sql,andid.poolistheobjectandsqlistheSQLquery.IDcanbeanyinput.dbGetQuery()willhavetwoparameters.Thepoolobjectandqueryarecreatedusinginterpolate:

query<-sqlInterpolate(pool,sql,id=input$ID)

dbGetQuery(pool,query)

Thisappskeletonisforasingle-fileapp.Foramulti-fileapp,itcanbeputonthetopoftheserveranduifileorinaglobalfile.

Page 317: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SQLInjectionSQLInjectionisakindofattackdonebyaddingSQLquirestotheURLoftheapplication.SuchqueriesexecuteontheDBMSwithouthavinglegitimateaccesstoit.Suchattacksarepossibleiftherearesomebranchesintothecode.Let'sseesomecodetounderstanditbetter:

dbGetQuery(conn,paste0("SELECT*FROMCityLIMIT",input$nrows,";"))

Aswecanseeintheprecedingcode,input$nrowshasbeenputdirectlyintothequery.Ifanattackergotaccesstothisinput$nrows,theycouldinjectanySQLstatementintoit.Inthiscase,thesolutioncanbetopreventanattackerfrompassingvectors.So,thecodecanbemodifiedasfollows:

dbGetQuery(conn,paste0("SELECT*FROMCityLIMIT",as.integer(input$nrows)[1],";"))

Theinputisconvertedintoanintegerfirst.So,ifanattackerputssomeSQLintoit,itwillgetconvertedintoanintegerandloseitsmeaning.Thisisaneasyexample.Let'sdiscussamorecomplexsituation:

query<-paste0("SELECT*FROMCityWHEREID='",input$ID,"';")

Inthiscode,ifanattackergetsaccesstoinput$IDandmanagestomodifythevalue,theycangetthedataofasinglecity.Forexample,input$IDchangedto5meansthatthedataofthecitywithID=5willbeinvoked.Butiftheyaretryingtogetinformationofallthecities,theycantryOR1=1ORandcangetdataofallthecity.Suchinputmakestheconditionalwaystrue.ThesolutiontothisattackistousesqlInterpolate().ItcanbeusedtointerpolatethevaluesintoaSQLstring,whichpreventsaSQLinjectionattack:

sql<-"SELECT*FROMCityWHEREID=?id;"

query<-sqlInterpolate(conn,sql,id=input$ID)

Intheprecedingcode,ifwechangetheinputto'OR1=1OR',itwillbeconvertedintoSELECT*FROMCityWHEREID='''OR1=1OR''',whereithasaddedextra('').ThiswillgiveblanktableoutputandpreventsSQLinjection.Instead,ifweuseinput$ID=6,itwillchangethequerytoSELECT*FROMCityWHEREID='6',whichisavalidID.SotheoutputwillbethedataofthecitywithID=6.

Page 318: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Thisprocessofcheckingandconvertinguserinputintosafevaluesiscalledsanitization.WemustalwaystakecaretosanitizetheuserinputtopreventSQLinjectionattacks.

Page 319: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

SummaryInthischapter,welearnedaboutseveralmethodstoshareyourShinyapplicationswiththeworld.ThisprocessisveryeasywithfellowusersofR,andalittleharderwiththewholeinternet;howeveryoudoit,I'msureyou'llagreethatitwasrelativelypainlessandworththeeffort.WediscussedhowtouseGitandGitHub(andGist),andhowtousethemtoshareyourcodeandapplicationswithotherRusers.WealsolookedatdistributingShinyapplicationsmanuallyoroverFTPtoRusersusingthe.zipand.tarfiles.Wecoveredhostingsolutionstoshareyourapplicationwiththewholeinternet,includingShinyapps,ShinyServer,andAmazonAWS.Wewentthroughthepersistentdata-storageoptionsandhowtousethedplyr,DBI,andPoolpackages.WealsosawhowtopreventSQLinjectionattacks.

Page 320: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

OtherBooksYouMayEnjoyIfyouenjoyedthisbook,youmaybeinterestedintheseotherbooksbyPackt:

RDataVisualizationRecipesVitorBianchiLanzetta

ISBN:9781788398312

GettoknowvariousdatavisualizationlibrariesavailableinRtorepresentdataGenerateelegantcodestocraftgraphicsusingggplot2,ggvisandplotlyAddelements,text,animation,andcolorstoyourplottomakesenseofdataDeepenyourknowledgebyaddingbar-charts,scatterplots,andtimeseriesplotsusingggplot2BuildinteractivedashboardsusingShiny.ColorspecificmapregionsbasedonthevaluesofavariableinyourdataframeCreatehigh-qualityjournal-publishablescatterplotsCreateanddesignvariousthree-dimensionalandmultivariateplots

Page 321: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

DataAnalysiswithR-SecondEditionTonyFischetti

ISBN:9781788393720

GainathoroughunderstandingofstatisticalreasoningandsamplingtheoryEmployhypothesistestingtodrawinferencesfromyourdataLearnBayesianmethodsforestimatingparametersTrainregression,classification,andtimeseriesmodelsHandlemissingdatagracefullyusingmultipleimputationIdentifyandmanageproblematicdatapointsLearnhowtoscaleyouranalysestolargerdatawithRcpp,data.table,dplyr,andparallelizationPutbestpracticesintoeffecttomakeyourjobeasierandfacilitatereproducibility

Page 322: Web Application Development with R Using Shiny · is the author of Web Application Development with R Using Shiny. He works full-time, developing software to store, collate, and present

Leaveareview-letotherreadersknowwhatyouthinkPleaseshareyourthoughtsonthisbookwithothersbyleavingareviewonthesitethatyouboughtitfrom.IfyoupurchasedthebookfromAmazon,pleaseleaveusanhonestreviewonthisbook'sAmazonpage.Thisisvitalsothatotherpotentialreaderscanseeanduseyourunbiasedopiniontomakepurchasingdecisions,wecanunderstandwhatourcustomersthinkaboutourproducts,andourauthorscanseeyourfeedbackonthetitlethattheyhaveworkedwithPackttocreate.Itwillonlytakeafewminutesofyourtime,butisvaluabletootherpotentialcustomers,ourauthors,andPackt.Thankyou!