blob: 14e798aa3f725936f8e945dc35d2334da6313b29 [file] [log] [blame]
Hao Zhu5e4dd502018-04-05 12:01:58 -04001---
2title: "用kableExtra做牛*的表格"
3author: "朱昊"
4date: "`r Sys.Date()`"
5output:
6 html_document:
7 theme: simplex
8 toc: true
9 toc_depth: 2
10 toc_float: true
11---
12
Hao Zhu9ac3e382018-04-12 18:56:32 -040013突然意识到这包写了都一年了还没写过中文文档,现在给大家补上。
Hao Zhu5e4dd502018-04-05 12:01:58 -040014
15另外这中文版我就不发CRAN了,要看的麻烦移步这包的文档网站[http://haozhu233.github.io/kableExtra/](http://haozhu233.github.io/kableExtra/)来看吧。
16
Hao Zhu222cd7e2018-04-10 14:27:19 -040017(因为我基本是在自由发挥。。你们不要太去在意中文英文的不同哈。。。)
Hao Zhu5e4dd502018-04-05 12:01:58 -040018
19# 简介
Hao Zhu9ac3e382018-04-12 18:56:32 -040020`kableExtra`的基本目标是帮你搭建以及美化一些常用而又较为复杂的表格。这些表格有个特点,那就是用word 或者excel来做会极其简单,而要用一个编程语言去描述往往反而会让人绝望,尤其是对于一些LaTeX初心者(比如当年的我。。)。而现在,在有了这个包的帮助下,我希望你能用一种更为直觉的方式来创建你的表格,把更多的时间花在内容上。而那些排版之类的事情,就让这个包帮你打理了吧。:)
Hao Zhu5e4dd502018-04-05 12:01:58 -040021
Hao Zhu222cd7e2018-04-10 14:27:19 -040022# 安装
23CRAN安装`install.packages("kableExtra")`不用我说,想尝鲜可以使用开发版。
Hao Zhu5e4dd502018-04-05 12:01:58 -040024```r
Hao Zhu5e4dd502018-04-05 12:01:58 -040025# install.packages("devtools")
26devtools::install_github("haozhu233/kableExtra")
27```
Hao Zhu222cd7e2018-04-10 14:27:19 -040028
29# 第一步
Hao Zhu9ac3e382018-04-12 18:56:32 -040030## 用`kable`生成HTML表格
31首先要强调一下,`kable`这个function来自于R圈大佬谢益辉的`knitr`包。大致上说,`kable`可以生成三种格式的表格:`HTML`, `LaTeX` `markdown`(默认)。`markdown`作为默认的格式完美契合`rmarkdown`本身,可却因为`markdown`表格本身功能上的限制,在很多情况下达不到我们的要求。因此,当你需要个性化你的表格时,你往往需要先让`kable`先帮你生成一个`HTML`的表格。在这份文档中,我们主要使用`mtcars`这个数据的前几列和几行数据来演示。
Hao Zhu222cd7e2018-04-10 14:27:19 -040032
Hao Zhu5e4dd502018-04-05 12:01:58 -040033```{r}
Hao Zhu5e4dd502018-04-05 12:01:58 -040034library(kableExtra)
35dt <- mtcars[1:5, 1:6]
Hao Zhu5e4dd502018-04-05 12:01:58 -040036
Hao Zhu5e4dd502018-04-05 12:01:58 -040037kable(dt, "html")
38```
39
Hao Zhu9ac3e382018-04-12 18:56:32 -040040
41注意,如果你有好几个表格要去生成,与其在每一个kable里定义格式,不如在所有的事情开始之前定义一个全局的设置。这样的话,上面的语句就只需要打`kable(dt)`就可以了。
42
43```{r}
44options(knitr.table.format = "html")
45```
46
47## bootstrap了解一下
48如果你从没听过bootstrap的话,你应该去了解一下。简单来说,bootstrap是个开源的CSS库,可以用来很方便地美化HTML页面。也因此,bootstrapRStudio的产品中被大量使用。你用rmarkdownshiny生成出来的HTML文档和app都有加载。而这个包的HTML部分也提供了一些借口方便你快速实现一些bootstrap风的表格。
49
Hao Zhu5e4dd502018-04-05 12:01:58 -040050```{r}
51dt %>%
52 kable("html") %>%
53 kable_styling()
54```
55
Hao Zhu9ac3e382018-04-12 18:56:32 -040056# 表格整体风格
57`kable_styling`提供了几种其他的方式来定制表格的整体风格。
Hao Zhu5e4dd502018-04-05 12:01:58 -040058
Hao Zhu9ac3e382018-04-12 18:56:32 -040059## Bootstrap的表格`class`
60如果你熟悉bootstrap,那么以下这些css `class`对你一定不陌生:`striped`, `bordered`, `hover`, `condensed` 以及 `responsive`. 如果你不熟悉,你可以看看 [这里](http://getbootstrap.com/css/#tables)。你可以通过`kable_styling`快速地把这些样式应用到你的表格里。比如,下面这个例子就是给表格加上斑马纹和悬浮效果。
Hao Zhu5e4dd502018-04-05 12:01:58 -040061
Hao Zhu5e4dd502018-04-05 12:01:58 -040062```{r}
63kable(dt, "html") %>%
64 kable_styling(bootstrap_options = c("striped", "hover"))
65```
66
Hao Zhu9ac3e382018-04-12 18:56:32 -040067有些人觉得默认的bootstrap表格每行都太高了,这时候用上`condensed`会让内容显得更紧凑。
Hao Zhu5e4dd502018-04-05 12:01:58 -040068```{r}
69kable(dt, "html") %>%
70 kable_styling(bootstrap_options = c("striped", "hover", "condensed"))
71```
72
Hao Zhu9ac3e382018-04-12 18:56:32 -040073`responsive`这选项可以让表格样式随屏幕宽度变化,更适合手机屏。
Hao Zhu5e4dd502018-04-05 12:01:58 -040074```{r}
75kable(dt, "html") %>%
76 kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive"))
77```
78
Hao Zhu9ac3e382018-04-12 18:56:32 -040079## “为啥我的表格这么宽啊?”
80“为啥我的表格这么宽”是一个`rmarkdown`新人常见问题。原因是`bootstrap`把宽度统一订成了100%的容器宽。设计`bootstrap`的人原来想让你用他们的grid system来控制表格的宽度,可是当你在写`rmarkdown`的时候,难道还想即兴来定义一串`<div>`?解决办法如下。
Hao Zhu5e4dd502018-04-05 12:01:58 -040081```{r}
82kable(dt, "html") %>%
83 kable_styling(bootstrap_options = "striped", full_width = F)
84```
85
Hao Zhu9ac3e382018-04-12 18:56:32 -040086## 表格位置
87表格在页面中位置也是排版很重要的一块。注意,这只有在表格不是全屏宽的时候才有用(这是当然的啦。
Hao Zhu5e4dd502018-04-05 12:01:58 -040088```{r}
89kable(dt, "html") %>%
90 kable_styling(bootstrap_options = "striped", full_width = F, position = "left")
91```
92
Hao Zhu9ac3e382018-04-12 18:56:32 -040093除了常见的左中右,你还可以选择`float_left``float_right`
Hao Zhu5e4dd502018-04-05 12:01:58 -040094```{r}
95kable(dt, "html") %>%
96 kable_styling(bootstrap_options = "striped", full_width = F, position = "float_right")
97```
Hao Zhu9ac3e382018-04-12 18:56:32 -040098从小丘西行百二十步,隔篁竹,闻水声,如鸣佩环,心乐之。伐竹取道,下见小潭,水尤清洌。全石以为底,近岸,卷石底以出,为坻,为屿,为嵁,为岩。青树翠蔓,蒙络摇缀,参差披拂。
Hao Zhu5e4dd502018-04-05 12:01:58 -040099
Hao Zhu9ac3e382018-04-12 18:56:32 -0400100潭中鱼可百许头,皆若空游无所依。日光下澈,影布石上,佁然不动;俶尔远逝,往来翕忽,似与游者相乐。
101
102潭西南而望,斗折蛇行,明灭可见。其岸势犬牙差互,不可知其源。
103
104坐潭上,四面竹树环合,寂寥无人,凄神寒骨,悄怆幽邃。以其境过清,不可久居,乃记之而去。
105
106同游者,吴武陵,龚古,余弟宗玄。隶而从者,崔氏二小生:曰恕己,曰奉壹。
107
108
109## 字体大小
110如题,当你的表格过大时,你可以调调字体大小。
Hao Zhu5e4dd502018-04-05 12:01:58 -0400111```{r}
112kable(dt, "html") %>%
113 kable_styling(bootstrap_options = "striped", font_size = 7)
114```
115
Hao Zhu9ac3e382018-04-12 18:56:32 -0400116# 列与行的格式
117## 列
118`column_spec`如其名,可以帮你定义某一列的样式,比如宽度啊,字体颜色啊,加粗,斜体等。列的宽度其实尤为重要,这样你表格的样式不会被一串巨长的文字打乱。
Hao Zhu5e4dd502018-04-05 12:01:58 -0400119
120```{r}
121text_tbl <- data.frame(
122 Items = c("Item 1", "Item 2", "Item 3"),
123 Features = c(
124 "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vehicula tempor ex. Morbi malesuada sagittis turpis, at venenatis nisl luctus a. ",
125 "In eu urna at magna luctus rhoncus quis in nisl. Fusce in velit varius, posuere risus et, cursus augue. Duis eleifend aliquam ante, a aliquet ex tincidunt in. ",
126 "Vivamus venenatis egestas eros ut tempus. Vivamus id est nisi. Aliquam molestie erat et sollicitudin venenatis. In ac lacus at velit scelerisque mattis. "
127 )
128)
129
130kable(text_tbl, "html") %>%
131 kable_styling(full_width = F) %>%
132 column_spec(1, bold = T, border_right = T) %>%
133 column_spec(2, width = "30em", background = "yellow")
134```
135
136
Hao Zhu9ac3e382018-04-12 18:56:32 -0400137## 行
138`row_spec``column_spec`差不多,除了没有列宽这样的东西。注意,当你数第几行的时候,你不需要考虑表头和你通过`group_rows`添加的那些行,就数那些原生的“内容”行就行。
Hao Zhu5e4dd502018-04-05 12:01:58 -0400139
140```{r}
141kable(dt, "html") %>%
142 kable_styling("striped", full_width = F) %>%
143 column_spec(5:7, bold = T) %>%
144 row_spec(3:5, bold = T, color = "white", background = "#D7261E")
145```
146
Hao Zhu9ac3e382018-04-12 18:56:32 -0400147### 表头的那行
148只需要说`row_spec(0, ...)`就可以了。
Hao Zhu5e4dd502018-04-05 12:01:58 -0400149```{r}
150kable(dt, format = "html") %>%
151 kable_styling("striped", full_width = F) %>%
152 row_spec(0, angle = -45)
153```
154
Hao Zhu9ac3e382018-04-12 18:56:32 -0400155# 格子的格式
156`cell_spec` 和之前说的两个`spec`不一样,你应该在把你的数据放进`kable`之前使用它。就像如下的例子,`cell_spec`可以很轻易的用在`dplyr`pipeline里。注意,因为你用`cell_spec`生成的是直接的`HTML``LaTeX`,你需要在`kable`里加上`escape = FALSE`。同时,你需要告诉`cell_spec`你到底需要`HTML`还是`LaTeX`。如果你需要大量使用的话,使用全局格式设定会让你好过很多。再说一遍,`options(knitr.table.format = "latex")`
Hao Zhu5e4dd502018-04-05 12:01:58 -0400157
Hao Zhu9ac3e382018-04-12 18:56:32 -0400158## `cell_spec`和`ifelse`
159`cell_spec``ifelse`结合会让表格里的数据的可视度一下子高很多。
Hao Zhu5e4dd502018-04-05 12:01:58 -0400160```{r, message=FALSE, warning=FALSE}
161library(dplyr)
162mtcars[1:10, 1:2] %>%
163 mutate(
164 car = row.names(.),
165 # You don't need format = "html" if you have ever defined options(knitr.table.format)
166 mpg = cell_spec(mpg, "html", color = ifelse(mpg > 20, "red", "blue")),
167 cyl = cell_spec(cyl, "html", color = "white", align = "c", angle = 45,
168 background = factor(cyl, c(4, 6, 8),
169 c("#666666", "#999999", "#BBBBBB")))
170 ) %>%
171 select(car, mpg, cyl) %>%
172 kable("html", escape = F) %>%
173 kable_styling("striped", full_width = F)
174```
175
Hao Zhu9ac3e382018-04-12 18:56:32 -0400176## 给你的表格加上Viridis Color
177这包还带了几个`cell_spec`的辅助型方程,包括 `spec_color`, `spec_font_size` `spec_angle`. 他们可以帮你把数据变成相应的颜色,字体大小和角度。其中最有意思的是那个颜色,这里用了[viridis color](https://CRAN.R-project.org/package=viridisLite)这个色板. 合理使用的话几乎可以在表格里画热图。
Hao Zhu5e4dd502018-04-05 12:01:58 -0400178
179```{r}
180iris[1:10, ] %>%
181 mutate_if(is.numeric, function(x) {
182 cell_spec(x, "html", bold = T,
183 color = spec_color(x, end = 0.9),
184 font_size = spec_font_size(x))
185 }) %>%
186 mutate(Species = cell_spec(
187 Species, "html", color = "white", bold = T,
188 background = spec_color(1:10, end = 0.9, option = "A", direction = -1)
189 )) %>%
190 kable("html", escape = F, align = "c") %>%
191 kable_styling("striped", full_width = F)
192```
193
Hao Zhu5e4dd502018-04-05 12:01:58 -0400194
Hao Zhu9ac3e382018-04-12 18:56:32 -0400195## 普通文本的格式
196其实你也可以用`cell_spec`或者`text_spec`去定义普通文字的样式。
Hao Zhu5e4dd502018-04-05 12:01:58 -0400197
198```{r}
Hao Zhu9ac3e382018-04-12 18:56:32 -0400199sometext <- strsplit("人群中突然钻出一个光头", "")[[1]]
Hao Zhu5e4dd502018-04-05 12:01:58 -0400200text_formatted <- paste(
201 text_spec(sometext, "html", color = spec_color(1:length(sometext), end = 0.9),
202 font_size = spec_font_size(1:length(sometext), begin = 5, end = 20)),
Hao Zhu9ac3e382018-04-12 18:56:32 -0400203 collapse = "")
Hao Zhu5e4dd502018-04-05 12:01:58 -0400204
Hao Zhu5e4dd502018-04-05 12:01:58 -0400205```
206`r text_formatted`
207
Hao Zhu9ac3e382018-04-12 18:56:32 -0400208## Tooltip 悬浮提示框
209你可以通过`cell_spec`相对简单地添加悬浮提示框. 举个例子,`text_spec("tooltip", color = "red", tooltip = "Hello World")` 会生成 `r text_spec("Hover over me", color = "red", tooltip = "Hello World")`。注意HTML原生的提示框非常慢,你可能会想用`bootstrap`javascript版的。如果你想这么做的话,你需要把接下来的这段代码放在你的rmarkdown文本的任何地方。需要注意的是,如果你和这个文档一样使用了这种目录在侧面的格式,你就没办法使用这个功能。原因在于这个和`jqueryui``tooltip`互相冲突。这种情况下,你可能会想试试我下面说的`popover`。这两个差不多。
Hao Zhu5e4dd502018-04-05 12:01:58 -0400210
Hao Zhu5e4dd502018-04-05 12:01:58 -0400211```
212<script>
213$(document).ready(function(){
214 $('[data-toggle="tooltip"]').tooltip();
215});
216</script>
217```
218
Hao Zhu9ac3e382018-04-12 18:56:32 -0400219## Popover Message 有头的悬浮弹出提示框
220和之前一样的设定,区别在于你可以给`popover`的小框加一个标题。不加的话,和上面的功能基本一样。
Hao Zhu5e4dd502018-04-05 12:01:58 -0400221
222```
223<script>
224$(document).ready(function(){
225 $('[data-toggle="popover"]').popover();
226});
227</script>
228```
229
230<script>
231$(document).ready(function(){
232 $('[data-toggle="popover"]').popover();
233});
234</script>
235
236```{r}
237popover_dt <- data.frame(
238 position = c("top", "bottom", "right", "left"),
239 stringsAsFactors = FALSE
240)
241popover_dt$`Hover over these items` <- cell_spec(
242 paste("Message on", popover_dt$position), # Cell texts
243 popover = spec_popover(
244 content = popover_dt$position,
245 title = NULL, # title will add a Title Panel on top
246 position = popover_dt$position
247 ))
248kable(popover_dt, "html", escape = FALSE) %>%
249 kable_styling("striped", full_width = FALSE)
250```
251
Hao Zhu9ac3e382018-04-12 18:56:32 -0400252## 链接
253你可以给文字添加一个链接`text_spec("Google", link = "https://google.com")`: `r text_spec("Google", link = "https://google.com")`。这里有一个利用加链接让`popover`悬浮框本来的文本更加明显的小技巧 `text_spec("Hover on me", link = "javascript:void(0)", popover = "Hello")`: `r text_spec("Hover on me", link = "javascript:void(0)", popover = "Hello")`
Hao Zhu5e4dd502018-04-05 12:01:58 -0400254
Hao Zhu9ac3e382018-04-12 18:56:32 -0400255## 同时使用`kableExtra`和`formattable`
256如果你也喜欢任坤大佬的`formattable`的话,你其实可以将`formattable``kableExtra`用在一起,灰常酷炫。
Hao Zhu5e4dd502018-04-05 12:01:58 -0400257```{r, message = FALSE, warning=FALSE}
258library(formattable)
259mtcars[1:5, 1:4] %>%
260 mutate(
261 car = row.names(.),
262 mpg = color_tile("white", "orange")(mpg),
263 cyl = cell_spec(cyl, "html", angle = (1:5)*60,
264 background = "red", color = "white", align = "center"),
265 disp = ifelse(disp > 200,
266 cell_spec(disp, "html", color = "red", bold = T),
267 cell_spec(disp, "html", color = "green", italic = T)),
268 hp = color_bar("lightgreen")(hp)
269 ) %>%
270 select(car, everything()) %>%
271 kable("html", escape = F) %>%
272 kable_styling("hover", full_width = F) %>%
273 column_spec(5, width = "3cm") %>%
274 add_header_above(c(" ", "Hello" = 2, "World" = 2))
275```
276
277
Hao Zhu9ac3e382018-04-12 18:56:32 -0400278# 行组和列组
279## 列组
280我们在Word里做表格时,要想表示两个列同属一个类,我们会在这两列的上面再加一行,画条横线,写上名字。基本上`add_header_above`就是做这事的。在使用这个方程时,你需要给他一个**`named vector`**(划重点)。这个`named vector`的本身是column span,而具体的文字则在names里(没看懂我在说啥的,请参考下面的例子)。这样的设计主要是为了方便。
Hao Zhu5e4dd502018-04-05 12:01:58 -0400281```{r}
282kable(dt, "html") %>%
283 kable_styling("striped") %>%
284 add_header_above(c(" " = 1, "Group 1" = 2, "Group 2" = 2, "Group 3" = 2))
285```
286
Hao Zhu9ac3e382018-04-12 18:56:32 -0400287事实上,你甚至可以一层一层继续往上加下去。
Hao Zhu5e4dd502018-04-05 12:01:58 -0400288```{r}
289kable(dt, "html") %>%
290 kable_styling(c("striped", "bordered")) %>%
291 add_header_above(c(" ", "Group 1" = 2, "Group 2" = 2, "Group 3" = 2)) %>%
292 add_header_above(c(" ", "Group 4" = 4, "Group 5" = 2)) %>%
293 add_header_above(c(" ", "Group 6" = 6))
294```
295
296## Group rows via labeling
297Sometimes we want a few rows of the table being grouped together. They might be items under the same topic (e.g., animals in one species) or just different data groups for a categorical variable (e.g., age < 40, age > 40). With the new function `group_rows()` in `kableExtra`, this kind of task can be completed in one line. Please see the example below. Note that when you count for the start/end rows of the group, you don't need to count for the header rows nor other group label rows. You only need to think about the row numbers in the "original R dataframe".
298```{r}
299kable(mtcars[1:10, 1:6], "html", caption = "Group Rows") %>%
300 kable_styling("striped", full_width = F) %>%
301 group_rows("Group 1", 4, 7) %>%
302 group_rows("Group 2", 8, 10)
303```
304
305Another way to use `group_rows` is to provide an grouping index, similar with `add_header_above()`. This feature is only available in kableExtra > 0.5.2.
306```{r, eval = F}
307# Not evaluated. This example generates the same table as above.
308kable(mtcars[1:10, 1:6], "html", caption = "Group Rows") %>%
309 kable_styling("striped", full_width = F) %>%
310 group_rows(index = c(" " = 3, "Group 1" = 4, "Group 2" = 3))
311```
312
313For advanced users, you can even define your own css for the group labeling.
314```{r}
315kable(dt, "html") %>%
316 kable_styling("striped", full_width = F) %>%
317 group_rows("Group 1", 3, 5, label_row_css = "background-color: #666; color: #fff;")
318```
319
320## Row indentation
321Unlike `group_rows()`, which will insert a labeling row, sometimes we want to list a few sub groups under a total one. In that case, `add_indent()` is probably more apporiate.
322For advanced users, you can even define your own css for the group labeling.
323```{r}
324kable(dt, "html") %>%
325 kable_styling("striped", full_width = F) %>%
326 add_indent(c(1, 3, 5))
327```
328
329## Group rows via multi-row cell
330Function `group_rows` is great for showing simple structural information on rows but sometimes people may need to show structural information with multiple layers. When it happens, you may consider to use `collapse_rows` instead, which will put repeating cells in columns into multi-row cells.
331
332```{r}
333collapse_rows_dt <- data.frame(C1 = c(rep("a", 10), rep("b", 5)),
334 C2 = c(rep("c", 7), rep("d", 3), rep("c", 2), rep("d", 3)),
335 C3 = 1:15,
336 C4 = sample(c(0,1), 15, replace = TRUE))
337kable(collapse_rows_dt, "html", align = "c") %>%
338 kable_styling(full_width = F) %>%
339 column_spec(1, bold = T) %>%
340 collapse_rows(columns = 1:2)
341```
342
343# Table Footnote
344
345> Now it's recommended to use the new `footnote` function instead of `add_footnote` to make table footnotes.
346
347Documentations for `add_footnote` can be found [here](http://haozhu233.github.io/kableExtra/legacy_features#add_footnote).
348
349There are four notation systems in `footnote`, namely `general`, `number`, `alphabet` and `symbol`. The last three types of footnotes will be labeled with corresponding marks while `general` won't be labeled. You can pick any one of these systems or choose to display them all for fulfill the APA table footnotes requirements.
350```{r}
351kable(dt, "html", align = "c") %>%
352 kable_styling(full_width = F) %>%
353 footnote(general = "Here is a general comments of the table. ",
354 number = c("Footnote 1; ", "Footnote 2; "),
355 alphabet = c("Footnote A; ", "Footnote B; "),
356 symbol = c("Footnote Symbol 1; ", "Footnote Symbol 2")
357 )
358```
359
360You can also specify title for each category by using the `***_title` arguments. Default value for `general_title` is "Note: " and "" for the rest three. You can also change the order using `footnote_order`. You can even display footnote as chunk texts (default is as a list) using `footnote_as_chunk`.
361
362```{r}
363kable(dt, "html", align = "c") %>%
364 kable_styling(full_width = F) %>%
365 footnote(general = "Here is a general comments of the table. ",
366 number = c("Footnote 1; ", "Footnote 2; "),
367 alphabet = c("Footnote A; ", "Footnote B; "),
368 symbol = c("Footnote Symbol 1; ", "Footnote Symbol 2"),
369 general_title = "General: ", number_title = "Type I: ",
370 alphabet_title = "Type II: ", symbol_title = "Type III: ",
371 footnote_as_chunk = T
372 )
373```
374
375If you need to add footnote marks in table, you need to do it manually (no fancy) using `footnote_mark_***()`. Remember that similar with `cell_spec`, you need to tell this function whether you want it to do it in `HTML` (default) or `LaTeX`. You can set it for all using the `knitr.table.format` global option. ALso, if you have ever use `footnote_mark_***()`, you need to put `escape = F` in your `kable` function to avoid escaping of special characters.
376
377```{r}
378dt_footnote <- dt
379names(dt_footnote)[2] <- paste0(names(dt_footnote)[2],
380 footnote_marker_symbol(1))
381row.names(dt_footnote)[4] <- paste0(row.names(dt_footnote)[4],
382 footnote_marker_alphabet(1))
383kable(dt_footnote, "html", align = "c",
384 # Remember this escape = F
385 escape = F) %>%
386 kable_styling(full_width = F) %>%
387 footnote(alphabet = "Footnote A; ",
388 symbol = "Footnote Symbol 1; ",
389 alphabet_title = "Type II: ", symbol_title = "Type III: ",
390 footnote_as_chunk = T)
391```
392
393# HTML Only Features
394## Scroll box
395If you have a huge table and you don't want to reduce the font size to unreadable, you may want to put your HTML table in a scroll box, of which users can pick the part they like to read. Note that scroll box isn't printer friendly, so be aware of that when you use this feature.
396
397When you use `scroll_box`, you can specify either `height` or `width`. When you specify `height`, you will get a vertically scrollable box and vice versa. If you specify both, you will get a two-way scrollable box.
398
399```{r}
400kable(cbind(mtcars, mtcars), "html") %>%
401 kable_styling() %>%
402 scroll_box(width = "500px", height = "200px")
403```