Vous êtes sur la page 1sur 116

Tutorial in R Shiny package:

Developing Web Applications in the area of


Biostatistics & Data Science
Martial Luyts

Jeroen Sichien

Interuniversity Institute for Biostatistics and statistical Bioinformatics (I-BioStat)


Katholieke Universiteit Leuven, Belgium
martial.luyts@kuleuven.be & jeroen.sichien@kuleuven.be
www.ibiostat.be

Interuniversity Institute for Biostatistics


and statistical Bioinformatics

Belgium, 30 March 2016

Contents
1. Introductory material . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

10

2. Interface development . . . . . . . . . . . . . . . . . . . . . . . . . . . .

12

. . . . . . . . . . . . . . . . . . . . . . . . . . . .

13

. . . . . . . . . . . . . . . . . . . . . . . . . . .

15

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

17

1.1. Motivation

1.2. Introduction to R Shiny


1.3. Example

2.1. Inputs within the UI framework

2.2. Outputs within the UI framework


2.3. Assemble UI framework

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

21

3. Learn to build an app in Shiny . . . . . . . . . . . . . . . . . . . . . . .

25

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

26

. . . . . . . . . . . . . . . . . . . . . . . . . .

49

. . . . . . . . . . . . . . . . . . . . . . . . . . .

63

. . . . . . . . . . . . . . . . . . . . . . . . . . . .

80

2.4. Layout structure of the UI

3.1. Step-by-step approach

3.2. Focus on special reactive functions


3.3. Progress dynamic user interface
3.4. Extension to dashboard shells

4. Apps in the area of biostatistics & data science . . . . . . . . . . . . . 109


4.1. Shiny as an extra tool ...

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 110

4.2. Other way of constructing Shiny apps


4.3. To the applications ...

. . . . . . . . . . . . . . . . . . . . . . . . . 111

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 112

References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113

Belgium, 30 March 2016

ii

Part 1:
Introduction, motivation and example

Belgium, 30 March 2016

Chapter 1:
Introductory material
Motivation

Introduction to R Shiny

Example

Belgium, 30 March 2016

1.1 Motivation
Biostatisticians often employ their analysis in R

Presenting/sharing their results are often done in a static format ...

Problem: Additionally questions related to their work cannot be showed immediately

Belgium, 30 March 2016

Simple idea: Move the water surface downwards to give more knowledge to the
audience (e.g. medical doctors)

Possible solution for gaining this information: R Shiny


Belgium, 30 March 2016

1.2 Introduction to R Shiny


R Shiny = R + interactivity + web made easy
In words: Open source R package from Rstudio that creates interactive web
applications around your R analyses and visualizations

No HTML/CSS/Javascript knowledge required to implement ...

.... but fully customizable and extensible with HTML/CSS/JavaScript

Belgium, 30 March 2016

Deploying Shiny Apps can happen in different ways:


Shiny Server (AGPLv3)
https://github.com/rstudio/shiny-server
Shiny Server Pro
Secure user access, tune application performance, monitor resource utilization
and get the direct support from R Studio, Inc.
https://www.rstudio.com/pricing/
Shiny hosting on rstudio.com
http://www.shinyapps.io

Remark: Basic knowledge of R code required

Belgium, 30 March 2016

Whats a Shiny App?


A Shiny app is a web page (UI) connected to a computer/server running a live R
session (Server)

Users can manipulate the UI, which will cause the server to update the UIs displays
(by running R code)

Belgium, 30 March 2016

Shiny Apps can be developed with the following template in R:


app.R:
>
>
>
>

library ( shiny )
u i < f l u i d P a g e ( )
s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
shinyApp ( u i = ui , s e r v e r = s e r v e r )

ui: Nested R functions that assemble an HTML user interface for the app
server: A function with instructions on how to build and rebuild the R objects
displayed in the UI
shinyApp: Combines ui and server into a functioning app

Save the template as app.R

Belgium, 30 March 2016

Alternatively, split template into two files named ui.R and server.R:
ui.R:

server.R:

> fluidPage ()

> f u n c t i o n ( i n p u t , o u t p u t ){}

Remark: No need to call shinyApp()

Save each app as a directory that contains an app.R file (or a ui.R file and a
server.R file) plus optional extra files

Belgium, 30 March 2016

1.3 Example
> library ( shiny )
> u i < f l u i d P a g e (
n u m e r i c I n p u t ( i n p u t I d = n ,
Sample s i z e , v a l u e = 2 5 ) ,
plotOutput ( outputId = h i s t ))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $ h i s t < r e n d e r P l o t ({
h i s t ( rnorm ( i n p u t $n ) )
})}
> shinyApp ( u i = ui , s e r v e r = s e r v e r )

Belgium, 30 March 2016

10

Part 2:
Layouts and functions

Belgium, 30 March 2016

11

Chapter 2:
Interface development
Design & explore UI framework
Inputs within the UI framework
Outputs within the UI framework

Assemble UI with HTML/CSS/... widgets

Adjustment of the layout scheme

Belgium, 30 March 2016

12

2.1 Inputs within the UI framework


> library ( shiny )
> u i < f l u i d P a g e (
n u m e r i c I n p u t ( i n p u t I d = n ,
Sample s i z e , v a l u e = 2 5 ) ,
plotOutput ( outputId = h i s t ))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $ h i s t < r e n d e r P l o t ({
h i s t ( rnorm ( i n p u t $n ) )
})}
> shinyApp ( u i = ui , s e r v e r = s e r v e r )

Input values are reactive


Access the current value of an input object with input$ < inputId >

Belgium, 30 March 2016

13

Different input functions are available:

Belgium, 30 March 2016

14

2.2 Outputs within the UI framework


> library ( shiny )
> u i < f l u i d P a g e (
n u m e r i c I n p u t ( i n p u t I d = n ,
Sample s i z e , v a l u e = 2 5 ) ,
plotOutput ( outputId = h i s t ))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $ h i s t < r e n d e r P l o t ({
h i s t ( rnorm ( i n p u t $n ) )
})}
> shinyApp ( u i = ui , s e r v e r = s e r v e r )

Used to add R output to the UI framework


Access the developed output of an output object with output$ < outputId >
render*() and *Output() functions work together
Belgium, 30 March 2016

15

Different output functions are available:

Belgium, 30 March 2016

16

2.3 Assemble UI framework


An apps UI is actually an HTML document
ui.R:
> f l u i d P a g e ( t e x t I n p u t ( a , ) )
## <d i v c l a s s = c o n t a i n e r f l u i d >
## <d i v c l a s s =formg r o u p s h i n y i n p u t c o n t a i n e r >
##
< l a b e l f o r =a></ l a b e l >
##
<i n p u t i d =a t y p e= t e x t
##
c l a s s =formc o n t r o l v a l u e =/>
## </ d i v >

Belgium, 30 March 2016

17

Static HTML elements can be added with tags, a list of functions that parallel
common HTML tags, e.g. tags$a()

Belgium, 30 March 2016

18

Example:
> u i < f l u i d P a g e (
t a g s $h1 ( LB i o s t a t App ) ,
tags $hr () ,
tags $br () ,
t a g s $p ( s t r o n g ( M a r t i a l L u y t s & J e r o e n S i c h i e n ) ) ,
t a g s $p (em( PhD s t u d e n t s i n s t a t i s t i c s ) ) ,
t a g s $a ( h r e f= h t t p s : // i b i o s t a t . be , I B i o s t a t ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = ui , s e r v e r = s e r v e r )

Belgium, 30 March 2016

19

Several files can be included as well:


CSS file
1. Place the file in the www subdirectory
2. Link to it with:
t a g s $head ( t a g s $ l i n k ( r e l = s t y l e s h e e t ,
t y p e = t e x t / c s s , h r e f = <f i l e n a m e > ) )
Javascript file
1. Place the file in the www subdirectory
2. Link to it with:
t a g s $head ( t a g s $ s c r i p t ( s r c = <f i l e n a m e > ) )
Image
1. Place the file in the www subdirectory
2. Link to it with: img(src = < f ilename > )
Belgium, 30 March 2016

20

2.4 Layout structure of the UI


Combine multiple elements into a single element that has its own properties with a
panel function
Example:

> u i < f l u i d P a g e (
wellPanel (
n u m e r i c I n p u t ( i n p u t I d = n ,
Sample s i z e , v a l u e = 2 5 ) ,
submitButton () ) ,
plotOutput ( outputId = h i s t ))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ) { . . . }
> shinyApp ( u i = ui , s e r v e r = s e r v e r )

Belgium, 30 March 2016

21

Different panels are available:

Organize panels and elements into a layout with a layout function

Belgium, 30 March 2016

22

Layer tabPanels on top of each other, and navigate between them

Belgium, 30 March 2016

23

Part 3:
Basic Tutorial to R Shiny

Belgium, 30 March 2016

24

Chapter 3:
Learn to build an app in Shiny
Step-by-step approach
Focus on special reactive functions
Progress dynamic user interface
Extension to dashboard shells

Belgium, 30 March 2016

25

3.1 Step-by-step approach


App 1:
Create a simple app that displays text within the title panel, sidebar panel and
main panel, where the sidebar panel is located on the right
Step 1: Install package & build framework

>
>
>
>
>

i n s t a l l . packages ( s h i n y )
library ( shiny )
u i < f l u i d P a g e ( )
s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

26

Step 2: Building the UI framework


> i n s t a l l . packages ( s h i n y )
> library ( shiny )
> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= F i r s t app . . . ) ,
sidebarLayout (
s i d e b a r P a n e l ( Sidebar panel , . . . ) ,
m a i n P a n e l ( Main p a n e l , . . . ) )
))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

27

Step 3: Adjusting the UI framework


> i n s t a l l . packages ( s h i n y )
> library ( shiny )
> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= F i r s t app . . . ) ,
s i d e b a r L a y o u t ( p o s i t i o n= r i g h t ,
s i d e b a r P a n e l ( Sidebar panel , . . . ) ,
m a i n P a n e l ( Main p a n e l , . . . ) )
))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

28

App 2:
Extend App 1 by displaying a box plot from random generating normal distributed
data in the main panel. Number of datapoints can be chosen apriori by the user in
the sidebar panel (located at the left).
Display:

Belgium, 30 March 2016

29

Step 1: Maintain framework without text in sidebar and main panel


> i n s t a l l . packages ( s h i n y )
> library ( shiny )
> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= Second app . . . ) ,
sidebarLayout (
sidebarPanel () ,
mainPanel ( ) )
))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

30

Step 2: Build the input structure in the sidebar panel


> i n s t a l l . packages ( s h i n y )
> library ( shiny )
> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= Second app . . . ) ,
sidebarLayout (
sidebarPanel ( numericInput ( inputId
=n , Sample s i z e , v a l u e =10)) ,
mainPanel ( ) )
))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

31

Step 3: Link the user inputs with R


> i n s t a l l . packages ( s h i n y )
> library ( shiny )
> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= Second app . . . ) ,
sidebarLayout (
sidebarPanel ( numericInput ( inputId
=n , Sample s i z e , v a l u e =10)) ,
mainPanel ( ) )
))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $box<r e n d e r P l o t ({
boxplot ( rnorm ( i n p u t $n ) , c o l=
b l u e , main= B o x p l o t o f n o r m a l
g e n e r a t e d d a t a , x l a b= Sample
data )})}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

32

Step 4: Output the boxplot in the UI main panel


> i n s t a l l . packages ( s h i n y )
> library ( shiny )
> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= Second app . . . ) ,
sidebarLayout (
sidebarPanel ( numericInput ( inputId
=n , Sample s i z e , v a l u e =10)) ,
mainPanel (
p l o t O u t p u t ( o u t p u t I d= box ) ) )
))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $box<r e n d e r P l o t ({
boxplot ( rnorm ( i n p u t $n ) , c o l =
b l u e , main= B o x p l o t o f n o r m a l
g e n e r a t e d d a t a , x l a b= Sample
data )})}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

33

App 3:
Extend App 2 by adding the possibility to choose your own title within a text input
and color of the box plot with a radio button (in the sidebar panel). Additionally,
a submit button needs to be present that only updates the main panel with a click.
Display:

Belgium, 30 March 2016

34

Step 1: Maintain framework of App 2


> i n s t a l l . packages ( s h i n y )
> library ( shiny )
> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= T h i r d app . . . ) ,
sidebarLayout (
sidebarPanel ( numericInput ( inputId
=n , Sample s i z e , v a l u e =10)) ,
mainPanel (
p l o t O u t p u t ( o u t p u t I d= box ) ) )
))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $box<r e n d e r P l o t ({
boxplot ( rnorm ( i n p u t $n ) , c o l =
b l u e , main= B o x p l o t o f n o r m a l
g e n e r a t e d d a t a , x l a b= Sample
data )})}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

35

Step 2: Extend slider panel layout


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= T h i r d app . . . ) ,
sidebarLayout (
sidebarPanel ( numericInput ( inputId
=n , Sample s i z e , v a l u e =10) ,
t e x t I n p u t ( i n p u t I d= t i t l e , T i t l e
o f . . . , Fancy B o x p l o t . . . ) ,
r a d i o B u t t o n s ( i n p u t I d= c o l o r ,
Choose . . . , l i s t ( B l u e , Green ) ,
Green ) ,
submitButton ( Apply changes ) ) ,
mainPanel (
p l o t O u t p u t ( o u t p u t I d= box ) ) ) ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $box<r e n d e r P l o t ({
boxplot ( rnorm ( i n p u t $n ) , c o l =
b l u e , main= B o x p l o t o f n o r m a l
g e n e r a t e d d a t a , x l a b= Sample
data )})}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

36

Step 3: Link the extra user inputs with R


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= T h i r d app . . . ) ,
sidebarLayout (
sidebarPanel ( numericInput ( inputId
=n , Sample s i z e , v a l u e =10) ,
t e x t I n p u t ( i n p u t I d= t i t l e , T i t l e
o f . . . , Fancy B o x p l o t . . . ) ,
r a d i o B u t t o n s ( i n p u t I d= c o l o r ,
Choose . . . , l i s t ( B l u e , Green ) ,
Green ) ,
submitButton ( Apply changes ) ) ,
mainPanel (
p l o t O u t p u t ( o u t p u t I d= box ) ) ) ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $box<r e n d e r P l o t ({
boxplot ( rnorm ( i n p u t $n ) , c o l =
i n p u t $ c o l o r , main=i n p u t $ t i t l e ,
x l a b= Sample d a t a ) } ) }
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

37

App 4:
Analyse the irish dataset by making a box plot of every numeric variable (i.e.,
Sepal.Length, Sepal.Width, Petal.Length, Petal.Width) per specie. Summarize these
box plots into one figure. Different slider inputs need to be used for choosing your
own subset of data.
Display:

Belgium, 30 March 2016

38

Step 1: Making libraries available & descriptive statistics irish dataset


>
>
>
>
>
>

i n s t a l l . packages ( s h i n y )
library ( shiny )
library ( ggplot2 )
library ( gridExtra )
str ( i r i s )
summary ( i r i s )

Step 2: Maintain framework of App 2


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= F o u r t h app . . . ) ,
sidebarLayout (
sidebarPanel () ,
mainPanel ( ) )
))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

39

Step 3: Import different slider inputs in UI slider panel


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= F o u r t h app . . . ) ,
sidebarLayout (
sidebarPanel (
s l i d e r I n p u t ( i n p u t I d= s e p a l l e n g t h ,
S e p a l . L e n g t h : , min =4.3 , max=7.9 ,
v a l u e =5.8 , step = 0 . 1 ) ,
s l i d e r I n p u t ( i n p u t I d= s e p a l w i d t h ,
S e p a l . Width : , min=2, max=4.4 ,
v a l u e =3, step = 0 . 1 ) ,
s l i d e r I n p u t ( i n p u t I d= p e t a l l e n g t h ,
P e t a l . L e n g t h : , min=1, max=6.9 ,
value = c (1.6 ,5.1)) ,
s l i d e r I n p u t ( i n p u t I d= p e t a l w i d t h ,
P e t a l . Width : , min =0.1 , max=2.5 ,
v a l u e =1.3 , step =0.3 ,
animate = animationOptions (
i n t e r v a l = 2 6 0 0 , l o o p = TRUE ) ) ,
mainPanel ( ) )
))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

40

Step 4: Link the different slider inputs with R & obtain own subsets
> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= F o u r t h app . . . ) ,
sidebarLayout (
sidebarPanel ( . . . ) ,
mainPanel ( ) ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $box < r e n d e r P l o t ({
s e p a l l<subset ( i r i s , S e p a l . L e n g t h >= 4 . 3
& Sepal . Length < i n p u t $ s e p a l l e n g t h ,
s e l e c t=c ( S e p a l . Length , S p e c i e s ) )
s e p a l w<subset ( i r i s , S e p a l . Width >= 2
& S e p a l . Width < i n p u t $ s e p a l w i d t h ,
s e l e c t=c ( S e p a l . Width , S p e c i e s ) )
p e t a l l<subset ( i r i s , P e t a l . Length>=
i n p u t $ p e t a l l e n g t h [ 1 ] & P e t a l . Length
< input$petallength [2] ,
s e l e c t=c ( P e t a l . Length , S p e c i e s ) )
p e t a l w<subset ( i r i s , P e t a l . Width >= 0 . 1
& P e t a l . Width < i n p u t $ p e t a l w i d t h ,
s e l e c t=c ( P e t a l . Width , S p e c i e s ) )
})}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

41

Step 5: Create box plots in R & combine them into one graph
> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= F o u r t h app . . . ) ,
sidebarLayout (
sidebarPanel ( . . . ) ,
mainPanel ( ) ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $box<r e n d e r P l o t ({
s e p a l l < subset ( . . . )
s e p a l w < subset ( . . . )
p e t a l l < subset ( . . . )
p e t a l w < subset ( . . . )
t e s t < g g p l o t ( s e p a l l , a e s ( x = S p e c i e s ,
y = S e p a l . L e n g t h ) ) + geom boxplot ( )
+ theme bw ( )
t e s t b < g g p l o t ( s e p a l w , a e s ( x = S p e c i e s ,
y = S e p a l . Width ) ) + geom boxplot ( ) + theme bw ( )
t e s t c < g g p l o t ( p e t a l l , a e s ( x = S p e c i e s ,
y = P e t a l . L e n g t h ) ) + geom boxplot ( )
+ theme bw ( )
t e s t d < g g p l o t ( p e t a l w , a e s ( x = S p e c i e s ,
y = P e t a l . Width ) ) + geom boxplot ( ) + theme bw ( )
g r i d . a r r a n g e ( t e s t , t e s t b , t e s t c , t e s t d , nrow=1)
})}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

42

Step 6: Output the box plot in the UI main panel


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= F o u r t h app . . . ) ,
sidebarLayout (
sidebarPanel ( . . . ) ,
mainPanel (
p l o t O u t p u t ( o u t p u t I d = box ) ) )
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $box<r e n d e r P l o t ({
s e p a l l < subset ( . . . )
s e p a l w < subset ( . . . )
p e t a l l < subset ( . . . )
p e t a l w < subset ( . . . )
t e s t < g g p l o t ( . . . ) + geom boxplot ( )
+ theme bw ( )
t e s t b < g g p l o t ( . . . ) + geom boxplot ( )
+ theme bw ( )
t e s t c < g g p l o t ( . . . ) + geom boxplot ( )
+ theme bw ( )
t e s t d < g g p l o t ( . . . ) + geom boxplot ( )
+ theme bw ( )
grid . arrange ( . . . ) } ) }
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

43

App 5:
Analyse the irish dataset by creating two tabsets in the main panel. The first
one contains a histogram per chosen variable, while the second one displays a
summary output of all variables. Variable selection is obtained by a select input.
Display:

Belgium, 30 March 2016

44

Step 1: Create basic layout structure

> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= F i f t h app . . . ) ,
sidebarLayout (
sidebarPanel () ,
mainPanel ( ) )
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

45

Step 2: Build the input structure in the sidebar panel


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= F i f t h app . . . ) ,
sidebarLayout (
sidebarPanel (
s e l e c t I n p u t ( i n p u t I d= v a r , 1 .
S e l e c t . . . , c h o i c e s=c (
S e p a l . L e n g t h =1, S e p a l . Width =
2 , P e t a l . L e n g t h =3, P e t a l . Width
=4) , s e l e c t e d =3, s e l e c t i z e =FALSE ) ,
s l i d e r I n p u t ( i n p u t I d= b i n , 2 . S e l e c t
. . . , min=5, max=25 , v a l u e =15) ,
r a d i o B u t t o n s ( i n p u t I d= c o l o u r ,
l a b e l= 3 . S e l e c t . . . , c h o i c e s=c (
black , yellow , red ) , s e l e c t e d
= y e l l o w )
),
mainPanel ( ) )
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

46

Step 3: Link the user inputs with R


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= F i f t h app . . . ) ,
sidebarLayout (
sidebarPanel (
selectInput (...) ,
sliderInput (...) ,
radioButtons ( . . . ) ) ,
mainPanel ( ) ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $ t e x t 1 < r e n d e r T e x t ({
colm = as . numeric ( i n p u t $ var )
paste ( The . . . , names ( i r i s [ colm ] ) ) } )
o u t p u t $ m y h i s t < r e n d e r P l o t ({
colm = as . numeric ( i n p u t $ var )
h i s t ( i r i s [ , colm ] , c o l =i n p u t $ c o l o u r ,
x l i m = c ( 0 , max( i r i s [ , colm ] ) ) ,
main = H i s t o g r a m . . . , b r e a k s =
seq ( 0 , max( i r i s [ , colm ] ) , l=i n p u t $ b i n +1) ,
x l a b = names ( i r i s [ colm ] ) ) } )
o u t p u t $summary < r e n d e r T a b l e ({
summary ( i r i s ) } )
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

47

Step 4: Create tabsets with outputs in the UI main panel


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= F i f t h app . . . ) ,
sidebarLayout (
sidebarPanel (
selectInput (...) ,
sliderInput (...) ,
radioButtons ( . . . ) ) ,
mainPanel (
t a b s e t P a n e l ( t y p e= t a b ,
t a b P a n e l ( P a n e l 1 ,
t e x t O u t p u t ( o u t p u t I d= t e x t 1 ) ,
p l o t O u t p u t ( o u t p u t I d= m y h i s t ) ) ,
t a b P a n e l ( P a n e l 2 ,
t a b l e O u t p u t ( o u t p u t I d= summary ) ) )
)))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $ t e x t 1 < r e n d e r T e x t ( { . . . } )
o u t p u t $ m y h i s t < r e n d e r P l o t ( { . . . } )
o u t p u t $summary < r e n d e r T a b l e ( { . . . } )
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

48

3.2 Focus on special reactive functions


Until now, render*() functions such as renderText(), renderPlot(),
renderTable() have been used (in the server statement)

These functions can be placed under the set of reactive functions, i.e., functions
that react when the user selection changes through the input widgets

Another function in shiny having the reactive property is the reactive() function.
Functionality: Any expression given in the reactive function that depends on the
input variable would change (rather updates or re-evaluates) with any change in
the input variable
Usuability: When using reactive expressions, i.e., when the expression is
Belgium, 30 March 2016

49

dependent on input variable, and there is need for the expression to be reactive
Advantage: Reusability, i.e., to evaluate an expression once and its value could be
used within multiple render statements. That way the reactive expression need not
to be calculated multiple time in each render statement.

Overview of reactive functions:

Belgium, 30 March 2016

50

Belgium, 30 March 2016

51

App 6:
Use the reactive function (in the server statement of App 5) for the quantitative
variable selection, and add two download buttons in the tabset panels that enables
the user to download the histogram (Panel 1) and summary table (Panel 2),
respectively. Different extensions can be chosen in the sider panel by radio buttons.
Display:

Belgium, 30 March 2016

52

Step 1: Maintain coding structure of App 5


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= S i x t h app . . . ) ,
sidebarLayout (
sidebarPanel (
selectInput (...) ,
sliderInput (...) ,
radioButtons ( . . . ) ) ,
mainPanel ( . . . ) )
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $ t e x t 1 < r e n d e r T e x t ({
colm = as . numeric ( i n p u t $ var )
paste ( The . . . , names ( i r i s [ colm ] ) )
})
o u t p u t $ m y h i s t < r e n d e r P l o t ({
colm = as . numeric ( i n p u t $ var )
h i s t ( i r i s [ , colm ] , c o l =i n p u t $ c o l o u r ,
x l i m = c ( 0 , max( i r i s [ , colm ] ) ) ,
main = H i s t o g r a m . . . , b r e a k s =
seq ( 0 , max( i r i s [ , colm ] ) , l=i n p u t $ b i n +1) ,
x l a b = names ( i r i s [ colm ] ) )
})
o u t p u t $summary < r e n d e r T a b l e ({
summary ( i r i s )
})
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

53

Step 2: Change the defined colm expression by a reactive function


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= S i x t h app . . . ) ,
sidebarLayout (
sidebarPanel (
selectInput (...) ,
sliderInput (...) ,
radioButtons ( . . . ) ) ,
mainPanel ( . . . ) )
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
colm < r e a c t i v e ({
as . numeric ( i n p u t $ var )
})
o u t p u t $ t e x t 1 < r e n d e r T e x t ({
paste ( The . . . , names ( i r i s [ colm ( ) ] ) )
})
o u t p u t $ m y h i s t < r e n d e r P l o t ({
h i s t ( i r i s [ , colm ( ) ] , c o l =i n p u t $ c o l o u r ,
x l i m = c ( 0 , max( i r i s [ , colm ( ) ] ) ) ,
main = H i s t o g r a m . . . , b r e a k s =
seq ( 0 , max( i r i s [ , colm ( ) ] ) , l=i n p u t $ b i n +1) ,
x l a b = names ( i r i s [ colm ( ) ] ) )
})
o u t p u t $summary < r e n d e r T a b l e ({
summary ( i r i s )
})
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

54

Step 3: Add the file extensions to the sider panel


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= S i x t h app . . . ) ,
sidebarLayout (
sidebarPanel (
selectInput (...) ,
sliderInput (...) ,
radioButtons ( . . . ) ,
splitLayout (
r a d i o B u t t o n s ( i n p u t I d= p l o t e x t ,
l a b e l= 4 . Ext . p l o t : , c h o i c e s=c ( png ,
p d f ) , s e l e c t e d= png ) ,
r a d i o B u t t o n s ( i n p u t I d= t a b l e e x t ,
l a b e l= 5 . Ext . t a b l e : , c h o i c e s=c ( c s v ,
t x t ) , s e l e c t e d= c s v ) )
),
mainPanel ( . . . ) )
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
colm < r e a c t i v e ( { . . . } )
o u t p u t $ t e x t 1 < r e n d e r T e x t ( { . . . } )
o u t p u t $ m y h i s t < r e n d e r P l o t ( { . . . } )
o u t p u t $summary < r e n d e r T a b l e ( { . . . } )
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

55

Step 4: Link the plot file extension with R


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= S i x t h app . . . ) ,
sidebarLayout (
sidebarPanel (
selectInput (...) ,
sliderInput (...) ,
radioButtons ( . . . ) ,
splitLayout (...)) ,
mainPanel ( . . . ) ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
colm < r e a c t i v e ( { . . . } )
o u t p u t $ t e x t 1 < r e n d e r T e x t ( { . . . } )
o u t p u t $ m y h i s t < r e n d e r P l o t ( { . . . } )
o u t p u t $summary < r e n d e r T a b l e ( { . . . } )
o u t p u t $ d o w n p l o t < d o w n l o a d H a n d l e r (
f i l e n a m e=f u n c t i o n ( ) {
paste ( i r i s h i s t , i n p u t $ p l o t e x t , s e p= . ) } ,
c o n t e n t=f u n c t i o n ( f i l e ){
i f ( i n p u t $ p l o t e x t== png )
png ( f i l e )
else
pdf ( f i l e )
h i s t ( i r i s [ , colm ( ) ] , . . . )
dev . o f f ( ) }
)
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

56

Step 5: Link the table file extension with R


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= S i x t h app . . . ) ,
sidebarLayout (
sidebarPanel (
selectInput (...) ,
sliderInput (...) ,
radioButtons ( . . . ) ,
splitLayout (...)) ,
mainPanel ( . . . ) )
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
colm < r e a c t i v e ( { . . . } )
o u t p u t $ t e x t 1 < r e n d e r T e x t ( { . . . } )
o u t p u t $ m y h i s t < r e n d e r P l o t ( { . . . } )
o u t p u t $summary < r e n d e r T a b l e ( { . . . } )
o u t p u t $ d o w n p l o t < d o w n l o a d H a n d l e r ( . . . )
o u t p u t $downsum < d o w n l o a d H a n d l e r (
f i l e n a m e=f u n c t i o n ( ) {
paste ( i r i s sum , i n p u t $ t a b l e e x t , s e p= . ) } ,
c o n t e n t=f u n c t i o n ( f i l e ){
s e p < switch ( i n p u t $ t a b l e e x t , c s v = , ,
t x t = ; )
w r i t e . t a b l e ( summary ( i r i s ) , f i l e , s e p=s e p )}
)
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

57

Step 6: Create download buttons with outputs in the UI tabset panels


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= S i x t h app . . . ) ,
sidebarLayout (
sidebarPanel (
selectInput (...) ,
sliderInput (...) ,
radioButtons ( . . . ) ,
splitLayout (...)) ,
mainPanel (
t a b s e t P a n e l ( t y p e= t a b ,
t a b P a n e l ( P a n e l 1 ,
t e x t O u t p u t ( o u t p u t I d= t e x t 1 ) , b r ( ) ,
plotOutput ( outputId = myhist ) ,
d o w n l o a d B u t t o n ( o u t p u t I d= d o w n p l o t ,
l a b e l= Download t h e p l o t ) ) ,
t a b P a n e l ( P a n e l 2 ,
t a b l e O u t p u t ( o u t p u t I d= summary ) ,
d o w n l o a d B u t t o n ( o u t p u t I d=downsum ,
l a b e l= Download t h e summary ) ) ) ) ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
colm < r e a c t i v e ( { . . . } )
o u t p u t $ t e x t 1 < r e n d e r T e x t ( { . . . } )
o u t p u t $ m y h i s t < r e n d e r P l o t ( { . . . } )
o u t p u t $summary < r e n d e r T a b l e ( { . . . } )
o u t p u t $ d o w n p l o t < d o w n l o a d H a n d l e r ( . . . )
o u t p u t $downsum < d o w n l o a d H a n d l e r ( . . . )
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

58

App 7:
Use partial reactivity in App 5 to change the number BINs and color of the
histogram. An action button in the sider panel needs to be present to occur this
reactivity.
Display:

Belgium, 30 March 2016

59

Step 1: Maintain coding structure of App 5


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= S e v e n t h app . . . ) ,
sidebarLayout (
sidebarPanel (
selectInput (...) ,
sliderInput (...) ,
radioButtons ( . . . ) ) ,
mainPanel (
t a b s e t P a n e l ( t y p e= t a b ,
t a b P a n e l ( P a n e l 1 , . . . ) ,
t a b P a n e l ( P a n e l 2 , . . . ) )
)))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $ t e x t 1 < r e n d e r T e x t ( { . . . } )
o u t p u t $ m y h i s t < r e n d e r P l o t ( { . . . } )
o u t p u t $summary < r e n d e r T a b l e ( { . . . } )
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

60

Step 2: Add the action button to the sider panel


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= S e v e n t h app . . . ) ,
sidebarLayout (
sidebarPanel (
selectInput (...) ,
sliderInput (...) ,
radioButtons ( . . . ) ,
a c t i o n B u t t o n ( i n p u t I d= a c t i o n ,
l a b e l= Update . . . ) ) ,
mainPanel (
t a b s e t P a n e l ( t y p e= t a b ,
t a b P a n e l ( P a n e l 1 , . . . ) ,
t a b P a n e l ( P a n e l 2 , . . . ) )
)))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $ t e x t 1 < r e n d e r T e x t ( { . . . } )
o u t p u t $ m y h i s t < r e n d e r P l o t ( { . . . } )
o u t p u t $summary < r e n d e r T a b l e ( { . . . } )
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

61

Step 3: Link the action button with R to obtain the required partial reactivity
> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= S e v e n t h app . . . ) ,
sidebarLayout (
sidebarPanel (
selectInput (...) ,
sliderInput (...) ,
radioButtons ( . . . ) ,
a c t i o n B u t t o n ( i n p u t I d= a c t i o n ,
l a b e l= Update . . . ) ) ,
mainPanel (
t a b s e t P a n e l ( t y p e= t a b ,
t a b P a n e l ( P a n e l 1 , . . . ) ,
t a b P a n e l ( P a n e l 2 , . . . ) ) ) ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
colm < r e a c t i v e ( { . . . } )
o u t p u t $ t e x t 1 < r e n d e r T e x t ( { . . . } )
o u t p u t $ m y h i s t < r e n d e r P l o t ({
i n p u t $action
colm = as . numeric ( i n p u t $ var )
h i s t ( i r i s [ , colm ] , c o l= i s o l a t e ( i n p u t $ c o l o u r ) ,
x l i m=c ( 0 , max( i r i s [ , colm ] ) ) , main=
H i s t o g r a m . . . , b r e a k s=seq ( 0 ,
max( i r i s [ , colm ] ) , l= i s o l a t e ( i n p u t $ b i n +1) ,
x l a b = names ( i r i s [ colm ] ) ) ) } )
o u t p u t $summary < r e n d e r T a b l e ( { . . . } )
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

62

3.3 Progress dynamic user interface


User interface panels like the sider panel are often kept static in the app

Dynamic user interfaces can be obtained as well


Basic idea: Input statements depend on other input statements, and will change
when the user chooses a different option.
Implementation: The user interface components are generated as HTML on the
server inside a renderUI() block and sent to the client, which displays them with
uiOutput(). Each time a new component is sent to the client, it completely
replaces the previous component.

Belgium, 30 March 2016

63

Example:

Belgium, 30 March 2016

64

App 8:
Obtain dynamic user interface components in such a way that a scatter plot with
lineair regression (Main panel) can be made on different variables (Slider panel) of a
particular dataset. These variables depend on their corresponding dataset, and will be
present in the slider panel when the right dataset is chosen (Slider panel).
Display:

Belgium, 30 March 2016

65

Step 1: Global coding structure & add selection input of three datasets
> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= E i g h t h app . . . ) ,
sidebarLayout (
sidebarPanel (
s e l e c t I n p u t ( i n p u t I d= d a t a 1 ,
l a b e l= S e l e c t . . . , c h o i c e s=
c ( i r i s , mtcars , t r e e s ) ) ) ,
mainPanel (
)))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

66

Step 2: Create reactive function with variable names & use renderUI()
> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= E i g h t h app . . . ) ,
sidebarLayout (
sidebarPanel (
s e l e c t I n p u t ( i n p u t I d= d a t a 1 , . . . ) ) ,
mainPanel (
)))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
var < r e a c t i v e ({
switch ( i n p u t $ data1 ,
i r i s = names ( i r i s ) ,
m t c a r s = names ( m t c a r s ) ,
t r e e s = names ( t r e e s ) )
})
o u t p u t $ vx < r e n d e r U I ({
selectInput ( variablex , Select
. . . , c h o i c e s = var ( ) )
})
o u t p u t $ vy < r e n d e r U I ({
selectInput ( variabley , Select
. . . , c h o i c e s = var ( ) )
})
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

67

Step 3: Link renderUI() to UI with uiOutput()


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= E i g h t h app . . . ) ,
sidebarLayout (
sidebarPanel (
s e l e c t I n p u t ( i n p u t I d= d a t a 1 , . . . ) ,
u i O u t p u t ( vx ) ,
u i O u t p u t ( vy ) ) ,
mainPanel (
)))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
var < r e a c t i v e ({
switch ( i n p u t $ data1 ,
i r i s = names ( i r i s ) ,
m t c a r s = names ( m t c a r s ) ,
t r e e s = names ( t r e e s ) )
})
o u t p u t $ vx < r e n d e r U I ({
selectInput ( variablex , Select
. . . , c h o i c e s = var ( ) )
})
o u t p u t $ vy < r e n d e r U I ({
selectInput ( variabley , Select
. . . , c h o i c e s = var ( ) )
})
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

68

Step 4: Link the three selection inputs with plot in R


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= E i g h t h app . . . ) ,
sidebarLayout (
sidebarPanel (
s e l e c t I n p u t ( i n p u t I d= d a t a 1 , . . . ) ,
u i O u t p u t ( vx ) ,
u i O u t p u t ( vy ) ) ,
mainPanel (
)))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
var < r e a c t i v e ( { . . . } )
o u t p u t $ vx < r e n d e r U I ( { . . . } )
o u t p u t $ vy < r e n d e r U I ( { . . . } )
o u t p u t $ p l o t < r e n d e r P l o t ({
attach ( get ( i n p u t $ d a t a 1 ) )
lm . o u t = lm ( get ( i n p u t $ v a r i a b l e y )
get ( i n p u t $ v a r i a b l e x ) , data=get ( i n p u t $ d a t a 1 ) )
p l o t ( get ( i n p u t $ v a r i a b l e y )
get ( i n p u t $ v a r i a b l e x ) , data=get ( i n p u t $ d a t a 1 ) ,
x l a b=i n p u t $ v a r i a b l e x , y l a b=i n p u t $ v a r i a b l e y ,
main = L i n e a i r r e g r e s s i o n )
a b l i n e ( lm . out , c o l= r e d )
})
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

69

Step 5: Output plot in UI


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= E i g h t h app . . . ) ,
sidebarLayout (
sidebarPanel (
s e l e c t I n p u t ( i n p u t I d= d a t a 1 , . . . ) ,
u i O u t p u t ( vx ) ,
u i O u t p u t ( vy ) ) ,
mainPanel ( plotOutput ( p l o t )
)))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
var < r e a c t i v e ( { . . . } )
o u t p u t $ vx < r e n d e r U I ( { . . . } )
o u t p u t $ vy < r e n d e r U I ( { . . . } )
o u t p u t $ p l o t < r e n d e r P l o t ( { . . . } )
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

70

App 9:
Create an app where the user can upload their own data file in the slider panel and
outputs information (About; Data; Summary) of this file in the main panel. When no
data is selected by the user, a pdf format is displayed in the main panel. In addition,
an image/logo needs to be present in the slider panel, together with the ability to
select different settings that specifies the data structure.
Display:

Belgium, 30 March 2016

71

Step 1: Create basic layout structure


>
>
>
>
>

i n s t a l l . packages ( s h i n y )
library ( shiny )
library ( ggplot2 )
library ( lattice )
u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= N i n t h app . . . ) ,
sidebarLayout (
sidebarPanel () ,
mainPanel ( ) ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

72

Step 2: Build the input structure in the sidebar panel


> u i < f l u i d P a g e ( t i t l e P a n e l ( t i t l e= . . . ) ,
sidebarLayout (
sidebarPanel (
f i l e I n p u t ( i n p u t I d= f i l e , l a b e l=
Upload y o u r d a t a ) ,
c h e c k b o x I n p u t ( i n p u t I d= h e a d e r ,
l a b e l= Header , v a l u e=FALSE ) ,
c h e c k b o x I n p u t ( i n p u t I d=
s t r i n g A s F a c t o r s , l a b e l=
s t r i n g A s F a c t o r s , v a l u e=FALSE ) ,
r a d i o B u t t o n s ( i n p u t I d= s e p , l a b e l=
S e p a r a t o r , c h o i c e s=c (Comma= , ,
S e m i c o l o n= ; , Tab= \ t , Space= ) ,
selected = , ) ,
h5 ( Made by : ) ,
d i v ( t a g s $img ( s t y l e= h e i g h t : 6 0 px ;
w i d t h : 1 8 0 px , s r c= h t t p : //www.
u h a s s e l t . be/ i m a g e s / l o g o s /
i n s t i t u t e n / I B i o s t a t l o g o . png ) ,
s t y l e= t e x t a l i g n : c e n t e r ; ) ) ,
mainPanel ( ) ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

73

Step 3: Link the user inputs with R


> u i < f l u i d P a g e ( t i t l e P a n e l ( t i t l e= . . . ) ,
sidebarLayout (
sidebarPanel (
f i l e I n p u t ( . . . ) , checkboxInput ( . . . ) ,
checkboxInput ( . . . ) , radioButtons ( . . . ) ,
h5 ( . . . ) , d i v ( t a g s $img ( . . . ) ) ,
mainPanel ( ) ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
data < r e a c t i v e ({
f i l e 1 < i n p u t $ f i l e
i f ( i s . n u l l ( f i l e 1 )){ return ()}
read . t a b l e ( f i l e = f i l e 1 $ d a t a p a t h , s e p=i n p u t $ sep ,
h e a d e r=i n p u t $ h e a d e r , s t r i n g s A s F a c t o r s=
input$ stringAsFactors )})
o u t p u t $ f i l e d f < r e n d e r T a b l e ({
i f ( i s . n u l l ( data ( ) ) ) { r e t u r n ( ) }
i n p u t $ f i l e })
o u t p u t $sum < r e n d e r T a b l e ({
i f ( i s . n u l l ( data ( ) ) ) { r e t u r n ( ) }
summary ( data ( ) ) } )
o u t p u t $ t a b l e < r e n d e r T a b l e ({
i f ( i s . n u l l ( data ( ) ) ) { r e t u r n ( ) }
data ( ) } )
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

74

Step 4: Use renderUI()


> u i < f l u i d P a g e ( t i t l e P a n e l ( t i t l e= . . . ) ,
sidebarLayout (
sidebarPanel (
fileInput (...) ,
checkboxInput ( . . . ) , checkboxInput ( . . . ) ,
radioButtons ( . . . ) ,
h5 ( . . . ) , d i v ( t a g s $img ( . . . ) ) ,
mainPanel ( ) ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
data < r e a c t i v e ( { . . . } )
o u t p u t $ f i l e d f < r e n d e r T a b l e ( { . . . } )
o u t p u t $sum < r e n d e r T a b l e ( { . . . } )
o u t p u t $ t a b l e < r e n d e r T a b l e ( { . . . } )
o u t p u t $ t b < r e n d e r U I ({
i f ( i s . n u l l ( data ( ) ) ) {
t a g s $ i f r a m e ( s t y l e= h e i g h t : 5 6 0 px ; w i d t h :100% ,
s r c= h t t p s : //perswww . k u l e u v e n . be/ u0018341
/ documents / biomedwet f a r m a c i e . p d f )}
else
t a b s e t P a n e l ( t a b P a n e l ( About f i l e ,
t a b l e O u t p u t ( f i l e d f ) ) , t a b P a n e l ( Data ,
t a b l e O u t p u t ( t a b l e ) ) , t a b P a n e l ( Summary ,
t a b l e O u t p u t ( sum ) ) )
})
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

75

Step 5: Link renderUI() to UI with uiOutput()


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= N i n t h app . . . ) ,
sidebarLayout (
sidebarPanel (
fileInput (...) ,
checkboxInput ( . . . ) ,
checkboxInput ( . . . ) ,
radioButtons ( . . . ) ,
h5 ( . . . ) ,
d i v ( t a g s $img ( . . . ) ) ,
mainPanel (
uiOutput ( tb )
)))
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
data < r e a c t i v e ( { . . . } )
o u t p u t $ f i l e d f < r e n d e r T a b l e ( { . . . } )
o u t p u t $sum < r e n d e r T a b l e ( { . . . } )
o u t p u t $ t a b l e < r e n d e r T a b l e ( { . . . } )
o u t p u t $ t b < r e n d e r U I ( { . . . } )
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

76

App 10:
Extend App 9 by adding a visitor hit counter in the slider panel.
Display:

Belgium, 30 March 2016

77

Step 1: Maintain coding structure of App 9


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= Tenth app . . . ) ,
sidebarLayout (
sidebarPanel (
fileInput (...) ,
checkboxInput ( . . . ) ,
checkboxInput ( . . . ) ,
radioButtons ( . . . ) ,
h5 ( . . . ) ,
d i v ( t a g s $img ( . . . ) ) ,
mainPanel ( . . . ) ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
data < r e a c t i v e ( { . . . } )
o u t p u t $ f i l e d f < r e n d e r T a b l e ( { . . . } )
o u t p u t $sum < r e n d e r T a b l e ( { . . . } )
o u t p u t $ t a b l e < r e n d e r T a b l e ( { . . . } )
o u t p u t $ t b < r e n d e r U I ( { . . . } )
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

78

Step 2: Create function in R that counts visitors & link them to UI


> u i < f l u i d P a g e (
t i t l e P a n e l ( t i t l e= Tenth app . . . ) ,
sidebarLayout (
sidebarPanel (
f i l e I n p u t ( . . . ) , checkboxInput ( . . . ) ,
checkboxInput ( . . . ) , radioButtons ( . . . ) ,
h5 ( t e x t O u t p u t ( c o u n t e r ) ) ,
h5 ( . . . ) ,
d i v ( t a g s $img ( . . . ) ) ,
mainPanel ( . . . ) ) )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
data < r e a c t i v e ( { . . . } )
o u t p u t $ f i l e d f < r e n d e r T a b l e ( { . . . } )
o u t p u t $sum < r e n d e r T a b l e ( { . . . } )
o u t p u t $ t a b l e < r e n d e r T a b l e ( { . . . } )
o u t p u t $ t b < r e n d e r U I ( { . . . } )
o u t p u t $ c o u n t e r < r e n d e r T e x t ({
i f ( ! f i l e . e x i s t s ( c o u n t e r . Rdata ) )
c o u n t e r < 0
else
load ( f i l e = c o u n t e r . Rdata )
c o u n t e r < c o u n t e r + 1
save ( c o u n t e r , f i l e = c o u n t e r . Rdata )
paste ( H i t s : , c o u n t e r )
})
}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

79

3.4 Extension to dashboard shells


Build-in UI framework of Shiny is simple of nature

More fancy layouts/dashboards are often preferred by the user, which can be done
with HTML, CSS and Javascript widgets
Advantage: Own layout structures can be developed
Disadvantage: Time consuming to programme
Belgium, 30 March 2016

80

Alternative way: Make use of the shinydashboard package, which makes it easy
to use Shiny and create dashboards like these:

Belgium, 30 March 2016

81

A Shiny dashboard has three parts, i.e., a header, a sidebar, and a body, and is
build up with the following template in R:
app.R:
> library ( shiny )
> library ( shinydashboard )
> u i < d a s h b o a r d P a g e (
dashboardHeader () ,
dashboardSidebar () ,
da shbo ardB ody ( )
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = ui , s e r v e r = s e r v e r )

Next to standard shiny statements/functions/etc. (Chapter 2), extra features can


be added in the dashboard framework:

Belgium, 30 March 2016

82

1. Header:

app.R:
> library ( shiny )
> library ( shinydashboard )
> u i < d a s h b o a r d P a g e (
d a s h b o a r d H e a d e r ( t i t l e = Header s t r u c t u r e s ,
X1 ,
X2 ,
X3
),
dashboardSidebar () ,
da shbo ardB ody ( )
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = ui , s e r v e r = s e r v e r )

Belgium, 30 March 2016

83

Message menus (X1)


dropdownMenu ( t y p e = m e s s a g e s ,
messageItem (
from = S a l e s Dept ,
message = S a l e s a r e s t e a d y t h i s month .
),
messageItem (
from = New U s e r ,
message = How do I r e g i s t e r ? ,
icon = icon ( question ) ,
time = 1 3 : 4 5
),
messageItem (
from = S u p p o r t ,
message = The new s e r v e r i s r e a d y . ,
i c o n = i c o n ( l i f e r i n g ) ,
time = 20141201
)
)

Belgium, 30 March 2016

84

Notification menus (X2)


dropdownMenu ( t y p e = n o t i f i c a t i o n s ,
notificationItem (
t e x t = 5 new u s e r s t o d a y ,
icon ( users )
),
notificationItem (
t e x t = 12 i t e m s d e l i v e r e d ,
icon ( truck ) ,
status = s u c c e s s
),
notificationItem (
t e x t = S e r v e r l o a d a t 86% ,
i c o n = i c o n ( e x c l a m a t i o n t r i a n g l e ) ,
status = warning
)
)

Belgium, 30 March 2016

85

Task menus (X3)


dropdownMenu ( t y p e = t a s k s ,
badgeStatus = success ,
t a s k I t e m ( v a l u e = 90 , c o l o r = green ,
Documentation
),
t a s k I t e m ( v a l u e = 1 7 , c o l o r = aqua ,
P r o j e c t X
),
t a s k I t e m ( v a l u e = 75 , c o l o r = y e l l o w ,
S e r v e r deployment
),
t a s k I t e m ( v a l u e = 80 , c o l o r = red ,
Overall project
)
)

Belgium, 30 March 2016

86

2. Sidebar:

app.R:
> u i < d a s h b o a r d P a g e (
dashboardHeader ( t i t l e = S i d e r b a r . . . ) ,
dashboardSidebar (
X1 ,
X2 ,
X3
),
da shbo ard B ody ( )
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = ui , s e r v e r = s e r v e r )

Belgium, 30 March 2016

87

Sidebar search form (X1)


sidebarSearchForm ( t e x t I d = searchText ,
buttonId = searchButton ,
l a b e l = Search . . . )

Menu items and tabs (X2)


sidebarMenu (
menuItem ( Dashboard , tabName = d a s h b o a r d ,
icon = icon ( dashboard )) ,
menuItem ( W i d g e ts , i c o n = i c o n ( t h ) ,
tabName = w i d g e t s , b a d g e L a b e l = new ,
badgeColor = green ) ,
menuItem ( C h a r t s , i c o n=i c o n ( barc h a r t o ) ,
menuSubItem ( Subi t e m 1 ,
tabName = s u b i t e m 1 ) ,
menuSubItem ( Subi t e m 2 ,
tabName = s u b i t e m 2 )
)
)

Belgium, 30 March 2016

88

Traditional inputs (X3)

t e x t I n p u t ( i n p u t I d= s l i d e r , l a b e l= S l i d e r ) ,
r a d i o B u t t o n s ( i n p u t I d= c o l o r , Button : ,
l i s t ( B l u e , Green ) , Green ) ,
d a t e R a n g e I n p u t ( dateRange2 , l a b e l = Date ,
s t a r t=Sys . Date () 3 , end=Sys . Date ()+3 ,
min=Sys . Date () 10 , max=Sys . Date ()+10 ,
s e p a r a t o r= , format= dd/mm/ yy ,
s t a r t v i e w= y e a r , l a n g u a g e= f r ,
w e e k s t a r t = 1)

Belgium, 30 March 2016

89

3. Body:

app.R:
> u i < d a s h b o a r d P a g e (
d a s h b o a r d H e a d e r ( t i t l e= S i d e r b a r
. . . ) ,
dashboardSidebar () ,
da shbo ard B ody (
X1
)
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ) { . . . }
> shinyApp ( u i = ui , s e r v e r = s e r v e r )

Belgium, 30 March 2016

90

Boxes (X1)
Example 1:
fluidRow (
box (
p l o t O u t p u t ( o u t p u t I d = box ) ) ,
box (
s l i d e r I n p u t ( i n p u t I d= s e p a l l e n g t h ,
S e p a l . L e n g t h : , min =4.3 , max=7.9 ,
v a l u e =5.8 , step = 0 . 1 ) ,
s l i d e r I n p u t ( i n p u t I d= s e p a l w i d t h ,
S e p a l . Width : , min=2, max=4.4 ,
v a l u e =3, step = 0 . 1 ) ,
s l i d e r I n p u t ( i n p u t I d= p e t a l l e n g t h ,
P e t a l . L e n g t h : , min=1, max=6.9 ,
value = c (1.6 , 5.1)) ,
s l i d e r I n p u t ( i n p u t I d= p e t a l w i d t h ,
P e t a l . Width : , min =0.1 , max = 2 . 5 ,
v a l u e = 1 . 3 , step = 0 . 3 , a n i m a t e=
a n i m a t i o n O p t i o n s ( i n t e r v a l =2600 ,
l o o p=TRUE) )
)
)

Belgium, 30 March 2016

91

Example 2:
fluidRow (
box (
t i t l e = Boxplot , status = primary ,
p l o t O u t p u t ( o u t p u t I d = box ) ) ,
box (
t i t l e = I n p u t s , status = warning ,
sliderInput (...) , sliderInput (...) ,
sliderInput (...) , sliderInput (...)
))

Example 3:
fluidRow (
box (
t i t l e = Boxplot , status = primary ,
s o l i d H e a d e r=TRUE, c o l l a p s i b l e =TRUE,
p l o t O u t p u t ( o u t p u t I d = box ) ) ,
box (
t i t l e = I n p u t s , status = warning ,
s o l i d H e a d e r = TRUE,
sliderInput (...) , sliderInput (...) ,
sliderInput (...) , sliderInput (...)
))

Belgium, 30 March 2016

92

Example 4:
fluidRow (
box (
t i t l e = B o x p l o t , s o l i d H e a d e r=TRUE,
c o l l a p s i b l e =TRUE, p l o t O u t p u t ( . . . ) ) ,
box (
t i t l e = I n p u t s , s o l i d H e a d e r = TRUE,
sliderInput (...) , sliderInput (...) ,
sliderInput (...) , sliderInput (...)
)
)

Example 5:
fluidRow (
box (
t i t l e = B o x p l o t , b a c k g r o u n d= g r e e n ,
s o l i d H e a d e r=TRUE, p l o t O u t p u t ( . . . ) ) ,
box (
t i t l e = I n p u t s , b a c k g r o u n d= y e l l o w ,
sliderInput (...) , sliderInput (...) ,
sliderInput (...) , sliderInput (...)
)
)

Belgium, 30 March 2016

93

Tabbox (X1)
Example 1:
tabBox (
t i t l e = F i r s t tabBox ,
i d = t a b s e t 1 , h e i g h t = 250 px ,
t a b P a n e l ( Tab1 , Welcome . . . ) ,
t a b P a n e l ( Tab2 , Tab c o n t e n t 2 )
)

Example 2:
tabBox (
s i d e = r i g h t , h e i g h t = 250 px ,
s e l e c t e d = Tab3 ,
t a b P a n e l ( Tab1 , Tab c o n t e n t 1 ) ,
t a b P a n e l ( Tab2 , Tab c o n t e n t 2 ) ,
t a b P a n e l ( Tab3 , Note t h a t . . . )
)

Belgium, 30 March 2016

94

Example 3:
tabBox (
t i t l e = t a g L i s t ( shiny : : icon ( gear ) ,
tabBox s t a t u s ) ,
t a b P a n e l ( Tab1 ,
Currently . . . : ,
verbatimTextOutput ( t a b s e t 1 S e l e c t e d )
),
t a b P a n e l ( Tab2 , Tab c o n t e n t 2 )
)

Infobox

Belgium, 30 March 2016

95

Step 1: Input two different infoboxes in the dashboard body


> library ( shinydashboard )
> u i < d a s h b o a r d P a g e (
d a s h b o a r d H e a d e r ( t i t l e= . . . ) ,
dashboardSidebar () ,
da shbo ardBo dy (
fluidRow (
i n f o B o x ( New O r d e r s , 10 2 ,
i c o n=i c o n ( c r e d i t c a r d ) ) ) ,
fluidRow (
i n f o B o x ( New O r d e r s , 10 2 ,
i c o n=i c o n ( c r e d i t c a r d ) , f i l l
=TRUE) )
)
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){}
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

96

Step 2: Use renderInfobox() in R


> u i < d a s h b o a r d P a g e ( . . . )
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $ p r o g r B o x<r e n d e r I n f o B o x ({
infoBox (
P r o g r e s s , p a s t e 0 (25+ i n p u t $count ,
% ) , i c o n=i c o n ( l i s t ) , c o l o r=
purple )})
o u t p u t $ apprBox<r e n d e r I n f o B o x ({
infoBox (
A p p r o v a l , 80% , i c o n=
i c o n ( thumbsup , l i b = g l y p h i c o n ) ,
c o l o r= y e l l o w ) } )
o u t p u t $ p r o g r B o x 2<r e n d e r I n f o B o x ({
infoBox (
P r o g r e s s , p a s t e 0 (25+ i n p u t $count ,
% ) , i c o n=i c o n ( l i s t ) , c o l o r=
p u r p l e , f i l l =TRUE) } )
o u t p u t $ apprBox2<r e n d e r I n f o B o x ({
infoBox (
A p p r o v a l , 80% , i c o n=
i c o n ( thumbsup , l i b = g l y p h i c o n ) ,
c o l o r= y e l l o w , f i l l =TRUE) } ) }
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

97

Step 3: Link renderInfobox() to UI with infoBoxOutput()


> u i < d a s h b o a r d P a g e (
d a s h b o a r d H e a d e r ( t i t l e= . . . ) ,
dashboardSidebar () ,
da shbo ardBo dy (
fluidRow ( . . . ,
infoBoxOutput ( progrBox ) ,
i n f o B o x O u t p u t ( apprBox )
),
fluidRow ( . . . ,
infoBoxOutput ( progrBox2 ) ,
i n f o B o x O u t p u t ( apprBox2 )
),
fluidRow (
box ( w i d t h = 4 ,
actionButton ( count ,
Increment progress )))
)
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $ p r o g r B o x<r e n d e r I n f o B o x ( { . . . } )
o u t p u t $ apprBox<r e n d e r I n f o B o x ( { . . . } )
o u t p u t $ p r o g r B o x 2<r e n d e r I n f o B o x ( { . . . } )
o u t p u t $ apprBox2<r e n d e r I n f o B o x ( { . . . } ) }
> shinyApp ( u i = u i , s e r v e r = s e r v e r )

Belgium, 30 March 2016

98

Valuebox
Similar to the Infobox (i.e., infoBox(. . . ) valueBox(. . . ), etc.)

Belgium, 30 March 2016

99

4. Layout:
Row-based

app.R:
> u i < d a s h b o a r d P a g e (
d a s h b o a r d H e a d e r ( t i t l e= . . . ) ,
dashboardSidebar () ,
da shbo ardBo dy (
fluidRow ( . . . ) ,
fluidRow ( . . . )
)
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ) { . . . }
> shinyApp ( u i = ui , s e r v e r = s e r v e r )

Belgium, 30 March 2016

100

Column-based
app.R:
> u i < d a s h b o a r d P a g e (
d a s h b o a r d H e a d e r ( t i t l e= . . . ) ,
dashboardSidebar () ,
da shbo ardBo dy (
fluidRow (
column ( w i d t h = 4 ,
box ( . . . ) ,
box ( . . . ) ,
box ( . . . ) ) ,
column ( w i d t h = 4 ,
box ( . . . ) ,
box ( . . . ) ,
box ( . . . ) )
)
)
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ) { . . . }
> shinyApp ( u i = ui , s e r v e r = s e r v e r )

Belgium, 30 March 2016

101

Mixed row and column layout


app.R:
> u i < d a s h b o a r d P a g e (
d a s h b o a r d H e a d e r ( t i t l e= . . . ) ,
dashboardSidebar () ,
da shbo ardBo dy (
fluidRow ( . . . ) ,
fluidRow (
column ( w i d t h = 4 ,
box ( . . . ) ,
box ( . . . ) ,
box ( . . . ) ) ,
column ( w i d t h = 4 ,
box ( . . . ) ,
box ( . . . ) ,
box ( . . . ) )
)
)
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ) { . . . }
> shinyApp ( u i = ui , s e r v e r = s e r v e r )

Belgium, 30 March 2016

102

5. Color themes:
app.R:
> u i < d a s h b o a r d P a g e ( s k i n=X1 ,
d a s h b o a r d H e a d e r ( t i t l e= . . . ) ,
dashboardSidebar ( . . . ) ,
da shbo ard Bo dy ( . . . )
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ) { . . . }
> shinyApp ( u i = ui , s e r v e r = s e r v e r )

Blue (X1)

Belgium, 30 March 2016

Black (X1)

103

Purple (X1)

Green (X1)

Red (X1)

Yellow (X1)

Belgium, 30 March 2016

104

6. Extras:
Logout panel
Usage: Deploying with Shiny Server Pro (SSP)

CSS
Usage: Customizing font

Long-titles
Code: titleWidth = 450

Belgium, 30 March 2016

105

Sidebar-width
Code: width = 450

Icons
. Font-Awesome
URL: http : //f ontawesome.io/icons/
Code: icon(calendar) (by default)
. Glyphicons
URL: http : //getbootstrap.com/components/#glyphicons
Code: icon(cog, lib = glyphicon)

Belgium, 30 March 2016

106

Statuses and colors


. Statuses
Code: status = primary

. Color
Code: color=red

Belgium, 30 March 2016

107

Part 4:
Applications in the area of biostatistics & data science

Belgium, 30 March 2016

108

Chapter 4:
Apps in biostatistics & data science
Shiny as an extra tool ...

Other way of constructing Shiny apps

To the applications ...

Belgium, 30 March 2016

109

4.1 Shiny as an extra tool ...


1. Teaching purposes
(e.g., Linear Mixed Models app)

2. Visualizing complex models


(e.g. Sitar Model app)

3. As a nice layout
(e.g., Face Recognition app)

Belgium, 30 March 2016

110

4.2 Other way of constructing Shiny apps


> d a t a s e t < read . d e l i m ( )
> F u n c t i o n 1 < f u n c t i o n ( par1 , p a r 2 ){
return ( l i s t ( obj1 , obj2 ) )
}
> F u n c t i o n 2 < f u n c t i o n ( p a r 3 ){
Return ( l i s t ( obj3 , obj4 ) )
}
> u i < (
p l o t O u t p u t ( oObj1 ) . . . t a b l e O u t p u t ( oObj2 ) . . .
numericInput ( iPar1 , . . . )
)
> s e r v e r < f u n c t i o n ( i n p u t , o u t p u t ){
o u t p u t $oObj1 < r e n d e r P l o t ( F u n c t i o n 1 ( i n p u t $ i P a r 1 , i n p u t $ i P a r 2 ) [ [ 1 ] ] )
o u t p u t $oObj2 < r e n d e r T a b l e ( F u n c t i o n 1 ( i n p u t $ i P a r 1 , i n p u t $ i P a r 2 ) [ [ 2 ] ] )
o u t p u t $oObj3 < r e n d e r T e x t ( F u n c t i o n 2 ( i n p u t $ i P a r 3 ) [ [ 1 ] ] )
o u t p u t $oObj4 < r e n d e r I m a g e ( F u n c t i o n 2 ( i n p u t $ i P a r 3 ) [ [ 2 ] ] )
}

Belgium, 30 March 2016

111

4.3 To the applications ...

Belgium, 30 March 2016

112

References
Beeley, C. (2013). Web Application Development with R Using Shiny. Packt Publishing,
110 pages
Chang, W. (2013). R Graphics Cookbook (1st ed.). OReilly Media, 416 pages
Teetor, P. (2011). Wickham, H. (2010). R Cookbook (OReilly Cookbooks) (1st ed.).
OReilly Media, 438 pages
Wickham, H. (2010). ggplot2: Elegant Graphics for Data Analysis (Use R!) (3rd ed.).
Springer, 213 pages

Belgium, 30 March 2016

113

Vous aimerez peut-être aussi