1

I am making a gt table showing the progress of individuals towards a goal. In the table, there is a row showing a horizontal bar graph of progress towards that goal (if goal is 50 and score is 40, the bar is at 80%).

However, when I change the order of the gt rows by using the groupname_col argument, the order of the other cells changes, but not the order of the gtExtras gt_plt_bar_pct column, so it's showing the wrong bars for the name and score in that row, instead, that column seems to always be represented in the order of rows in the input data.

I understand that I can fix this by using arrange on the df before the gt begins, but this doesn't seem like a good solution since I'm going to want to change the order of the rows to view by different groups. Is this a flaw with gtExtras? is there a better fix?

thanks!

reprex:

library(tibble)
library(gt)
library(gtExtras)
library(dplyr) 

# make dataframe of individuals and their goals
df <- tribble(
  ~name, ~group, ~score, ~goal,
    "Bob", "C",   20,   40,
    "Chris",  "A", 50,   40,
    "Dale",  "B",  30,   50,
    "Jay",    "A", 0,   40,
     "Ben",   "B", 10,   20
  
) %>%
  # calculate percent towards goal, and cap at 100%
  mutate(percent_to_goal = score/goal *100,
         percent_to_goal = case_when(percent_to_goal >= 100 ~ 100,
                                     TRUE ~ percent_to_goal))


df %>%
  
  # this fixes the issue, but doesn't seem like a permanent solution
  #arrange(group, name) %>%
  
  # make gt table
  gt(rowname_col = "name", groupname_col = "group") %>%
  
  # order groups
  row_group_order(groups = c("A","B","C")) %>%
  
  # add bar chart column
  gt_plt_bar_pct(column = percent_to_goal)  %>%
  
  # highlight blue if person reaches their goal
  tab_style(
    style = list(
      cell_fill(color = "lightcyan"),
      cell_text(weight = "bold")),
    locations = cells_body(
      columns = c(goal,score, percent_to_goal),
      rows = score >= goal
    )
  ) 

Here is the output from the above code: notice that the length of the bar charts do not always reflect the values of the rows they are appearing in. Instead, they reflect the order of the original dataset. output with original code

EDIT: remove row_group_order. If I run the above code again, but comment out the line meant to rearrange the appearance of groups, the grouping shows up in a different order (order of appearance of groups in the original dataset), and the name and first two columns sort into these groups accordingly, but the bar chart column still does not, and remains in the original order of the dataset. Image below:

Output without row_group_order

Jake L
  • 987
  • 9
  • 21
  • Interesting issue (and nice reprex!). I broke it down to as small an example as a I could. The only way I could get it to work was `df %>% group_by(group) %>% arrange(group) %>% gt() %>% gt_plt_bar_pct(column = percent_to_goal, scaled = TRUE)`. – rdelrossi Mar 02 '22 at 19:58
  • @rdelrossi thanks, it seems like your fix is similar to mine (I didn't actually realize you could `group_by()` on the pipe instead of `groupname_col` inside the `gt()`. But still seems like the unless you `arrange()` beforehand, the {gt} columns (score and goal) will change automatically and the {gtExtras} column (percent_to_goal) won't. This seems like a flaw in {gtExtras}, no? – Jake L Mar 03 '22 at 22:54
  • @rdelrossi wondering if I should report this as an issue on the repository, but I'm not sure if it's actually a bug or if user error. – Jake L Mar 03 '22 at 22:57
  • 1
    It's worth posting, imo. Author Tom Mock has taken my questions before via Twitter, too. He's at [@thomas_mock](https://twitter.com/thomas_mock). Be sure to post anything you learn! – rdelrossi Mar 03 '22 at 23:08
  • 2
    Howdy - thanks for letting me know about the SO post @jakeL ! The `row_group_order()` function is not one I'm testing against, so there's a decent chance it's a proper bug in `gtExtras`. I will generally say that it's almost always a good idea to do basic data sorting in R itself, and then use gt as the presentation layer. – Thomas Mock Mar 04 '22 at 15:40
  • I'll revisit my functions for `row_group_order` starting with plotting functions, but there's a decent chance that it'll cause problems. Long story short, there is a specific "order of operations" that gt does and I'm really only able to affect things in the middle. If `row_group_order()` occurs last, the data will unfortunately always not match. Will try to report back here with a proper SO answer once I've determined that. – Thomas Mock Mar 04 '22 at 15:42
  • Hi @ThomasMock ! Thanks for your response and for the tip- I will stick to sorting before gt. Just for the sake of experimenting, I removed the `row_group_order` line of code, and the output is still off (see edit above), so I think the issue has to do with the `groupname_col` or even just the `group_by()` as @rdelrossi showed above. The gtExtras column doesn't seem to rearrange itself into groups like the gt columns do. Thanks for looking into it! – Jake L Mar 04 '22 at 16:05
  • 1
    Found the error! I'll post a solution here in a bit. Prior to enhancing the rest of gtExtras, I wasn't use the `gt_index()` I wrote. `gt_plt_bar_pct()` was an older version that I kept around and it hadn't converted over to `gt_index()` function which respects grouping. I should be able to push out the fix soon by replacing the internals and once that's live I'll add the answer below. – Thomas Mock Mar 04 '22 at 16:31
  • 1
    @ThomasMock wow, thanks for looking into it so quickly! I'll keep my eyes out for the new push. – Jake L Mar 06 '22 at 19:16
  • Outstanding, @ThomasMock. Thanks for a great package and for getting on this so quickly. – rdelrossi Mar 09 '22 at 23:10
  • Added an answer below, gtExtras v 0.2.4 has corrected this issue by using `gt_index()` internally. – Thomas Mock Mar 17 '22 at 16:58

1 Answers1

1

Per gtExtras v 0.2.4 this bug has been fixed. Thanks for raising and the great reprex!

library(tibble)
library(gt)
library(gtExtras)
library(dplyr) 

# make dataframe of individuals and their goals
df <- tribble(
  ~name, ~group, ~score, ~goal,
  "Bob", "C",   20,   40,
  "Chris",  "A", 50,   40,
  "Dale",  "B",  30,   50,
  "Jay",    "A", 0,   40,
  "Ben",   "B", 10,   20
  
) %>%
  # calculate percent towards goal, and cap at 100%
  mutate(percent_to_goal = score/goal *100,
    percent_to_goal = case_when(percent_to_goal >= 100 ~ 100,
      TRUE ~ percent_to_goal))


df %>%
  # make gt table
  gt(rowname_col = "name", groupname_col = "group") %>%
  
  # order groups
  row_group_order(groups = c("A","B","C")) %>%
  
  # add bar chart column
  gt_plt_bar_pct(column = percent_to_goal)  %>%
  
  # highlight blue if person reaches their goal
  tab_style(
    style = list(
      cell_fill(color = "lightcyan"),
      cell_text(weight = "bold")),
    locations = cells_body(
      columns = c(goal,score, percent_to_goal),
      rows = score >= goal
    )
  ) 

Screenshot of table with inline bar charts

Thomas Mock
  • 206
  • 2
  • 5