How to create an interactive table in R

0
16


Interactive tables with searching and sorting can be a nice way of exploring data. And sometimes, you might want to share that data with other people — including text-only data like a .

But when that data includes a column with fairly long entries, that column may not fit well in a table the width of your screen. This can be especially tricky when not every row includes the very-wide column. For example, a table of questionnaire results where one field is “Do you have any additional comments?” Not everyone may.

That’s where a table with expandable rows can come in handy. At the NICAR data journalism conference earlier this year, I posted a form so speakers (and other attendees) could submit links to session presentations. Some people added additional comments; others didn’t. Showing that column by default would waste a lot of screen real estate.

Instead, that comment field displays in  only if a user clicks on the expand-row icon. Not every row can be expanded with a clickable icon at the left of the Topic name because not every row has data in that field, as you can (hopefully) see in the screenshot below.

Sharon Machlis, IDG

R-generated table with some rows that are expandable to display more information. 

Let’s see how to make a table like this. 

Sharon Machlis, IDG

Default reactable table with no search box and column displaying HTML code instead of HTML as HTML.

In the next code group, I add a search box to the table and little arrow icons showing that the columns are sortable.

reactable(nicar, searchable = TRUE, showSortable = TRUE, showSortIcon = TRUE)

To tell reactable to display the Resource column as HTML, I use the columns argument and a list where colDef sets the attributes of one or more columns. Below, I’m setting html = true for the Resource column so it displays as HTML, and I’m also making that column resizable.

reactable(nicar, searchable = TRUE, showSortable = TRUE, showSortIcon = TRUE,
columns = list(
Resource = colDef(html = TRUE, resizable = TRUE)
)
)

To tell reactable not to display the Comments column in the main table, I set colDef(show = FALSE).

reactable(nicar, searchable = TRUE, showSortable = TRUE, showSortIcon = TRUE,
columns = list(
Resource = colDef(html = TRUE, resizable = TRUE),
Comments = colDef(show = FALSE)
)
)

So far so good.

Sharon Machlis, IDG

Reactable table tweaked to include a search box, one column displaying as HTML, and another column not showing in the main table.

Add reactable code for expandable rows

The next step is adding the expandable rows, and that’s a bit more complex:

# Function needed according to Greg Lin, creator of reactable
html <- function(x, inline = FALSE) {
container <- if (inline) htmltools::span else htmltools::div
container(dangerouslySetInnerHTML = list("__html" = x))
}
reactable(nicar, searchable = TRUE, showSortable = TRUE,
columns = list(
Resource = colDef(html = TRUE, resizable = TRUE),
Comments = colDef(show = FALSE)
),
# if there exists a comment, make row expandable
details = function(index) {
if(nicar$Comments[index] != "") {
htmltools::tagList(
html(nicar$Comments[index])
)
}
}
)

I didn’t write this part myself; reactable creator Greg Lin wrote it. Honestly, I don’t understand what every line is doing. But it works! 

Sharon Machlis

A reactable table with expandable rows.

Will I remember this code the next time I want to make a table with expandable rows? No. Definitely not. But if I make an RStudio code snippet, I don’t have to remember it. It will always be just a couple of keystrokes away.

If you’re not familiar with RStudio code snippets at all, check out the for a full explainer. But here are the basics.  

Make an RStudio code snippet

Below is an image of my table code highlighting the variables for my data frame and column names, as well as changing the column definition from dollar sign notation to bracket notation (which works a lot better in snippets). Also — very important — I added a snippet title and indented every line of code with a starting tab. That’s a must!

Sharon Machlis, IDG

Code for my table with variables highlighted, column syntax changed to bracket notations, and snippet title and indentation added.

Then I just need to change each variable name to a generic snippet variable: 1 for the data frame, 2 for the column I want to display as HTML, and 3 for the expandable-row column. Note the variable syntax: ${number:variable_name}. These variables will make it easy for me to fill in actual variable names back in RStudio. 

snippet my_expandable_row	
html <- function(x, inline = FALSE) {
container <- if (inline) htmltools::span else htmltools::div
container(dangerouslySetInnerHTML = list("__html" = x))
}
reactable(${1:mydf}, searchable = TRUE, showSortable = TRUE,
columns = list(
${2:html_column} = colDef(html = TRUE, resizable = TRUE),
${3:expand_col} = colDef(show = FALSE)
),
details = function(index) {
if(${1:mydf}[['${3:expand_col}']][index] != "") {
htmltools::tagList(
html(${1:mydf}[['${3:expand_col}']][index])
)
}
}
)

You can copy and paste the snippet code above into your own RStudio snippets file using

usethis::edit_rstudio_snippets()

to open the snippets file in RStudio. Make sure the snippet code quotes are plain quotes and that each line is indented with a tab (not just spaces; a starting tab for each line of code is mandatory).

Now if you type the name of the snippet in an RStudio source R script file, it should expand to give you the code. You can then type the name of the first variable, hit tab, type the name of your second variable, and so on. Check out the video embedded in this article to see how this works. And enjoy your own interactive tables with expandable rows!

For more R tips, head to the 

Copyright © 2020 IDG Communications, Inc.

LEAVE A REPLY