adajam
adajam

Reputation: 221

Group / pack every N rows using "pack_rows" in Kable

I'm trying to use a vector in combination with "pack_rows" in kable (or "group_rows" - whichever works), to consistently 'group' a pre-defined number of rows.

I have a character vector called "stimuli_list", ordered alphabetically, containing the names of many individual items (e.g. "anchor", "apple", "ashtray") - too many to define one by one. For each of these individual items, I have 6 rows of corresponding data in a separate df (also arranged alphabetically). I want to group, or pack, all 6 rows of data under the single item label they correspond to. My desired output would look like:

            col1    col2      col3
anchor
            row 1   of data   for anchor
            row 2   of data   for anchor
            row 3   of data   for anchor
            row 4   of data   for anchor
            row 5   of data   for anchor
            row 6   of data   for anchor
apple
            row 1   of data   for apple
            row 2   of data   for apple
            row 3   of data   for apple
            row 4   of data   for apple
            row 5   of data   for apple
            row 6   of data   for apple
and so on...

But as I don't know how to define the number of rows to group, I'm getting this:

            col1    col2      col3
anchor
            row 1   of data   for anchor
apple
            row 2   of data   for anchor
ashtray
            row 3   of data   for anchor
balloon
            row 4   of data   for anchor
banana
            row 5   of data   for anchor
barrel
            row 6   of data   for anchor
basket
            row 1   of data   for apple
bear
            row 2   of data   for apple
and so on...

As the data is all ordered correctly, I simply need to tell pack_rows to do its job on every 6th row, rather than every single row. The code I currently have:

    b %>%
      kable("latex", longtable = T, booktabs = T, linesep = c("", "", "", "", "", "\\addlinespace")) %>%
      kable_styling(bootstrap_options = c("striped","condensed")) %>%
      kable_styling(latex_options = c("repeat_header"), font_size = 6) %>%
      add_header_above(c(" " = 1, "Familiarity" = 2, "Visual Complexity" = 2, 
                         "Colour Diagnosticity" = 2, "Mental Imagery Agreement" = 2)) %>%
      pack_rows(index = table(a))

Any help appreciated!


reprex:

stimuli_list:

a <- structure(list(stim = c("anchor", "apple", "ashtray", "balloon", 
"banana", "barrel", "basket", "bear", "bell", "belt")), row.names = c(NA, 
-10L), class = c("tbl_df", "tbl", "data.frame"))

Main data:

b <- structure(list(Photograph = c("anchor1-photo-colour", "anchor1-photo-grey", 
"anchor2-photo-colour", "anchor2-photo-grey", "anchor3-photo-colour", 
"anchor3-photo-grey", "apple1-photo-colour", "apple1-photo-grey", 
"apple2-photo-colour", "apple2-photo-grey"), Fam_Mean = c(3.55, 
2.97, 3.3, 2.81, 3.52, 3.1, 4.79, 4.85, 4.95, 4.4), Fam_SD = c(1.32, 
1.52, 1.56, 1.57, 1.33, 1.52, 0.49, 0.49, 0.22, 0.88), VisCom_Mean = c(2.95, 
2.81, 3.45, 3, 2.4, 2.35, 3.1, 2.19, 3, 2.4), VisCom_SD = c(1.12, 
0.93, 1.23, 0.97, 0.88, 1.09, 1.14, 1.08, 0.97, 0.99), ColDia_Mean = c(2.81, 
NaN, 3.5, NaN, 2.7, NaN, 3.43, NaN, 3.5, NaN), ColDia_SD = c(1.21, 
NA, 1.19, NA, 1.3, NA, 1.08, NA, 1.32, NA), MenIma_Mean = c(4.05, 
3.95, 3.75, 3.52, 3.8, 4.25, 4.15, 3.05, 3.76, 2.75), MenIma_SD = c(1.05, 
0.89, 1.25, 1.33, 1.01, 0.79, 0.88, 1.23, 1.04, 1.45)), row.names = c(NA, 
-10L), class = c("tbl_df", "tbl", "data.frame"))

Upvotes: 0

Views: 1575

Answers (1)

r2evans
r2evans

Reputation: 160447

Your a represents 10 different stims, yet your b only seems to look at 2 of them (anchor and apple). Further, table(a) is only going to return lots of 1s, so kable is only going to group one row at a time.

The mechanism we need it to be able to identify somehow the anchor in anchor1-photo-colour to extract that. If there is a means to do this without regexes earlier in your generation of b, then it might be better to do it there, since regexes can introduce problems if done incorrectly.

If we assume that all anchor[0-9].* photographs are concurrent (and same for other stims), then we can do something like this:

table(gsub("[0-9].*", "", b$Photograph))
# anchor  apple 
#      6      4 

which is something we can pass to pack_rows.

I'll demonstrate using an html engine just for simplicity, it should be the same with your "latex" output.

b %>%
  kable("html", longtable = T, booktabs = T, linesep = c("", "", "", "", "", "\\addlinespace")) %>%
  kable_styling(bootstrap_options = c("striped","condensed")) %>%
  kable_styling(latex_options = c("repeat_header"), font_size = 6) %>%
  add_header_above(c(" " = 1, "Familiarity" = 2, "Visual Complexity" = 2, 
                     "Colour Diagnosticity" = 2, "Mental Imagery Agreement" = 2)) %>%
  pack_rows(index = table(gsub("[0-9].*", "", b$Photograph)))

sample kable packed rows

Upvotes: 4

Related Questions