Let’s make a simple gt table with the exibble dataset, using the row column for labels in the stub. We’ll add a single row to the bottom of the table with rows_add(). With name-value pairs, it’s possible to add values for the new body cells that correspond to columns available in the table. For any columns that are missed, the related body cells will receive NA values.
Again with exibble, we can create an example where we insert ‘spacer’ rows. These are rows without any content and merely serve to add extra vertical space to the table in specific locations. In this case, we’ll have a stub with row names and row groups (set up in the gt() call). The two rows being added will occupy the bottom row of each group. The only data defined for the two rows involves values for the row and group columns. It’s important that the data for group uses the group names already present in the data ("grp_a" and "grp_b"). The corresponding values for row will be "row_a_end" and "row_b_end", these will be used later expressions for targeting the rows. Here’s the code needed to generate spacer rows at the end of each row group:
All missing values were substituted with an empty string (""), and that was done by using sub_missing(). We removed the top border of the new rows with a call to tab_style(), targeting those rows where the row labels end with "end". Finally, we get rid of the row labels with the use of text_case_when(), using a similar strategy of targeting the name of the row label.
Another application is starting from nothing (really just the definition of columns) and building up a table using several invocations of rows_add(). This might be useful in interactive or programmatic applications. Here’s an example where two columns are defined with dplyr::tibble() (and no rows are present initially); with two calls of rows_add(), two separate rows are added.
It’s possible to use formula syntax in rows_add() to perform column resolution along with attaching values for new rows. If we wanted to use an equivalent value for multiple cells in a new row, a valid input would be in the form of <expr> ~ <value vector>. In the following example, we create a simple table with six columns (the rendered gt table displays four columns and a stub column since the group column is used for row group labels). Let’s add a single row where some of the cell values added correspond to columns are resolved on the LHS of the formula expressions:
We can see that using starts_with("gr") yields a successful match to the group column with the tangible result being an addition of a row to the "Group A" group (the added row is the second one in the rendered gt table). Through the use of c(a, b), it was possible to add the value 5 to both the a and b columns. A similar approach was taken with adding the 72.63 value to the quantity_x and quantity_y columns though we used the starts_with("quantity") expression to get gt to resolve those two columns.
You can start with an empty table (i.e., no columns and no rows) and add one or more rows to it. In the completely empty table scenario, where you would use something like dplyr::tibble() or data.frame() with gt(), the first rows_add() could have rows of arbitrary width. In other words, you get to generate table columns (and rows) with a completely empty table via rows_add(). Here’s an example of that:
In the above, three columns and three rows were generated. The second usage of rows_add() had to use of a subset of those columns (all three were used to create a complete, new row).
We can also start with a virtually empty table: one that has columns but no actual rows. With this type of multi-column, zero-row table, one needs to use a subset of the columns when generating new rows through rows_add().