-
Notifications
You must be signed in to change notification settings - Fork 25
/
index.Rmd
162 lines (107 loc) · 8.21 KB
/
index.Rmd
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
---
title: rCharts
subtitle: Shiny Applications
author: Ramnath Vaidyanathan
github:
user: ramnathv
repo: rChartsShiny
branch: "gh-pages"
framework: minimal
mode: selfcontained
widgets: polycharts
hitheme: solarized_dark
---
## Interactive Visualizations with rCharts and Shiny
```{r setup, echo = F}
require(knitr)
read_chunk('rChartOECD/ui.R'); read_chunk('rChartOECD/server.R')
```
<style>
p {
text-align: justify;
}
body {
background-image: url(libraries/frameworks/minimal/images/light_wool.png)
}
</style>
In this blog post, I will take you through the details of creating an interactive visualization using [rCharts](http://ramnathv.github.io/rCharts) and [Shiny](http://rstudio.github.io/shiny). I will be attempting to replicate [this visualization](http://www.oecd.org/gender/data/proportionofemployedwhoareseniormanagersbysex.htm) of senior manager percentages by gender across countries, put together by OECD using [Tableau](http://www.tableausoftware.com). Here is the [final shiny app](http://glimmer.rstudio.com/ramnathv/rChartOECD/) that we will be building.
## Data
The data was collected by the International Labor Organization. I used a version of the dataset put together by the excellent data visualization blog: [thewhyaxis](http://thewhyaxis.info/gap-remake/). I cleaned up the dataset, partially in excel and then in R to get the following (more details on the clean up excercise in R can be found in the github repo)
```{r echo = F, message = F, comment = NA, warning = F}
get_gdoc <- function(url){
require(RCurl)
s = getURLContent(url)
read.csv(textConnection(s))
}
durl <- "https://docs.google.com/spreadsheet/pub?key=0AovoNzJt5GetdGxyaVlpM3ZtTVBiNjlDS0hvanVORnc&single=true&gid=0&output=csv"
dat <- get_gdoc(durl)
dat2 <- reshape(dat, varying = names(dat)[2:35], direction = 'long', timevar = "year")
dat2m <- reshape2::melt(dat2, id = c(1:3, 6))
dat2m <- na.omit(transform(dat2m, value = as.numeric(as.character(value))))
names(dat2m) <- c('country', 'countrycode', 'year', 'id', 'gender', 'value')
head(dat2m)
```
We now proceed to creating an interactive visualization. If you want to follow along, you would need to install `rCharts`, an R package that provides a [lattice](http://cran.r-project.org/web/packages/lattice/index.html) package style plotting interface to create interactive visualizations using the javascript library [polychart.js](https://github.com/Polychart/polychart2).
```{r eval = F}
require(devtools)
install_github('rCharts', 'ramnathv')
```
## First Steps
Our first objective is to recreate the charts here without any menu controls. Once we are able to achieve that, we can add the menu controls easily using Shiny and convert it into an interactive app. This blog post will attemp to show you both how to use rCharts to create such visualizations, as well as how to convert them into an interactive app using Shiny.
```{r echo = F}
opts_chunk$set(tidy = F)
```
### Bar Plot
We will now recreate the bar plot shown in the Tableau visualization.
<div id='chart1'></div>
```{r chart1, results = 'asis', comment = NA, message = F, warning = F}
require(rCharts)
YEAR = 2011
# Step 1. create subsets of data by gender
men <- subset(dat2m, gender == "Men" & year == YEAR)
women <- subset(dat2m, gender == "Women" & year == YEAR)
# Step 2. initialize bar plot for value by countrycode for women
p1 <- rPlot(x = list(var = "countrycode", sort = "value"), y = "value",
color = 'gender', data = women, type = 'bar')
# Step 3. add a second layer for men, displayed as points
p1$layer(x = "countrycode", y = "value", color = 'gender',
data = men, type = 'point', size = list(const = 3))
# Step 4. format the x and y axis labels
p1$guides(x = list(title = "", ticks = unique(men$countrycode)))
p1$guides(y = list(title = "", max = 18))
# Step 5. set the width and height of the plot and attach it to the dom
p1$addParams(width = 600, height = 300, dom = 'chart1',
title = "Percentage of Employed who are Senior Managers")
# Step 6. print the chart (just type p1 if you are using it in your R console)
p1$print()
```
The first step is to create subsets of the data by gender for a specific year. We then proceed to initialize a bar plot for `women`. The function `rPlot` uses an interface very similar to the `lattice` package. The first argument specifies that the x variable is going to be `countrycode` and we want it sorted by `value`. The remaining arguments specify different aesthetics of the bar plot.
The next step adds a second layer to this plot using the data for `men`, specifying that the values be displayed as `points`. The code in **Step 3** might seem a little strange to some of you, since there is no explicit assignment involved. The reason for this is that `rCharts` uses [Reference Classes](), which allow object oriented programming in R, leading to more concise code. In essence, `layer2` is a method of the object `p1` that adds a layer to the plot object.
The last few steps tweak the axis labels, width and height of the plot, before attaching it to a specific DOM element. At this point, you can run Steps 1 through 5 and type `p1` in your R console, and if everything goes right, you will be staring at the same plot created here.
### Line Chart
We can now add a line chart for comparing the values for a specific country across years. We follow the same approach outlined above, except that we only need a single layer in this case.
<div id='chart2'></div>
```{r chart2, results = 'asis', comment = NA, warning = F}
COUNTRY = "Canada"
country = subset(dat2m, country == COUNTRY)
p2 <- rPlot(value ~ year, color = 'gender', type = 'line', data = country)
p2$addParams(width = 600, height = 300, dom = 'chart2')
p2$guides(y = list(min = 0, title = ""))
p2$print()
```
### Shiny App
Now that we have created the charts for a given `COUNTRY` and `YEAR`, we can go ahead and wrap the code in a Shiny app to allow users to interactively choose the inputs. To create a Shiny app, we need two files: `ui.R` that specifies the user interface and `server.R` that specifies how to generate outputs.
#### User Interface (ui.R)
Let us design the user interface first. Note that we need four components, two select boxes to allow the user to select the year and country, and two `div` tags to place the dynamically generated chart output.
```{r ref.label = 'ui.R', eval = F}
```
Although the above code is self explanatory, I want to draw your attention to a couple of things. First, we choose a layout where the controls are placed in a sidebar and the charts in the main panel. Second, we generate the choices for the two selection boxes using the unique values for `year` and `country` in the dataset. Third, `showOutput` is a function in `rCharts` that creates placeholders for the generated charts, with a given id.
#### Chart Output (server.R)
Now that we nailed the UI, we need to tweak the plotting code to interface with the UI. To achieve this, we need to do three things. First, we need to replace COUNTRY and YEAR by `input$country` and `input$year` so that their values are dynamically obtained from user input. Second, we need to wrap the plotting calls inside `renderChart`, which is a function in `rCharts` that adds allows the plots to react to user inputs. Third, we need to assign the output of these calls to their respective elements in the UI (chart1 and chart2).
```{r ref.label = 'server.R', eval = F}
```
Finally, we place the code required to read and process the data in `global.R` so that the data is accessible to both `ui.R` and `server.R`. You can see the resulting [Shiny app here](http://glimmer.rstudio.com/ramnathv/rChartOECD) and the [source code](https://github.com/ramnathv/rChartsShiny/tree/gh-pages/rChartOECD)
### Notes
This blog post is a github repo and is reproducible using the [slidify](http://slidify.org) package. You can download/clone this repo and run `slidify("index.Rmd")` to reproduce the entire post along with the embedded charts. If you have any questions or comments, please use the [issues page](https://github.com/ramnathv/rChartsShiny/issues/new), tagging it appropriately.
### License
`rCharts` is licensed under the MIT License. However, the Polycharts JavaScript library used to create these charts is not free for commercial use. You can read more about its license at http://polychart.com/js/license.