knitr::opts_chunk$set(echo = TRUE)
library(reactablefmtr) library(viridis) library(dplyr) library(stringr) library(purrr) library(nflfastR)
data_bars()
customization options| Parameter | Description | Default Value |
|:----------------------|:----------------------------------------------|:---------------------------------|
| data
| name of data set | NULL |
| text_position
| position of the values relative to bars | 'inside-end' |
| number_fmt
| the format of the values | NULL |
| fill_color
| color of the filled portion of the bars | '#15607A' |
| fill_color_ref
| column containing color assignments | NULL |
| fill_by
| column containing value assignments | NULL |
| fill_opacity
| opaqueness of the fill color | 1 |
| bias
| the spacing between colors | 1 |
| min_value
| the minimum value for the width of the bars | NULL (0) |
| max_value
| the maximum value for the width of the bars | NULL (max value of the column) |
| align_bars
| the alignment of the bars within the column | 'left' |
| bar_height
| the height of the bars | NULL |
| force_outside
| convert a range of values to 'outside-end' | NULL |
| text_size
| the size of the text | NULL |
| text_color
| the color of the text | 'black' |
| text_color_ref
| column containing text color assignments | NULL |
| brighten_text
| auto-adjust text color based on fill color | TRUE |
| brighten_text_color
| color of the auto-adjusted text color | 'white' |
| bold_text
| bold format text | FALSE |
| border_style
| the style of the border around the bars | NULL |
| border_width
| the width of the border around the bars | NULL |
| border_color
| the color of the border around the bars | NULL |
| icon
| add an icon to the bars | NULL |
| icon_ref
| column containing icon assignments | NULL |
| icon_size
| the size of the icons | NULL |
| icon_color
| the color of the icons | NULL |
| icon_color_ref
| column containing icon color assignments | NULL |
| img
| add an image to the bars | NULL |
| img_ref
| column containing image assignments | NULL |
| img_height
| the height of the images | NULL |
| img_width
| the width of the images | NULL |
| box_shadow
| add a box shadow around the bars | NULL |
| round_edges
| round the edges around the bars | FALSE |
| tooltip
| enable hover tooltip | FALSE |
| animation
| animation of color transitions on sort | 'width 1s ease' |
By default, the values are positioned on the "inside-end" of the filled bars:
data <- data.frame( Group = c("Red Group 1","Red Group 2","Red Group 3","Red Group 4","Red Group 5", "Blue Group 1","Blue Group 2","Blue Group 3","Blue Group 4","Blue Group 5", "Green Group 1","Green Group 2","Green Group 3","Green Group 4","Green Group 5"), Pct1 = c(.27, .82, .44, .68, .78, .74, .66, .33, .23, .20, .50, .55, .40, .70, .60), Pct2 = c(.33, .17, .87, .54, .37, .84, .72, .61, .48, .77, .21, .39, .60, .55, .81) ) reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, number_fmt = scales::percent) ) )
However, you can change the location of the values with text_position
. The available options are "inside-end" (default), "outside-base", "outside-end", "inside-base", "center", "above", or "none". Below is an example of "outside-base" which is the way the old version of data_bars()
displayed the values.
reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, text_position = "outside-base", number_fmt = scales::percent) ) )
Values positioned inside the base of the filled bars with "inside-base":
reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, text_position = "inside-base", number_fmt = scales::percent) ) )
Values positioned inside the end of the filled bars with "outside-end":
reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, text_position = "inside-end", number_fmt = scales::percent) ) )
Values positioned inside the center of the filled bars with "center":
reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, text_position = "center", number_fmt = scales::percent) ) )
Values positioned above the filled bars with "above":
reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, text_position = "above", number_fmt = scales::percent) ) )
Lastly, values can be hidden with "none":
reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, text_position = "none") ) )
If the values are difficult to see inside the bars since they are small relative to other values in the column, you can "force" them to show outside of the data bars by providing a range of values within force_outside
:
reactable( data, pagination = FALSE, defaultSortOrder = "desc", defaultSorted = "Pct2", defaultColDef = colDef( cell = data_bars(data, number_fmt = scales::percent, force_outside = c(0,0.4)) ) )
By default, the filled bars are aligned from left-to-right, but can be aligned from right-to-left by setting align_bars = "right"
:
reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, align_bars = "right", number_fmt = scales::percent) ) )
The same text positions outlined in the section above can be applied to right-aligned data bars. You can also mix and match alignments.
reactable( data, pagination = FALSE, columns = list( Pct1 = colDef( cell = data_bars(data, align_bars = "right", text_position = "inside-end", number_fmt = scales::percent) ), Pct2 = colDef( cell = data_bars(data, align_bars = "left", text_position = "inside-end", number_fmt = scales::percent) ) ) )
Box shadows can be added to the bars to create a "3-D" effect via box_shadow
.
reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, box_shadow = TRUE, number_fmt = scales::percent) ) )
The edges of the bars can be rounded by setting round_edges
to TRUE.
reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, round_edges = TRUE, number_fmt = scales::percent) ) )
Borders can be placed around the bars by setting the border properties within border_style
, border_color
, and border_width
:
reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, border_style = "solid", border_color = "gold", border_width = "2px", number_fmt = scales::percent) ) )
By default, the width of the filled data bars is equal to the maximum value within that particular column. In most cases, this is what we want to display, but sometimes it's better to extend the range. For example, in the percentages below, if we want to extend the width to show the values out of 100%, we could do so by setting the max_value
to 1:
reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, fill_color = viridis(5), background = "lightgrey", text_position = "inside-end", max_value = 1, number_fmt = scales::percent) ) )
Now when you look at the 82% value above, there is 18% empty space filled by the background showing that the value is out of 100% and not 82%.
The default height of the data bars is set to 19px but can be adjusted within bar_height
.
To increase the height of the bars, provide a numeric value greater than 19:
reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, bar_height = 35, number_fmt = scales::percent) ) )
To decrease the height of the bars, provide a numeric value less than 19:
reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, bar_height = 3, text_position = "outside-end", background = "transparent", number_fmt = scales::percent) ) )
You can now conditionally assign colors to rows based on values within another column with the fill_color_ref
argument. This allows you to assign colors to groups such as shown below:
data %>% mutate(color_pal = case_when( str_detect(Group, "Red") ~ "#FF3B28", str_detect(Group, "Blue") ~ "#006FEF", str_detect(Group, "Green") ~ "#3ABC0E", TRUE ~ "darkgrey" )) %>% reactable(., pagination = FALSE, defaultColDef = colDef( cell = data_bars(., fill_color_ref = "color_pal", text_position = "inside-end", background = "lightgrey", max_value = 1, number_fmt = scales::percent) ), columns = list(color_pal = colDef(show = FALSE) ## hide the color_pal column ) )
Or you can conditionally assign colors based on values:
data %>% mutate(color_pal = case_when( Pct1 >= .7 ~ "#FF3B28", TRUE ~ "darkgrey" )) %>% select(-Pct2) %>% reactable(., pagination = FALSE, defaultSorted = "Pct1", defaultSortOrder = "desc", defaultColDef = colDef( cell = data_bars(., fill_color_ref = "color_pal", text_position = "inside-end", background = "lightgrey", max_value = 1, number_fmt = scales::percent) ), columns = list(color_pal = colDef(show = FALSE) ) )
data_bars_gradient()
is now depreciated and has been replaced with the gradient
argument within data_bars()
. Set fill_gradient = TRUE
to change any multi-color palette to a left-to-right gradient to be used as the fill for the bars:
reactable( data, pagination = FALSE, defaultColDef = colDef( cell = data_bars(data, fill_color = c("#1efffd", "#1e20ff"), fill_gradient = TRUE, background = "lightgrey", max_value = 1, brighten_text = FALSE, text_color = "white", number_fmt = scales::percent) ) )
With fill_by
, you can apply data bars to a non-numeric column by referencing values contained within another column.
Note: this only works with columns of character-type, not for factors.
car_data <- MASS::Cars93 %>% filter(Type %in% c('Compact', 'Sporty', 'Van')) %>% select(c('Make', 'Type', 'MPG.city')) %>% mutate(Make = as.character(Make)) %>% tail(10) reactable( car_data, columns = list( Make = colDef( cell = data_bars(car_data, fill_by = "MPG.city") ) ) )
You are still able to control the position of the text relative to the bars with text_position
:
car_data <- MASS::Cars93 %>% filter(Type %in% c('Compact', 'Sporty', 'Van')) %>% select(c('Make', 'Type', 'MPG.city')) %>% mutate(Make = as.character(Make)) %>% tail(10) reactable( car_data, defaultSorted = "MPG.city", defaultSortOrder = "desc", columns = list( Make = colDef( cell = data_bars(car_data, fill_by = "MPG.city", text_position = "above") ) ) )
add_legend()
customization options| Parameter | Description | Default Value |
|:-------------|:-----------------------------------------|:---------------------------------|
| data
| name of dataset | NULL |
| col_name
| name of column containing numeric values | NULL |
| bins
| number of bins to be displayed | 5 |
| colors
| color palette | c('#15607A','#FFFFFF','#FA8C00') |
| bias
| opaqueness of color palette | 1 |
| labels
| show or hide value labels | TRUE |
| number_fmt
| the format of the values | NULL |
| title
| the title above the legend | NULL |
| footer
| the footer below the legend | NULL |
| align
| align to the left or right of the table | 'right' |
If you would like to add a legend below the table, you can do so by including add_legend()
. The two things you will need within add_legend()
, are the name of the column from which the legend is to be displayed for, and the color palette used within the table.
Since we used a custom color palette for the fill_color
of data_bars
in the example below, we will need to match that color palette within colors
of the legend.
Adding a legend is useful when using the fill_by
option in data_bars
since the values aren't directly displayed on the bars as they would be if they were used in a numeric column.
reactable( car_data, defaultSorted = "MPG.city", defaultSortOrder = "desc", columns = list( Make = colDef( cell = data_bars(car_data, fill_by = "MPG.city", text_position = "above", fill_color = c("#22577A","#38A3A5","#57CC99","#80ED99","#C7F9CC")) ) ) ) %>% add_legend(car_data, col_name = 'MPG.city', title = 'MPG City', align = 'left', colors = c("#22577A","#38A3A5","#57CC99","#80ED99","#C7F9CC"))
data_bars_pos_neg()
is also now depreciated and has been replaced with the default setting of data_bars()
which automatically detects if there are negative values within a column and adjusts the bars to go in opposite directions rather than one.
If two colors are provided, the first color will be applied to the negative-filled bars and the second color will be applied to the positive-filled bars
data %>% mutate(Change = Pct1 - Pct2) %>% select(Group, Change) %>% reactable(., pagination = FALSE, columns = list( Change = colDef( cell = data_bars(., fill_color = c("lightblue","orange"), number_fmt = scales::percent)) ) )
The labels can be positioned in the same fashion that is used for the positive-valued data bars in the examples above:
data %>% mutate(Change = Pct1 - Pct2) %>% select(Group, Change) %>% reactable(., pagination = FALSE, defaultSorted = "Change", defaultSortOrder = "asc", columns = list( Change = colDef( cell = data_bars(., fill_color = c("lightblue","orange"), text_position = "inside-end", number_fmt = scales::percent)) ) )
Now within the data_bars()
formatter, you can directly add icons to your tables!
First let's start with a dataset that shows fake data from some of the leading social media websites. We will later use the names of the sites within the Logo column to apply the icons from the Font Awesome icon library. Please note that the names of the sites are all lower-case to match the icon names within Font Awesome.
data <- data.frame( Company = c("facebook", "twitter", "linkedin", "reddit", "youtube", "instagram", "pinterest", "snapchat"), Primary = c("#4267B2", "#1DA1F2", "#0E76A8", "#FF4500", "#FF0000", "#833AB4", "#E60023", "#FFFC00"), Values = c(75, 120, 90, 100, 80, 70, 60, 40) ) reactable( data, defaultSorted = "Values", defaultSortOrder = "desc", columns = list( Values = colDef( cell = data_bars(data, fill_color = "black", fill_opacity = 0.8, text_position = "inside-end")) ) )
To add the logos of each company to the end of the data bars, use icon_ref
to reference the column (Company) containing the names of the companies:
reactable( data, defaultSorted = "Values", defaultSortOrder = "desc", columns = list( Values = colDef( cell = data_bars(data, icon_ref = "Company", fill_color = "black", fill_opacity = 0.8, text_position = "inside-end")) ) )
By default, the color of the icon is inherited from the color of the filled data bar, but they can be changed either through icon_color
or with icon_color_ref
which we will be using below in order to apply each company's primary color to icons:
reactable( data, defaultSorted = "Values", defaultSortOrder = "desc", columns = list( Values = colDef( cell = data_bars(data, icon_ref = "Company", icon_color_ref = "Primary", fill_color = "black", fill_opacity = 0.8, text_position = "inside-end")) ) )
An alternative would be to use fill_color_ref
instead, which applies each company's primary color to the fill of the data bars and then the icons inherit that color as well:
reactable( data, defaultSorted = "Values", defaultSortOrder = "desc", columns = list( Values = colDef( cell = data_bars(data, icon_ref = "Company", fill_color_ref = "Primary", text_position = "inside-end")) ) )
The size of the icons can also be adjusted with icon_size
:
reactable( data, defaultSorted = "Values", defaultSortOrder = "desc", columns = list( Values = colDef( cell = data_bars(data, icon_ref = "Company", icon_size = 35, fill_color_ref = "Primary", text_position = "inside-end", background = "transparent") ), Company = colDef(show = FALSE), Primary = colDef(show = FALSE) ) )
Similarly, you can now assign images to your data bars!
First let's load the dataset from nflfastR that was used in the Embed Images example (this dataset is limited to just the 2018-2019 seasons):
## load multiple seasons seasons <- 2018:2019 pbp <- map_df(seasons, function(x) { readRDS(url( paste0( "https://raw.githubusercontent.com/guga31bb/nflfastR-data/master/data/play_by_play_", x, ".rds" ) )) }) ## figures with QB stats qbs <- pbp %>% filter(week <= 17,!is.na(epa)) %>% group_by(id, name) %>% summarize( epa = mean(qb_epa), cpoe = mean(cpoe, na.rm = T), n_dropbacks = sum(pass), n_plays = n(), team = last(posteam) ) %>% ungroup() %>% filter(n_dropbacks > 100 & n_plays > 1000) ## join team logos to dataset qbs <- qbs %>% left_join(teams_colors_logos, by = c('team' = 'team_abbr')) %>% select(name, team_logo_espn, team_color, cpoe, epa)
The URL's for the team logos contained within the team_logo_espn column can be referenced using img_ref
to overlay on top of the data bars. The images can also be re-sized using img_height
and img_width
. The default image size is 20px by 20px.
reactable( qbs, defaultPageSize = 20, columns = list( team_logo_espn = colDef(show = FALSE), ## hide column containing team logos team_color = colDef(show = FALSE), ## hide column containing team colors name = colDef(maxWidth = 120), cpoe = colDef( cell = data_bars(qbs, fill_color_ref = "team_color", fill_opacity = 0.3, brighten_text = FALSE, text_position = "inside-end", number_fmt = scales::percent, img_ref = "team_logo_espn", img_height = 30, img_width = 30) ), epa = colDef( cell = data_bars(qbs, fill_color_ref = "team_color", fill_opacity = 0.3, brighten_text = FALSE, text_position = "inside-end", number_fmt = scales::number_format(accuracy = 0.01), img_ref = "team_logo_espn", img_height = 30, img_width = 30) ) ) )
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.