Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 1 | --- |
| 2 | title: "用kableExtra做牛*的表格" |
| 3 | author: "朱昊" |
| 4 | date: "`r Sys.Date()`" |
| 5 | output: |
| 6 | html_document: |
| 7 | theme: simplex |
| 8 | toc: true |
| 9 | toc_depth: 2 |
| 10 | toc_float: true |
| 11 | --- |
| 12 | |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 13 | 说起来这包写了都一年了我还没写过中文文档,现在给大家补上。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 14 | |
| 15 | 另外这中文版我就不发CRAN了,要看的麻烦移步这包的文档网站[http://haozhu233.github.io/kableExtra/](http://haozhu233.github.io/kableExtra/)来看吧。 |
| 16 | |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 17 | (因为我基本是在~~自由发挥~~重写一遍。。你们不要太去在意中文英文的不同哈。。。) |
| 18 | |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 19 | |
| 20 | # 简介 |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 21 | `kableExtra`的目标是帮你搭建以及美化一些常用而又较为复杂的表格。这些表格有个特点,那就是用word 或者excel来做会极其简单,而要用一个编程语言去描述,尤其是对于一些LaTeX初心者(比如当年的我。。),往往会让人绝望。而现在,在这个包的帮助下,我希望你能用一种更为直觉的方式来创建你的表格,把更多的时间花在内容上。而那些排版之类的事情,就留给这个包吧。:) |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 22 | |
Hao Zhu | 222cd7e | 2018-04-10 14:27:19 -0400 | [diff] [blame] | 23 | # 安装 |
| 24 | CRAN安装`install.packages("kableExtra")`不用我说,想尝鲜可以使用开发版。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 25 | ```r |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 26 | # install.packages("devtools") |
| 27 | devtools::install_github("haozhu233/kableExtra") |
| 28 | ``` |
Hao Zhu | 222cd7e | 2018-04-10 14:27:19 -0400 | [diff] [blame] | 29 | |
| 30 | # 第一步 |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 31 | ## 用`kable`生成HTML表格 |
| 32 | 首先要强调一下,`kable`这个function来自于R圈大佬谢益辉的`knitr`包。大致上说,`kable`可以生成三种格式的表格:`HTML`, `LaTeX` 和 `markdown`(默认)。`markdown`作为默认的格式完美契合`rmarkdown`本身,可却因为`markdown`表格本身功能上的限制,在很多情况下达不到我们的要求。因此,当你需要个性化你的表格时,你往往需要先让`kable`先帮你生成一个`HTML`的表格。在这份文档中,我们主要使用`mtcars`这个数据的前几列和几行数据来演示。 |
Hao Zhu | 222cd7e | 2018-04-10 14:27:19 -0400 | [diff] [blame] | 33 | |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 34 | ```{r} |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 35 | library(kableExtra) |
| 36 | dt <- mtcars[1:5, 1:6] |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 37 | |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 38 | kable(dt, "html") |
| 39 | ``` |
| 40 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 41 | 注意,如果你有好几个表格要去生成,与其在每一个kable里定义格式,不如在所有的事情开始之前定义一个全局的设置。这样的话,上面的语句就只需要打`kable(dt)`就可以了。 |
| 42 | |
| 43 | ```{r} |
| 44 | options(knitr.table.format = "html") |
| 45 | ``` |
| 46 | |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 47 | 当然,在今后的版本中(目前开发版),甚至这一步都可以被省略。今后,`kableExtra`将会自动根据你需要的情况帮你设好这个全局格式。这一步发生在你加载这个包的时候(`library(kableExtra)`),所以如果你不想要这个功能的话,可以在你加载`kableExtra`之前通过设置`options(kableExtra.auto_format = F)`来解决。 |
| 48 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 49 | ## bootstrap了解一下 |
| 50 | 如果你从没听过bootstrap的话,你应该去了解一下。简单来说,bootstrap是个开源的CSS库,可以用来很方便地美化HTML页面。也因此,bootstrap在RStudio的产品中被大量使用。你用rmarkdown和shiny生成出来的HTML文档和app都有加载。而这个包的HTML部分也提供了一些借口方便你快速实现一些bootstrap风的表格。 |
| 51 | |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 52 | ```{r} |
| 53 | dt %>% |
| 54 | kable("html") %>% |
| 55 | kable_styling() |
| 56 | ``` |
| 57 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 58 | # 表格整体风格 |
| 59 | `kable_styling`提供了几种其他的方式来定制表格的整体风格。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 60 | |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 61 | ## Bootstrap的表格格式 |
| 62 | 如果你熟悉bootstrap,那么以下这些CSS类对你一定不陌生:`striped`, `bordered`, `hover`, `condensed` 以及 `responsive`. 不熟悉也没关系,你可以看看 [这里](http://getbootstrap.com/css/#tables)来了解。你可以通过`kable_styling`快速地把这些样式应用到你的表格里。比如,下面这个例子就是给表格加上斑马纹和悬浮效果。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 63 | |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 64 | ```{r} |
| 65 | kable(dt, "html") %>% |
| 66 | kable_styling(bootstrap_options = c("striped", "hover")) |
| 67 | ``` |
| 68 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 69 | 有些人觉得默认的bootstrap表格每行都太高了,这时候用上`condensed`会让内容显得更紧凑。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 70 | ```{r} |
| 71 | kable(dt, "html") %>% |
| 72 | kable_styling(bootstrap_options = c("striped", "hover", "condensed")) |
| 73 | ``` |
| 74 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 75 | `responsive`这选项可以让表格样式随屏幕宽度变化,更适合手机屏。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 76 | ```{r} |
| 77 | kable(dt, "html") %>% |
| 78 | kable_styling(bootstrap_options = c("striped", "hover", "condensed", "responsive")) |
| 79 | ``` |
| 80 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 81 | ## “为啥我的表格这么宽啊?” |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 82 | “为啥我的表格这么宽”是一个`rmarkdown`新人常见问题。这其中的原因是,`bootstrap`把表格的宽度统一订成了100%的[容器](http://w3schools.wang/w3css/w3css_containers.html)宽。设计`bootstrap`的人原来想让你用他们的grid system来控制表格的宽度,可是当你在写`rmarkdown`的时候,难不成还想即兴来定义一串`<div>`?解决办法如下。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 83 | ```{r} |
| 84 | kable(dt, "html") %>% |
| 85 | kable_styling(bootstrap_options = "striped", full_width = F) |
| 86 | ``` |
| 87 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 88 | ## 表格位置 |
| 89 | 表格在页面中位置也是排版很重要的一块。注意,这只有在表格不是全屏宽的时候才有用(这是当然的啦。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 90 | ```{r} |
| 91 | kable(dt, "html") %>% |
| 92 | kable_styling(bootstrap_options = "striped", full_width = F, position = "left") |
| 93 | ``` |
| 94 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 95 | 除了常见的左中右,你还可以选择`float_left`和`float_right`。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 96 | ```{r} |
| 97 | kable(dt, "html") %>% |
| 98 | kable_styling(bootstrap_options = "striped", full_width = F, position = "float_right") |
| 99 | ``` |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 100 | 滚滚长江东逝水,浪花淘尽英雄。是非成败转头空。青山依旧在,几度夕阳红。白发渔樵江渚上,惯看秋月春风。 一壶浊酒喜相逢。 古今多少事,都付笑谈中。滚滚长江东逝水,浪花淘尽英雄。是非成败转头空。青山依旧在,几度夕阳红。白发渔樵江渚上,惯看秋月春风。 一壶浊酒喜相逢。古今多少事,都付笑谈中。滚滚长江东逝水,浪花淘尽英雄。是非成败转头空。青山依旧在,几度夕阳红。白发渔樵江渚上,惯看秋月春风。 一壶浊酒喜相逢。古今多少事,都付笑谈中。滚滚长江东逝水,浪花淘尽英雄。是非成败转头空。青山依旧在,几度夕阳红。白发渔樵江渚上,惯看秋月春风。一壶浊酒喜相逢。古今多少事,都付笑谈中。滚滚长江东逝水,浪花淘尽英雄。是非成败转头空。青山依旧在,几度夕阳红。白发渔樵江渚上,惯看秋月春风。一壶浊酒喜相逢。古今多少事,都付笑谈中。滚滚长江东逝水,浪花淘尽英雄。是非成败转头空。青山依旧在,几度夕阳红。白发渔樵江渚上,惯看秋月春风。 一壶浊酒喜相逢。古今多少事,都付笑谈中。滚滚长江东逝水,浪花淘尽英雄。是非成败转头空。青山依旧在,几度夕阳红。白发渔樵江渚上,惯看秋月春风。 一壶浊酒喜相逢。 古今多少事,都付笑谈中。 |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 101 | |
| 102 | |
| 103 | ## 字体大小 |
| 104 | 如题,当你的表格过大时,你可以调调字体大小。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 105 | ```{r} |
| 106 | kable(dt, "html") %>% |
| 107 | kable_styling(bootstrap_options = "striped", font_size = 7) |
| 108 | ``` |
| 109 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 110 | # 列与行的格式 |
| 111 | ## 列 |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 112 | `column_spec`如其名,可以帮你定义某一列或者几列的样式,比如宽度,字体颜色,加粗,斜体等。列的宽度其实尤为重要,这样如果你的表格里有一串巨长的文字,它的格式不会一下被打乱。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 113 | |
| 114 | ```{r} |
| 115 | text_tbl <- data.frame( |
| 116 | Items = c("Item 1", "Item 2", "Item 3"), |
| 117 | Features = c( |
| 118 | "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin vehicula tempor ex. Morbi malesuada sagittis turpis, at venenatis nisl luctus a. ", |
| 119 | "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. ", |
| 120 | "Vivamus venenatis egestas eros ut tempus. Vivamus id est nisi. Aliquam molestie erat et sollicitudin venenatis. In ac lacus at velit scelerisque mattis. " |
| 121 | ) |
| 122 | ) |
| 123 | |
| 124 | kable(text_tbl, "html") %>% |
| 125 | kable_styling(full_width = F) %>% |
| 126 | column_spec(1, bold = T, border_right = T) %>% |
| 127 | column_spec(2, width = "30em", background = "yellow") |
| 128 | ``` |
| 129 | |
| 130 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 131 | ## 行 |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 132 | `row_spec`和`column_spec`差不多,除了没有列宽。注意,当你数第几行的时候,你不需要考虑表头和你通过`group_rows`添加的那些行,就数那些原生的“内容”行就行。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 133 | |
| 134 | ```{r} |
| 135 | kable(dt, "html") %>% |
| 136 | kable_styling("striped", full_width = F) %>% |
| 137 | column_spec(5:7, bold = T) %>% |
| 138 | row_spec(3:5, bold = T, color = "white", background = "#D7261E") |
| 139 | ``` |
| 140 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 141 | ### 表头的那行 |
| 142 | 只需要说`row_spec(0, ...)`就可以了。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 143 | ```{r} |
| 144 | kable(dt, format = "html") %>% |
| 145 | kable_styling("striped", full_width = F) %>% |
| 146 | row_spec(0, angle = -45) |
| 147 | ``` |
| 148 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 149 | # 格子的格式 |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 150 | `cell_spec` 和之前说的两个`spec`不一样,你应该在把你的数据放进`kable`之前使用它,就像接下来的例子。你可以很容易地在`dplyr`的pipeline里加上一截`cell_spec`。注意,因为你用`cell_spec`生成的是直接的`HTML`和`LaTeX`,你需要在`kable`里加上`escape = FALSE`。同时,你需要告诉`cell_spec`你到底需要`HTML`还是`LaTeX`。而在今后版本的`kableExtra`里,因为全局的表格格式已经被自动设好了,你就不需要做这一步了。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 151 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 152 | ## `cell_spec`和`ifelse` |
| 153 | `cell_spec`和`ifelse`结合会让表格里的数据的可视度一下子高很多。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 154 | ```{r, message=FALSE, warning=FALSE} |
| 155 | library(dplyr) |
| 156 | mtcars[1:10, 1:2] %>% |
| 157 | mutate( |
| 158 | car = row.names(.), |
| 159 | # You don't need format = "html" if you have ever defined options(knitr.table.format) |
| 160 | mpg = cell_spec(mpg, "html", color = ifelse(mpg > 20, "red", "blue")), |
| 161 | cyl = cell_spec(cyl, "html", color = "white", align = "c", angle = 45, |
| 162 | background = factor(cyl, c(4, 6, 8), |
| 163 | c("#666666", "#999999", "#BBBBBB"))) |
| 164 | ) %>% |
| 165 | select(car, mpg, cyl) %>% |
| 166 | kable("html", escape = F) %>% |
| 167 | kable_styling("striped", full_width = F) |
| 168 | ``` |
| 169 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 170 | ## 给你的表格加上Viridis Color |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 171 | 这包还带了几个`cell_spec`的辅助型方程,包括 `spec_color`, `spec_font_size` 和 `spec_angle`. 他们可以帮你把数据变成相应的颜色,字体大小和角度。其中最有意思的是那个颜色,这里用了[viridis color](https://CRAN.R-project.org/package=viridisLite)这个色板. 合理使用的话几乎可以用表格做出类似热图的可视化。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 172 | |
| 173 | ```{r} |
| 174 | iris[1:10, ] %>% |
| 175 | mutate_if(is.numeric, function(x) { |
| 176 | cell_spec(x, "html", bold = T, |
| 177 | color = spec_color(x, end = 0.9), |
| 178 | font_size = spec_font_size(x)) |
| 179 | }) %>% |
| 180 | mutate(Species = cell_spec( |
| 181 | Species, "html", color = "white", bold = T, |
| 182 | background = spec_color(1:10, end = 0.9, option = "A", direction = -1) |
| 183 | )) %>% |
| 184 | kable("html", escape = F, align = "c") %>% |
| 185 | kable_styling("striped", full_width = F) |
| 186 | ``` |
| 187 | |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 188 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 189 | ## 普通文本的格式 |
| 190 | 其实你也可以用`cell_spec`或者`text_spec`去定义普通文字的样式。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 191 | |
| 192 | ```{r} |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 193 | sometext <- strsplit("人群中突然钻出一个光头", "")[[1]] |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 194 | text_formatted <- paste( |
| 195 | text_spec(sometext, "html", color = spec_color(1:length(sometext), end = 0.9), |
| 196 | font_size = spec_font_size(1:length(sometext), begin = 5, end = 20)), |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 197 | collapse = "") |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 198 | |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 199 | ``` |
| 200 | `r text_formatted` |
| 201 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 202 | ## Tooltip 悬浮提示框 |
| 203 | 你可以通过`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 Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 204 | |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 205 | ``` |
| 206 | <script> |
| 207 | $(document).ready(function(){ |
| 208 | $('[data-toggle="tooltip"]').tooltip(); |
| 209 | }); |
| 210 | </script> |
| 211 | ``` |
| 212 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 213 | ## Popover Message 有头的悬浮弹出提示框 |
| 214 | 和之前一样的设定,区别在于你可以给`popover`的小框加一个标题。不加的话,和上面的功能基本一样。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 215 | |
| 216 | ``` |
| 217 | <script> |
| 218 | $(document).ready(function(){ |
| 219 | $('[data-toggle="popover"]').popover(); |
| 220 | }); |
| 221 | </script> |
| 222 | ``` |
| 223 | |
| 224 | <script> |
| 225 | $(document).ready(function(){ |
| 226 | $('[data-toggle="popover"]').popover(); |
| 227 | }); |
| 228 | </script> |
| 229 | |
| 230 | ```{r} |
| 231 | popover_dt <- data.frame( |
| 232 | position = c("top", "bottom", "right", "left"), |
| 233 | stringsAsFactors = FALSE |
| 234 | ) |
| 235 | popover_dt$`Hover over these items` <- cell_spec( |
| 236 | paste("Message on", popover_dt$position), # Cell texts |
| 237 | popover = spec_popover( |
| 238 | content = popover_dt$position, |
| 239 | title = NULL, # title will add a Title Panel on top |
| 240 | position = popover_dt$position |
| 241 | )) |
| 242 | kable(popover_dt, "html", escape = FALSE) %>% |
| 243 | kable_styling("striped", full_width = FALSE) |
| 244 | ``` |
| 245 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 246 | ## 链接 |
| 247 | 你可以给文字添加一个链接`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 Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 248 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 249 | ## 同时使用`kableExtra`和`formattable` |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 250 | 如果你也喜欢[`formattable`](https://github.com/renkun-ken/formattable)的话,你其实可以将`formattable`和`kableExtra`用在一起,灰常酷炫。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 251 | ```{r, message = FALSE, warning=FALSE} |
| 252 | library(formattable) |
| 253 | mtcars[1:5, 1:4] %>% |
| 254 | mutate( |
| 255 | car = row.names(.), |
| 256 | mpg = color_tile("white", "orange")(mpg), |
| 257 | cyl = cell_spec(cyl, "html", angle = (1:5)*60, |
| 258 | background = "red", color = "white", align = "center"), |
| 259 | disp = ifelse(disp > 200, |
| 260 | cell_spec(disp, "html", color = "red", bold = T), |
| 261 | cell_spec(disp, "html", color = "green", italic = T)), |
| 262 | hp = color_bar("lightgreen")(hp) |
| 263 | ) %>% |
| 264 | select(car, everything()) %>% |
| 265 | kable("html", escape = F) %>% |
| 266 | kable_styling("hover", full_width = F) %>% |
| 267 | column_spec(5, width = "3cm") %>% |
| 268 | add_header_above(c(" ", "Hello" = 2, "World" = 2)) |
| 269 | ``` |
| 270 | |
| 271 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 272 | # 行组和列组 |
| 273 | ## 列组 |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 274 | 我们在Word里做表格时,要想表示两个列同属一个分类,我们会在这两列的上面再加一行,画条横线,写上名字。基本上`add_header_above`就是被设计来做这事的。在使用这个方程时,你需要给他一个**`named vector`**(划重点)。这个`named vector`的本身数值是所有列的 span值,而具体的文字则在names里(没看懂我在说啥的,请参考下面的例子)。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 275 | ```{r} |
| 276 | kable(dt, "html") %>% |
| 277 | kable_styling("striped") %>% |
| 278 | add_header_above(c(" " = 1, "Group 1" = 2, "Group 2" = 2, "Group 3" = 2)) |
| 279 | ``` |
| 280 | |
Hao Zhu | 9ac3e38 | 2018-04-12 18:56:32 -0400 | [diff] [blame] | 281 | 事实上,你甚至可以一层一层继续往上加下去。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 282 | ```{r} |
| 283 | kable(dt, "html") %>% |
| 284 | kable_styling(c("striped", "bordered")) %>% |
| 285 | add_header_above(c(" ", "Group 1" = 2, "Group 2" = 2, "Group 3" = 2)) %>% |
| 286 | add_header_above(c(" ", "Group 4" = 4, "Group 5" = 2)) %>% |
| 287 | add_header_above(c(" ", "Group 6" = 6)) |
| 288 | ``` |
| 289 | |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 290 | ## 行组 |
| 291 | 我们一般做表格时,想表示几行同属一类一般有两种方式,其一是新插入一行大类的名称,然后再给那几行小的加上缩进。其二是在左边再加上一列,通过合并相印的行来表示所属的意思。相对应的,在`kableExtra`里,第一种方法可以用`group_rows`实现,而第二种则可以用`collapse_row`。 |
| 292 | |
| 293 | ### `group_rows` |
| 294 | 我们先说`group_rows`,请看下面这个例子。 |
| 295 | |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 296 | ```{r} |
| 297 | kable(mtcars[1:10, 1:6], "html", caption = "Group Rows") %>% |
| 298 | kable_styling("striped", full_width = F) %>% |
| 299 | group_rows("Group 1", 4, 7) %>% |
| 300 | group_rows("Group 2", 8, 10) |
| 301 | ``` |
| 302 | |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 303 | 另一种使用`group_rows`的方法是提供一个目录,用法和`add_header_above`相同。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 304 | ```{r, eval = F} |
| 305 | # Not evaluated. This example generates the same table as above. |
| 306 | kable(mtcars[1:10, 1:6], "html", caption = "Group Rows") %>% |
| 307 | kable_styling("striped", full_width = F) %>% |
| 308 | group_rows(index = c(" " = 3, "Group 1" = 4, "Group 2" = 3)) |
| 309 | ``` |
| 310 | |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 311 | 如果你熟悉CSS,你可以自己定义标签行的样式。 |
| 312 | |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 313 | ```{r} |
| 314 | kable(dt, "html") %>% |
| 315 | kable_styling("striped", full_width = F) %>% |
| 316 | group_rows("Group 1", 3, 5, label_row_css = "background-color: #666; color: #fff;") |
| 317 | ``` |
| 318 | |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 319 | ### 行的缩进 |
| 320 | 有时候只添加缩进就可以变的很有用,这时候你需要`add_indent`。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 321 | ```{r} |
| 322 | kable(dt, "html") %>% |
| 323 | kable_styling("striped", full_width = F) %>% |
| 324 | add_indent(c(1, 3, 5)) |
| 325 | ``` |
| 326 | |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 327 | ### 合并行 |
| 328 | `collapse_rows` 做的就是我们之前说的第二种在表格内表示所属关系的方法。请看下面的例子,第一二两列所有重复的内容都被自动合并了。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 329 | |
| 330 | ```{r} |
| 331 | collapse_rows_dt <- data.frame(C1 = c(rep("a", 10), rep("b", 5)), |
| 332 | C2 = c(rep("c", 7), rep("d", 3), rep("c", 2), rep("d", 3)), |
| 333 | C3 = 1:15, |
| 334 | C4 = sample(c(0,1), 15, replace = TRUE)) |
| 335 | kable(collapse_rows_dt, "html", align = "c") %>% |
| 336 | kable_styling(full_width = F) %>% |
| 337 | column_spec(1, bold = T) %>% |
| 338 | collapse_rows(columns = 1:2) |
| 339 | ``` |
| 340 | |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 341 | # 表格注脚 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 342 | |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 343 | 给表格添加注脚也是一个很常见的操作。在`kableExtra`里对应的是`footnote`方程。在这里,你可以使用四套编号体系:无编号`general`,数字`number`,字母`alphabet`和特殊符号`symbol`。注意,特殊符号我只定义了20个,因为一般你给表格加的注脚也不会有那么多。正如下面这个例子,你可以选择只用其中一种或者同时使用几种。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 344 | |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 345 | ```{r} |
| 346 | kable(dt, "html", align = "c") %>% |
| 347 | kable_styling(full_width = F) %>% |
| 348 | footnote(general = "Here is a general comments of the table. ", |
| 349 | number = c("Footnote 1; ", "Footnote 2; "), |
| 350 | alphabet = c("Footnote A; ", "Footnote B; "), |
| 351 | symbol = c("Footnote Symbol 1; ", "Footnote Symbol 2") |
| 352 | ) |
| 353 | ``` |
| 354 | |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 355 | 要是想要修改每一类的标题的话,你可以使用那些`***_title`变量. 你还可以通过 `footnote_order`来更改他们的顺序. 你甚至可以通过`footnote_as_chunk`,让备注们以一个段落的方式显示. |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 356 | |
| 357 | ```{r} |
| 358 | kable(dt, "html", align = "c") %>% |
| 359 | kable_styling(full_width = F) %>% |
| 360 | footnote(general = "Here is a general comments of the table. ", |
| 361 | number = c("Footnote 1; ", "Footnote 2; "), |
| 362 | alphabet = c("Footnote A; ", "Footnote B; "), |
| 363 | symbol = c("Footnote Symbol 1; ", "Footnote Symbol 2"), |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 364 | general_title = "备注: ", number_title = "备注233: ", |
| 365 | alphabet_title = "备注666: ", symbol_title = "备注888: ", |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 366 | footnote_as_chunk = T |
| 367 | ) |
| 368 | ``` |
| 369 | |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 370 | 若是想在表格内部添加注释的小字的话,你需要使用那些`footnote_mark_***()`方程. 和 `cell_spec`一样,你需要告诉他们你想要的格式(在今后的版本里你不需要了)同时在使用`kable`的时候往里加上`escape=F`。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 371 | |
| 372 | ```{r} |
| 373 | dt_footnote <- dt |
| 374 | names(dt_footnote)[2] <- paste0(names(dt_footnote)[2], |
| 375 | footnote_marker_symbol(1)) |
| 376 | row.names(dt_footnote)[4] <- paste0(row.names(dt_footnote)[4], |
| 377 | footnote_marker_alphabet(1)) |
| 378 | kable(dt_footnote, "html", align = "c", |
| 379 | # Remember this escape = F |
| 380 | escape = F) %>% |
| 381 | kable_styling(full_width = F) %>% |
| 382 | footnote(alphabet = "Footnote A; ", |
| 383 | symbol = "Footnote Symbol 1; ", |
| 384 | alphabet_title = "Type II: ", symbol_title = "Type III: ", |
| 385 | footnote_as_chunk = T) |
| 386 | ``` |
| 387 | |
Hao Zhu | 6f2a017 | 2018-04-13 17:03:40 -0400 | [diff] [blame] | 388 | # HTML独占功能 |
| 389 | ## 框住你的表格 |
| 390 | 若你的表格过大而你又不想随便缩字体大小,你可以用`scroll_box`把它放进一个盒子,这样用户可以自己选择想看的位置。下面的例子里我同时定义了盒子的高度和宽度,但你其实可以根据你的需求,只定义其中一个。需要注意的是,如果你同时需要打印这个表格,那你最好不要使用这个`scroll_box`。因为在打印的时候,被打印的将不会是整个表格,而会是到时候你屏幕上显示的部分。 |
Hao Zhu | 5e4dd50 | 2018-04-05 12:01:58 -0400 | [diff] [blame] | 391 | |
| 392 | ```{r} |
| 393 | kable(cbind(mtcars, mtcars), "html") %>% |
| 394 | kable_styling() %>% |
| 395 | scroll_box(width = "500px", height = "200px") |
| 396 | ``` |