Skip to contents

The functions in this package are built to mesh seamlessly with the {tidyverse} set of packages, created by Posit: https://posit.co/, particularly {gt} which gives R users the tools to create beautiful tables: https://gt.rstudio.com/

Introduction

Tables are an essential and often under-appreciated method of visualising data. Many data visualisation professionals eschew their usage as they are not considered visually engaging. However, they are often the ideal tool for the job. Many of us would do well to ask ourselves ‘Do I need these charts or should this be a table?’

You should consider using a table when:

  • You need to display precise values
  • You need to display multiple raw volumes and percentages in the same place
  • You want users to compare individual elements
  • Your data has multiple dimensions and plotting becomes convoluted
  • You’re slide-limited e.g. because need to provide an executive summary of complex data

Apart from using tables to display or communicate findings, it’s important to be aware of how tables can aid hypothesis generation, showing you where to dig next in the data mining process.

Tabular Data

We’ll use the example data frame which ships with {DisplayR} and the {tidyverse} to create some summary tables, then we’ll use {gt} and some {DisplayR} functions to create aesthetically-pleasing tables.

df <- DisplayR::disp_example

Let’s say we need to visualise volume - raw numbers and %, as well as sentiment counts for a categorical variable - in this case we’ll use topic. We can create a summary table like so:

(summary_table <- df %>%
  filter(!is.na(sentiment)) %>%
  count(topic, sentiment, name = "sent_n") %>%
  add_count(topic, wt = sent_n, name = "volume") %>%
  pivot_wider(names_from = sentiment, values_from = sent_n) %>%
  mutate(percent = round(volume / sum(volume) * 100, 2), .after = volume) %>%
  arrange(desc(volume))
)
#> # A tibble: 9 × 6
#>   topic                 volume percent negative neutral positive
#>   <chr>                  <int>   <dbl>    <int>   <int>    <int>
#> 1 Conversational AI       1559   31.2       412     784      363
#> 2 AI Ethics & Society      798   16.0       341     332      125
#> 3 AI-Powered Creativity    637   12.7       210     292      135
#> 4 Risks & Challenges       631   12.6       394     178       59
#> 5 AI Search                380    7.6       123     182       75
#> 6 Coding & Assistance      364    7.28      115     167       82
#> 7 AI Performance           280    5.6        58     122      100
#> 8 AI & Business            268    5.36       57     110      101
#> 9 AI & Security             82    1.64       24      45       13

We could use various means to visualise this table, let’s try a data table, which is fairly common. We’ll style it with bootstrap allow filtering at the top of the table.

DT::datatable(summary_table, style = "bootstrap", filter = "top")

Whilst functional, the table is lacking in visual appeal; it’s better used for exploring data internally than it is for communicating findings or including in a deck.

Despite making it clear which topic has the highest volume, it would require considerable mental work to figure out which topic had the highest proportion of positive or negative sentiment. We’re also lacking vital elements such as titles, subtitles, and captions; as well as additional flourishes such as icons which can bring the table to life. Let’s see how we could visualise the output with gt.

GT

library(gt)
(my_gt <- df %>%
  disp_gt(
    date_var = date,
    group_var = topic,
    sentiment_var = sentiment,
    sentiment_max_colours =
      list(
        "negative" = "#D83B01",
        "neutral" = "#FFB900",
        "positive" = "#107C10"
      ),
    time_unit = "day",
    table_title = "Topic Modelling Summary Table", source_note = "Data Source: xxx"
  ) %>%
  gt::cols_hide("Sentiment x Time")
)
#> Warning: Removed 1 row containing missing values or values outside the scale range
#> (`geom_col()`).
#> Warning: Removed 1 row containing missing values or values outside the scale range
#> (`geom_line()`).
Topic Modelling Summary Table
topic Volume Positive Neutral Negative Volume x Time
Conversational AI 1,559 23.3% 50.3% 26.4%
AI Ethics & Society 798 15.7% 41.6% 42.7%
AI-Powered Creativity 637 21.2% 45.8% 33.0%
Risks & Challenges 631 9.4% 28.2% 62.4%
AI Search 380 19.7% 47.9% 32.4%
Coding & Assistance 364 22.5% 45.9% 31.6%
AI Performance 280 35.7% 43.6% 20.7%
AI & Business 268 37.7% 41.0% 21.3%
AI & Security 82 15.9% 54.9% 29.3%
Total 4,999
Data Source: xxx

This table is preferable to me for multiple reason:

The gradient fill for the positive & negative columns make comparison easy. The Volume x Time charts are a nice addition, and allow us to compare the trends of multiple topics at a glance, whilst also keeping volume + sentiment information an eye movement away. The overall styling is just more pleasant than the Data Table.

*note, there is a Sentiment x Time chart which has been hidden from view, we’re still experimenting with which charts work/ don’t work for the default outputs.

One of the drawbacks with gt is that we cannot easily output to PowerPoint, step forward flextable

Flextable & Exporting to PowerPoint

The function will not include the Volume x Time chart, but we will get a nice gradient fill for the Positive + Negative columns which we can export to PowerPoint.

(my_ft <- df %>%
  disp_flextable(topic, sentiment))

Topic

Volume

Negative

Neutral

Positive

Conversational AI

1,559

26.4

50.3

23.3

AI Ethics & Society

798

42.7

41.6

15.7

AI-Powered Creativity

637

33.0

45.8

21.2

Risks & Challenges

631

62.4

28.2

9.4

AI Search

380

32.4

47.9

19.7

Coding & Assistance

364

31.6

45.9

22.5

AI Performance

280

20.7

43.6

35.7

AI & Business

268

21.3

41.0

37.7

AI & Security

82

29.3

54.9

15.9

Total

4,999

-

-

-

We can preview how this would look in powerpoint with:

print(my_ft, preview = "pptx")

Topic

Volume

Negative

Neutral

Positive

Conversational AI

1,559

26.4

50.3

23.3

AI Ethics & Society

798

42.7

41.6

15.7

AI-Powered Creativity

637

33.0

45.8

21.2

Risks & Challenges

631

62.4

28.2

9.4

AI Search

380

32.4

47.9

19.7

Coding & Assistance

364

31.6

45.9

22.5

AI Performance

280

20.7

43.6

35.7

AI & Business

268

21.3

41.0

37.7

AI & Security

82

29.3

54.9

15.9

Total

4,999

-

-

-