![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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/1.jpg)
![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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/2.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/3.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/4.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/5.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/6.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/7.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/8.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/9.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/10.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/11.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/12.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/13.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/14.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/15.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/16.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/17.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/18.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/19.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/20.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/21.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/22.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/23.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/24.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/25.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/26.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/27.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/28.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/29.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/30.jpg)
>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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/31.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/32.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/33.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/34.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/35.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/36.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/37.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/38.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/39.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/40.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/41.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/42.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/43.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/44.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/45.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/46.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/47.jpg)
![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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/48.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/49.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/50.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/51.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/52.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/53.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/54.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/55.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/56.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/57.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/58.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/59.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/60.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/61.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/62.jpg)
![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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/63.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/64.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/65.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/66.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/67.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/68.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/69.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/70.jpg)
![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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/71.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/72.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/73.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/74.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/75.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/76.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/77.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/78.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/79.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/80.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/81.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/82.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/83.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/84.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/85.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/86.jpg)
![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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/87.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/88.jpg)
),
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/89.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/90.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/91.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/92.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/93.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/94.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/95.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/96.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/97.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/98.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/99.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/100.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/101.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/102.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/103.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/104.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/105.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/106.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/107.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/108.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/109.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/110.jpg)
<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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/111.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/112.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/113.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/114.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/115.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/116.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/117.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/118.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/119.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/120.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/121.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/122.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/123.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/124.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/125.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/126.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/127.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/128.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/129.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/130.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/131.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/132.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/133.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/134.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/135.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/136.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/137.jpg)
![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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/138.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/139.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/140.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/141.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/142.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/143.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/144.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/145.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/146.jpg)
...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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/147.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/148.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/149.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/150.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/151.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/152.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/153.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/154.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/155.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/156.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/157.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/158.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/159.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/160.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/161.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/162.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/163.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/164.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/165.jpg)
}
//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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/166.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/167.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/168.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/169.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/170.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/171.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/172.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/173.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/174.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/175.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/176.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/177.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/178.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/179.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/180.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/181.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/182.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/183.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/184.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/185.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/186.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/187.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/188.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/189.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/190.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/191.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/192.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/193.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/194.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/195.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/196.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/197.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/198.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/199.jpg)
![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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/200.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/201.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/202.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/203.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/204.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/205.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/206.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/207.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/208.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/209.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/210.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/211.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/212.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/213.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/214.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/215.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/216.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/217.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/218.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/219.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/220.jpg)
(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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/221.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/222.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/223.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/224.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/225.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/226.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/227.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/228.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/229.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/230.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/231.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/232.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/233.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/234.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/235.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/236.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/237.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/238.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/239.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/240.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/241.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/242.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/243.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/244.jpg)
)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/245.jpg)
})
}
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/246.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/247.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/248.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/249.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/250.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/251.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/252.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/253.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/254.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/255.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/256.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/257.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/258.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/259.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/260.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/261.jpg)
})
}
#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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/262.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/263.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/264.jpg)
![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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/265.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/266.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/267.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/268.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/269.jpg)
#
#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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/270.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/271.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/272.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/273.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/274.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/275.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/276.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/277.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/278.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/279.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/280.jpg)
![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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/281.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/282.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/283.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/284.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/285.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/286.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/287.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/288.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/289.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/290.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/291.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/292.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/293.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/294.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/295.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/296.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/297.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/298.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/299.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/300.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/301.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/302.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/303.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/304.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/305.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/306.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/307.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/308.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/309.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/310.jpg)
"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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/311.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/312.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/313.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/314.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/315.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/316.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/317.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/318.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/319.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/320.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/321.jpg)
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](https://reader034.vdocuments.mx/reader034/viewer/2022042110/5e8b553cc8140f0abf21d106/html5/thumbnails/322.jpg)
Leaveareview-letotherreadersknowwhatyouthinkPleaseshareyourthoughtsonthisbookwithothersbyleavingareviewonthesitethatyouboughtitfrom.IfyoupurchasedthebookfromAmazon,pleaseleaveusanhonestreviewonthisbook'sAmazonpage.Thisisvitalsothatotherpotentialreaderscanseeanduseyourunbiasedopiniontomakepurchasingdecisions,wecanunderstandwhatourcustomersthinkaboutourproducts,andourauthorscanseeyourfeedbackonthetitlethattheyhaveworkedwithPackttocreate.Itwillonlytakeafewminutesofyourtime,butisvaluabletootherpotentialcustomers,ourauthors,andPackt.Thankyou!