Search code examples
rdataframedatatablesgtgtextras

{gtExtras} column showing in wrong order in {gt} table when grouped


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


Solution

  • 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