How to build tables with gt

In publications, tables are extremely important to compare individual values, while plots are for showing traces or patterns. The gt package, can generate quality tables in R. Here I am going to show you a single line of code in order to produce a table. In addition the complexity of our code will be increased by adding a special design to our table, such as changes in fonts, in colors and footnotes. We will go ahead and we will use the the same data-set from the Basic Data Wrangling blog content.

Downloading Data

Install Packages and Loading Libraries

First step is to install packages either from CRAN, Bioconductor or from Github and to load the libraries.

library(data.table)
library(dplyr)
library(tidyverse)
library(plyr)
library(scales)
library(tidyquant)
library(gt)

Importing Data

Navigate your directory to your folder where you have saved the data set.

filename <- "~/Documents/MyWebPage/content/blog/example/Encode_HMM_data.txt"

Now we will go ahead to import our data set using the fread() function.

my_data <- fread(filename)

Then you need to polish your dataset and split into a dataframe by chromosome and type with ddply() function from plyr package.

colnames(my_data)[1:4] <- c("chrom","start","stop","type")
my_data <- my_data[,c(1:4)] #Keeping only the columns 1 to 4
my_data$type <- gsub('[[:digit:]]+_','',my_data$type) #removing the numbers and underscores from our type column
my_data2 <- ddply(my_data, .(type, chrom), summarise , no = length(type))
glimpse(my_data2)
## Rows: 276
## Columns: 3
## $ type  <chr> "Active_Promoter", "Active_Promoter", "Active_Promoter", "Active…
## $ chrom <chr> "chr1", "chr10", "chr11", "chr12", "chr13", "chr14", "chr15", "c…
## $ no    <int> 1497, 596, 759, 788, 323, 498, 492, 668, 901, 243, 1085, 1011, 3…

Pivot_wider

pivot_wider() makes the data-set wider and is often utilized to tidy long data sets and required for the purpose of creating tables.

my_data_final <- my_data2 %>% group_by(type) %>% 
  mutate(prop = no/sum(no)) %>% 
  ungroup() %>% 
  pivot_wider(
    id_cols = type,
    names_from = chrom,
    values_from = prop
  )
head(my_data_final)
## # A tibble: 6 × 24
##   type      chr1   chr10   chr11   chr12   chr13   chr14   chr15   chr16   chr17
##   <chr>    <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>   <dbl>
## 1 Activ… 0.00262 1.04e-3 1.33e-3 1.38e-3 5.65e-4 8.72e-4 8.61e-4 1.17e-3 1.58e-3
## 2 Heter… 0.0118  6.57e-3 6.95e-3 6.37e-3 3.53e-3 3.91e-3 4.35e-3 3.63e-3 4.44e-3
## 3 Insul… 0.00542 2.73e-3 3.16e-3 2.78e-3 1.36e-3 1.89e-3 2.02e-3 1.84e-3 2.20e-3
## 4 Poise… 0.00121 4.06e-4 4.83e-4 4.74e-4 2.26e-4 2.94e-4 3.22e-4 2.49e-4 5.09e-4
## 5 Repet… 0.00209 1.26e-3 1.35e-3 1.09e-3 5.51e-4 6.37e-4 5.74e-4 1.11e-3 6.20e-4
## 6 Repre… 0.00511 2.31e-3 3.08e-3 2.10e-3 1.04e-3 1.20e-3 1.55e-3 1.18e-3 1.85e-3
## # … with 14 more variables: chr18 <dbl>, chr19 <dbl>, chr2 <dbl>, chr20 <dbl>,
## #   chr21 <dbl>, chr22 <dbl>, chr3 <dbl>, chr4 <dbl>, chr5 <dbl>, chr6 <dbl>,
## #   chr7 <dbl>, chr8 <dbl>, chr9 <dbl>, chrX <dbl>

Data Wrangling

Our data frame is almost ready to be converted into a table. However, we need a bit further to polish our data in order to add a heatmap to our cells illustrating differences in the range of specific values for Chr19. Below I am showing a simple way of doing this using the function order.

my_data_final <- my_data_final[order(my_data_final[,12],decreasing = TRUE),]

Create a table

Finally we are ready to convert our dataset into a table by running a single line of code.

table_gt <- my_data_final %>% gt()
table_gt
type chr1 chr10 chr11 chr12 chr13 chr14 chr15 chr16 chr17 chr18 chr19 chr2 chr20 chr21 chr22 chr3 chr4 chr5 chr6 chr7 chr8 chr9 chrX
Weak_Enhancer 0.029892936 0.0151101185 0.0148213232 0.0158259807 0.0082350408 0.0106346670 0.0111212433 0.010445637 0.0137921619 0.0068190689 0.0097840336 0.0259268140 0.0080057549 3.372779e-03 0.0062047226 0.0213270930 0.0137274018 0.0164980861 0.020259426 0.0159064933 0.0136836449 0.0126579841 0.0085098339
Weak_Txn 0.013753656 0.0069678422 0.0066807972 0.0071761249 0.0035880624 0.0050985492 0.0053295854 0.005362841 0.0068348214 0.0030069713 0.0052910794 0.0117390901 0.0035110504 1.449227e-03 0.0031452430 0.0095162417 0.0064077544 0.0073914086 0.008735619 0.0076644514 0.0057794059 0.0060244443 0.0036143165
Strong_Enhancer 0.010053576 0.0053593401 0.0051160519 0.0061277105 0.0024678868 0.0043476815 0.0043494318 0.004267169 0.0055973774 0.0025308967 0.0041866563 0.0089263992 0.0030489779 1.309205e-03 0.0027409296 0.0072461358 0.0043196771 0.0058616688 0.007309146 0.0054661068 0.0046067221 0.0043756859 0.0025606514
Weak_Promoter 0.006272983 0.0026411640 0.0029247084 0.0031557447 0.0013722151 0.0019988133 0.0020688243 0.002455635 0.0032310065 0.0010291613 0.0033080185 0.0045052062 0.0014982348 6.791064e-04 0.0012864517 0.0037280844 0.0024521344 0.0030244741 0.003670325 0.0031732474 0.0024661366 0.0025904060 0.0018412886
Heterochrom/lo 0.011802100 0.0065705299 0.0069520897 0.0063674981 0.0035338039 0.0039101129 0.0043459312 0.003630069 0.0044439466 0.0032677622 0.0032065026 0.0112490133 0.0034830460 1.321457e-03 0.0020023139 0.0089859085 0.0067893142 0.0074421666 0.007976000 0.0069013318 0.0063394937 0.0057181463 0.0052280695
Txn_Elongation 0.004344181 0.0020495713 0.0021370850 0.0025133940 0.0011376783 0.0016592601 0.0018272864 0.001995313 0.0024363819 0.0009328962 0.0019410543 0.0038050964 0.0012321931 4.533211e-04 0.0010466641 0.0030437271 0.0019743095 0.0025816547 0.002446884 0.0026061585 0.0015997508 0.0019900619 0.0006441010
Insulator 0.005422350 0.0027251772 0.0031627458 0.0027759351 0.0013634637 0.0018850455 0.0020233172 0.001841289 0.0022035954 0.0013739654 0.0019305526 0.0048097539 0.0015174879 5.443353e-04 0.0010414132 0.0037665904 0.0028774510 0.0030804829 0.003190750 0.0030244741 0.0026936722 0.0026044082 0.0023646207
Active_Promoter 0.002620161 0.0010431635 0.0013284582 0.0013792162 0.0005653386 0.0008716366 0.0008611350 0.001169183 0.0015769972 0.0004253167 0.0018990477 0.0017695274 0.0006493518 2.992969e-04 0.0006353496 0.0014754813 0.0008961405 0.0012391942 0.001557744 0.0012899522 0.0010256608 0.0011061734 0.0010571657
Txn_Transition 0.002753182 0.0012777003 0.0013984692 0.0015314901 0.0005373342 0.0009521492 0.0011131745 0.001489483 0.0016557595 0.0004830757 0.0012987036 0.0020968287 0.0009346465 3.097986e-04 0.0007771218 0.0018867958 0.0010519149 0.0015017354 0.001410721 0.0014859829 0.0009854045 0.0011936871 0.0002765433
Repressed 0.005114302 0.0023051113 0.0030822331 0.0021020795 0.0010379127 0.0011989379 0.0015542436 0.001183185 0.0018535405 0.0011166750 0.0008996410 0.0041201458 0.0014474769 3.518051e-04 0.0007351152 0.0029124565 0.0017240202 0.0021545877 0.002789937 0.0019585570 0.0019883117 0.0021878429 0.0007841229
Repetitive/CNV 0.002088077 0.0012619478 0.0013512118 0.0010886706 0.0005513364 0.0006370999 0.0005740900 0.001114925 0.0006195971 0.0004235664 0.0008943902 0.0016365065 0.0006791064 5.688392e-04 0.0003203002 0.0014544780 0.0014019698 0.0014159720 0.001030912 0.0015839983 0.0013582129 0.0013529621 0.0013687145
Poised_Promoter 0.001214690 0.0004060637 0.0004830757 0.0004743244 0.0002257854 0.0002940461 0.0003220505 0.000248539 0.0005093298 0.0001610252 0.0002730428 0.0008016257 0.0002467887 6.651043e-05 0.0001872794 0.0004970779 0.0004060637 0.0004410691 0.000612596 0.0004323178 0.0003658073 0.0004200658 0.0001225192

Table Options

Our table is generated, however it needs further customization. Few finer details such as tab style, font and colors can be changed using the opt_xxx() and tab_options() functions. In addition you can also tweak values in the data_frame using the fmt_number() function. In our dataset due high amount of decimals we restricted down to five decimals for each of the values.

table_gt_final <- table_gt %>%  opt_all_caps() %>% 
  opt_table_font(
    font = list(
      google_font("Lato"),
      default_fonts()
    )
  ) %>% 
  opt_row_striping() %>% 
  tab_options(
    row.striping.background_color = "#fafafa",
    table_body.hlines.color = "#f6f7f7",
    source_notes.font.size = 12,
    table.font.size = 16,
    table.width = px(700),
    heading.align = "left",
    heading.title.font.size = 24,
    table.border.top.color = "transparent",
    table.border.top.width = px(3),
    data_row.padding = px(7)
  ) %>% fmt_number(
    columns = 2:24,
    decimals = 5,
  use_seps = TRUE
  ) %>% 
  tab_style(style = list(
    cell_text(style = "italic")),
    locations = cells_body(
      columns = c(type)
    ))
table_gt_final
type chr1 chr10 chr11 chr12 chr13 chr14 chr15 chr16 chr17 chr18 chr19 chr2 chr20 chr21 chr22 chr3 chr4 chr5 chr6 chr7 chr8 chr9 chrX
Weak_Enhancer 0.02989 0.01511 0.01482 0.01583 0.00824 0.01063 0.01112 0.01045 0.01379 0.00682 0.00978 0.02593 0.00801 0.00337 0.00620 0.02133 0.01373 0.01650 0.02026 0.01591 0.01368 0.01266 0.00851
Weak_Txn 0.01375 0.00697 0.00668 0.00718 0.00359 0.00510 0.00533 0.00536 0.00683 0.00301 0.00529 0.01174 0.00351 0.00145 0.00315 0.00952 0.00641 0.00739 0.00874 0.00766 0.00578 0.00602 0.00361
Strong_Enhancer 0.01005 0.00536 0.00512 0.00613 0.00247 0.00435 0.00435 0.00427 0.00560 0.00253 0.00419 0.00893 0.00305 0.00131 0.00274 0.00725 0.00432 0.00586 0.00731 0.00547 0.00461 0.00438 0.00256
Weak_Promoter 0.00627 0.00264 0.00292 0.00316 0.00137 0.00200 0.00207 0.00246 0.00323 0.00103 0.00331 0.00451 0.00150 0.00068 0.00129 0.00373 0.00245 0.00302 0.00367 0.00317 0.00247 0.00259 0.00184
Heterochrom/lo 0.01180 0.00657 0.00695 0.00637 0.00353 0.00391 0.00435 0.00363 0.00444 0.00327 0.00321 0.01125 0.00348 0.00132 0.00200 0.00899 0.00679 0.00744 0.00798 0.00690 0.00634 0.00572 0.00523
Txn_Elongation 0.00434 0.00205 0.00214 0.00251 0.00114 0.00166 0.00183 0.00200 0.00244 0.00093 0.00194 0.00381 0.00123 0.00045 0.00105 0.00304 0.00197 0.00258 0.00245 0.00261 0.00160 0.00199 0.00064
Insulator 0.00542 0.00273 0.00316 0.00278 0.00136 0.00189 0.00202 0.00184 0.00220 0.00137 0.00193 0.00481 0.00152 0.00054 0.00104 0.00377 0.00288 0.00308 0.00319 0.00302 0.00269 0.00260 0.00236
Active_Promoter 0.00262 0.00104 0.00133 0.00138 0.00057 0.00087 0.00086 0.00117 0.00158 0.00043 0.00190 0.00177 0.00065 0.00030 0.00064 0.00148 0.00090 0.00124 0.00156 0.00129 0.00103 0.00111 0.00106
Txn_Transition 0.00275 0.00128 0.00140 0.00153 0.00054 0.00095 0.00111 0.00149 0.00166 0.00048 0.00130 0.00210 0.00093 0.00031 0.00078 0.00189 0.00105 0.00150 0.00141 0.00149 0.00099 0.00119 0.00028
Repressed 0.00511 0.00231 0.00308 0.00210 0.00104 0.00120 0.00155 0.00118 0.00185 0.00112 0.00090 0.00412 0.00145 0.00035 0.00074 0.00291 0.00172 0.00215 0.00279 0.00196 0.00199 0.00219 0.00078
Repetitive/CNV 0.00209 0.00126 0.00135 0.00109 0.00055 0.00064 0.00057 0.00111 0.00062 0.00042 0.00089 0.00164 0.00068 0.00057 0.00032 0.00145 0.00140 0.00142 0.00103 0.00158 0.00136 0.00135 0.00137
Poised_Promoter 0.00121 0.00041 0.00048 0.00047 0.00023 0.00029 0.00032 0.00025 0.00051 0.00016 0.00027 0.00080 0.00025 0.00007 0.00019 0.00050 0.00041 0.00044 0.00061 0.00043 0.00037 0.00042 0.00012

Adding some style and colour

Our table has already got a better design, however as we mentioned above we will add a heatmap to our cells with a color showing the differences in numneric values (min and max) for chr19. To do that we need to create a palette and apply conditional colouring using the function data_color().

min_Chr19 <- min(my_data_final$chr19)
max_Chr19 <- max(my_data_final$chr19)
palette <- col_numeric(c("#FEF0D9", "#990000"), domain = c(min_Chr19, max_Chr19), alpha = 0.75)
               
table_gt_final %>% data_color(columns = c(chr19),
               colors = palette) 
type chr1 chr10 chr11 chr12 chr13 chr14 chr15 chr16 chr17 chr18 chr19 chr2 chr20 chr21 chr22 chr3 chr4 chr5 chr6 chr7 chr8 chr9 chrX
Weak_Enhancer 0.02989 0.01511 0.01482 0.01583 0.00824 0.01063 0.01112 0.01045 0.01379 0.00682 0.00978 0.02593 0.00801 0.00337 0.00620 0.02133 0.01373 0.01650 0.02026 0.01591 0.01368 0.01266 0.00851
Weak_Txn 0.01375 0.00697 0.00668 0.00718 0.00359 0.00510 0.00533 0.00536 0.00683 0.00301 0.00529 0.01174 0.00351 0.00145 0.00315 0.00952 0.00641 0.00739 0.00874 0.00766 0.00578 0.00602 0.00361
Strong_Enhancer 0.01005 0.00536 0.00512 0.00613 0.00247 0.00435 0.00435 0.00427 0.00560 0.00253 0.00419 0.00893 0.00305 0.00131 0.00274 0.00725 0.00432 0.00586 0.00731 0.00547 0.00461 0.00438 0.00256
Weak_Promoter 0.00627 0.00264 0.00292 0.00316 0.00137 0.00200 0.00207 0.00246 0.00323 0.00103 0.00331 0.00451 0.00150 0.00068 0.00129 0.00373 0.00245 0.00302 0.00367 0.00317 0.00247 0.00259 0.00184
Heterochrom/lo 0.01180 0.00657 0.00695 0.00637 0.00353 0.00391 0.00435 0.00363 0.00444 0.00327 0.00321 0.01125 0.00348 0.00132 0.00200 0.00899 0.00679 0.00744 0.00798 0.00690 0.00634 0.00572 0.00523
Txn_Elongation 0.00434 0.00205 0.00214 0.00251 0.00114 0.00166 0.00183 0.00200 0.00244 0.00093 0.00194 0.00381 0.00123 0.00045 0.00105 0.00304 0.00197 0.00258 0.00245 0.00261 0.00160 0.00199 0.00064
Insulator 0.00542 0.00273 0.00316 0.00278 0.00136 0.00189 0.00202 0.00184 0.00220 0.00137 0.00193 0.00481 0.00152 0.00054 0.00104 0.00377 0.00288 0.00308 0.00319 0.00302 0.00269 0.00260 0.00236
Active_Promoter 0.00262 0.00104 0.00133 0.00138 0.00057 0.00087 0.00086 0.00117 0.00158 0.00043 0.00190 0.00177 0.00065 0.00030 0.00064 0.00148 0.00090 0.00124 0.00156 0.00129 0.00103 0.00111 0.00106
Txn_Transition 0.00275 0.00128 0.00140 0.00153 0.00054 0.00095 0.00111 0.00149 0.00166 0.00048 0.00130 0.00210 0.00093 0.00031 0.00078 0.00189 0.00105 0.00150 0.00141 0.00149 0.00099 0.00119 0.00028
Repressed 0.00511 0.00231 0.00308 0.00210 0.00104 0.00120 0.00155 0.00118 0.00185 0.00112 0.00090 0.00412 0.00145 0.00035 0.00074 0.00291 0.00172 0.00215 0.00279 0.00196 0.00199 0.00219 0.00078
Repetitive/CNV 0.00209 0.00126 0.00135 0.00109 0.00055 0.00064 0.00057 0.00111 0.00062 0.00042 0.00089 0.00164 0.00068 0.00057 0.00032 0.00145 0.00140 0.00142 0.00103 0.00158 0.00136 0.00135 0.00137
Poised_Promoter 0.00121 0.00041 0.00048 0.00047 0.00023 0.00029 0.00032 0.00025 0.00051 0.00016 0.00027 0.00080 0.00025 0.00007 0.00019 0.00050 0.00041 0.00044 0.00061 0.00043 0.00037 0.00042 0.00012

Adding Footnotes

Footnotes are important for explanatory (content) notes or copyright permission. Therefore footnotes could also be significant for academic/scientific tables with more complex data-sets. Footnotes are usually placed at the bottom of the table. One way to add a footnote with gt package is to use the function tab_footnote(). In addition you have the option to modify the set of footnote marks with the function opt_footnote_marks. The valid keywords are : numbers (for numeric marks), letters (for alphabetic marks), standard (for traditional symbol marks) and extended (which adds more symbols to the standard set.) For our table we have used the numbers keyword as an option for footnote mark.

table_gt_final2 <- table_gt_final %>% data_color(columns = c(chr19),
               colors = palette) %>% 
               tab_footnote(
               footnote = md("Enhancers"),
               locations = cells_body(
               columns = c("type"),
               rows = c(1,3))) %>% 
  tab_footnote(footnote = md("Promoters"),
               locations = cells_body(
                 columns = c("type"),
                 rows = c(4,8,12)
                 )) %>% opt_footnote_marks(marks = "numbers")
table_gt_final2
type chr1 chr10 chr11 chr12 chr13 chr14 chr15 chr16 chr17 chr18 chr19 chr2 chr20 chr21 chr22 chr3 chr4 chr5 chr6 chr7 chr8 chr9 chrX
Weak_Enhancer1 0.02989 0.01511 0.01482 0.01583 0.00824 0.01063 0.01112 0.01045 0.01379 0.00682 0.00978 0.02593 0.00801 0.00337 0.00620 0.02133 0.01373 0.01650 0.02026 0.01591 0.01368 0.01266 0.00851
Weak_Txn 0.01375 0.00697 0.00668 0.00718 0.00359 0.00510 0.00533 0.00536 0.00683 0.00301 0.00529 0.01174 0.00351 0.00145 0.00315 0.00952 0.00641 0.00739 0.00874 0.00766 0.00578 0.00602 0.00361
Strong_Enhancer1 0.01005 0.00536 0.00512 0.00613 0.00247 0.00435 0.00435 0.00427 0.00560 0.00253 0.00419 0.00893 0.00305 0.00131 0.00274 0.00725 0.00432 0.00586 0.00731 0.00547 0.00461 0.00438 0.00256
Weak_Promoter2 0.00627 0.00264 0.00292 0.00316 0.00137 0.00200 0.00207 0.00246 0.00323 0.00103 0.00331 0.00451 0.00150 0.00068 0.00129 0.00373 0.00245 0.00302 0.00367 0.00317 0.00247 0.00259 0.00184
Heterochrom/lo 0.01180 0.00657 0.00695 0.00637 0.00353 0.00391 0.00435 0.00363 0.00444 0.00327 0.00321 0.01125 0.00348 0.00132 0.00200 0.00899 0.00679 0.00744 0.00798 0.00690 0.00634 0.00572 0.00523
Txn_Elongation 0.00434 0.00205 0.00214 0.00251 0.00114 0.00166 0.00183 0.00200 0.00244 0.00093 0.00194 0.00381 0.00123 0.00045 0.00105 0.00304 0.00197 0.00258 0.00245 0.00261 0.00160 0.00199 0.00064
Insulator 0.00542 0.00273 0.00316 0.00278 0.00136 0.00189 0.00202 0.00184 0.00220 0.00137 0.00193 0.00481 0.00152 0.00054 0.00104 0.00377 0.00288 0.00308 0.00319 0.00302 0.00269 0.00260 0.00236
Active_Promoter2 0.00262 0.00104 0.00133 0.00138 0.00057 0.00087 0.00086 0.00117 0.00158 0.00043 0.00190 0.00177 0.00065 0.00030 0.00064 0.00148 0.00090 0.00124 0.00156 0.00129 0.00103 0.00111 0.00106
Txn_Transition 0.00275 0.00128 0.00140 0.00153 0.00054 0.00095 0.00111 0.00149 0.00166 0.00048 0.00130 0.00210 0.00093 0.00031 0.00078 0.00189 0.00105 0.00150 0.00141 0.00149 0.00099 0.00119 0.00028
Repressed 0.00511 0.00231 0.00308 0.00210 0.00104 0.00120 0.00155 0.00118 0.00185 0.00112 0.00090 0.00412 0.00145 0.00035 0.00074 0.00291 0.00172 0.00215 0.00279 0.00196 0.00199 0.00219 0.00078
Repetitive/CNV 0.00209 0.00126 0.00135 0.00109 0.00055 0.00064 0.00057 0.00111 0.00062 0.00042 0.00089 0.00164 0.00068 0.00057 0.00032 0.00145 0.00140 0.00142 0.00103 0.00158 0.00136 0.00135 0.00137
Poised_Promoter2 0.00121 0.00041 0.00048 0.00047 0.00023 0.00029 0.00032 0.00025 0.00051 0.00016 0.00027 0.00080 0.00025 0.00007 0.00019 0.00050 0.00041 0.00044 0.00061 0.00043 0.00037 0.00042 0.00012
1 Enhancers
2 Promoters

Save the table

And now we are ready to save our table. The gtsave() function makes it easy to save a gt table to a file in a different format such as (HTML, PDF, PNG, LaTeX, or RTF file) via the {webshot} package.

webshot::install_phantomjs() 
## It seems that the version of `phantomjs` installed is greater than or equal to the requested version.To install the requested version or downgrade to another version, use `force = TRUE`.
table <- table_gt_final2 %>% gtsave("~/Documents/MyWebPage/content/blog/example/table.pdf")

Feel free to download the files from github:

Download FILES

Previous