-
-
Notifications
You must be signed in to change notification settings - Fork 2
/
upsetjs.Rmd
235 lines (154 loc) · 8.9 KB
/
upsetjs.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
---
title: "Introduction to UpSet.js"
author: "Samuel Gratzl"
date: "`r Sys.Date()`"
output: rmarkdown::html_vignette
vignette: >
%\VignetteIndexEntry{Introduction to UpSet.js}
%\VignetteEngine{knitr::rmarkdown}
\usepackage[utf8]{inputenc}
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
# UpSet.js R Widget
[UpSet.js](https://upset.js.org) is a JavaScript re-implementation of [UpSetR](https://www.rdocumentation.org/packages/UpSetR/) which itself is based on [UpSet](https://upset.app/).
The core library is written in React but provides also bundle editions for plain JavaScript use and this R wrapper using [HTMLWidget](https://www.htmlwidgets.org/).
In this tutorial the basic widget functionality is explained.
Let's begin with importing the library
```{r libraries}
# devtools::install_url("https://github.com/upsetjs/upsetjs_r/releases/latest/download/upsetjs.tar.gz")
library(upsetjs)
```
## Basic User Interface
**Note**: The input data will be described in more detail in the next section
example of list input (list of named vectors, each having a list of contained elements)
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
listInput <- list(one = c('a', 'b', 'c', 'e', 'g', 'h', 'k', 'l', 'm'), two = c('a', 'b', 'd', 'e', 'j'), three = c('a', 'e', 'f', 'g', 'h', 'i', 'j', 'l', 'm'))
w <- upsetjs() %>% fromList(listInput) %>% interactiveChart()
w
```
An UpSet plot consists of three areas:
- The bottom left area shows the list of sets as a vertical bar chart. The length of the bar corresponds to the cardinality of the set, i.e., the number of elements in this set.
- The top right area shows the list of set intersections as a horizontal bar chart. Again the length corresponds to the cardinality of the set
- The bottom right area shows which intersection consists of which sets. A dark dot indicates that the set is part of this set intersection. The line connecting the dots is just to visually group the dots.
Moving the mouse over a bar or a dot will automatically highlight the corresponding set or set intersection in orange. In addition, the number elements which are shared with the highlighted sets are also highlighted. This gives a quick overview how sets and set intersections are related to each other. More details, in the Interaction section.
## Input Formats
In the current version the UpSet.js wrapper supports three input data formats: list, expression, and through a data.frame.
### List Input
The first format is a list. The key of the list entry is the set name while the value is the vector of elements this set has. See also UpsetR
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
upsetjs() %>% fromList(list(one = c('a', 'b', 'c', 'e', 'g', 'h', 'k', 'l', 'm'), two = c('a', 'b', 'd', 'e', 'j'), three = c('a', 'e', 'f', 'g', 'h', 'i', 'j', 'l', 'm')))
```
### Expression Input
The second version is a a variant in which not the elements are given but their cardinality. Thus, besides the sets also all the set intersections have to be defined. Moreover, this version has only limited interactivty support.
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
# example of expression input
expressionInput <- list(one = 9, two = 5, three = 9, `one&two` = 3, `one&three` = 6, `two&three` = 3, `one&two&three` = 2)
upsetjs() %>% fromExpression(expressionInput) %>% interactiveChart()
```
### Data Frame Input
The last format is a a binary/boolean data frame. The rownames contain the list of elements. Each regular column represents a set with boolean values (e.g., 0 and 1) whether the row represented by the rowname is part of the set or not.
The following data frame defines the same set structure as the dictionary format before.
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
# boolean table with rows = elements, columns = sets, cell = is row part of this set
dataFrame <- as.data.frame(list(
one=c(1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1),
two=c(1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0),
three=c(1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1)),
row.names=c('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'))
upsetjs() %>% fromDataFrame(dataFrame)
```
## Data Intersections
In case of an `expressionInput` the combinations of sets are directly given.
`generateIntersections`, `generateDistinctIntersections`, and `generateUnions` let you customize the generation of the set combinations
- `min` ... minimum number of sets in a set combination
- `max` ... maximum number of sets in a set combination, NULL means no limit
- `empty` ... include empty set combinations with no elements. By default they are not included
- `order.by` ... sort set combinations either by `cardinality` (number of elements) or by `degree` (number of sets
- `limit` ... show only the first limit set combinations
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
upsetjs() %>% fromList(listInput) %>%
generateDistinctIntersections()
```
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
upsetjs() %>% fromList(listInput) %>%
generateIntersections(min=2, max=NULL, empty=T, order.by='cardinality', limit=NULL)
```
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
upsetjs() %>% fromList(listInput) %>%
generateUnions(min=0, max=2, empty=T, order.by='degree', limit=NULL)
```
## Interaction
### Interactivity
by setting the `interactiveFlag` flag, the user can interactively highlight sets within the chart.
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
upsetjs() %>%
fromList(listInput) %>%
interactiveChart()
```
### Selection
with `setSelection` one manually sets the selection that is currently highlighted. The set is referenced by its name, a vector with multiple names is detected as an intersection name
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
upsetjs() %>%
fromList(listInput) %>%
setSelection("one")
```
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
upsetjs() %>%
fromList(listInput) %>%
setSelection(c("one", "two"))
```
In case UpSet.js will be used in a R Shiny context, it reports the current selection based using two custom events:
- `<outputid>_hover` when the user hovers over an item
- `<outputid>_click` when the user clicks on an item
- `<outputid>_contextMenu` when the user right clicks on an item
both events are list objects with a `name` attribute that is either `NULL` or the name of the set. In addition, there is an `elems` attribute which contains the list of highlighted elements.
See also Shiny examples at [events.R](https://github.com/upsetjs/upsetjs_r/blob/main/shiny/events.R)
## Queries
besides the selection UpSet.js supports defining queries. A query can be a list of elements or a set that should be highlighted. A query consists of a name, a color, and either the list of elements or the set (combination) to highlight.
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
upsetjs() %>%
fromList(listInput) %>%
addQuery("Q1", color="red", elems=c('a', 'b', 'c')) %>%
addQuery("Q2", color="blue", set='two')
```
## Attributes
UpSet.js supports rendering boxplots as aggregations for numerical attributes of elements and mosaic plots for categorical attributes.
The are given as part of the data frame. The attributes element has to be a list or a data frame.
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
dataFrame <- as.data.frame(list(
one=c(1, 1, 1, 0, 1, 0, 1, 1, 0, 0, 1, 1, 1),
two=c(1, 1, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0),
three=c(1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1)),
row.names=c('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm'))
upsetjs() %>%
fromDataFrame(dataFrame, attributes = list(attr=runif(nrow(dataFrame))))
```
## Styling
### Theme
UpSet.js supports thre themes: light, dark, and vega. The theme can be set by the `chartTheme` function
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
upsetjs() %>%
fromList(listInput) %>%
chartTheme('dark')
```
### Title
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
upsetjs() %>%
fromList(listInput) %>%
chartLabels(title = "Chart Title", description = "this is a long chart description")
```
### Labels
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
upsetjs() %>%
fromList(listInput) %>%
chartLabels(combination.name = "Combination Label", set.name = "Set Label")
```
### Log Scale
setting `chartLayout(numerical.scale = 'log')` switches to a log scale, similarly `'linear'` goes back to a linear scale
```{r, fig.width=9, fig.height=5, out.width="850px", tidy=TRUE, fig.align='center'}
upsetjs() %>%
fromList(listInput) %>%
chartLayout(numerical.scale = 'log')
```