Table and Figure cross-reference officer R
Asked Answered
O

2

8

I would like to be able to cross-reference a table or figure in a word document using the officer R package.

I have come across these materials so far but they do not seem to have a solution: https://davidgohel.github.io/officer/articles/word.html#table-and-image-captions and a similar question add caption to flextable in docx

In both of these I can only insert a caption as a level 2 header and not a true table caption.

What I want to be able to do in Word is Insert -> Cross-reference and go to Reference type: Table and see my caption there. Right now I can only see the caption under Numbered item.

Does this functionality exist in officer or anywhere else?

Outfit answered 20/9, 2018 at 19:24 Comment(1)
did you ever find a solution? I would also like this functionMacur
M
7

In word, the table numbers use the { SEQ \\@ arabic } pattern, but references to them use { REF bookmark \h }. We can use this to make new code which can reference a SEQ field.

code:

ft <- regulartable(head(iris)) # create flextable
str <- paste0(' REF ft \\h ')  # create string to be used as reference to future bookmark

doc <- read_docx() %>%
  body_add_par('This is my caption' , style = 'Normal') %>% # add caption
  slip_in_seqfield(str = "SEQ Table \\@ arabic",           
                   style = 'Default Paragraph Font', 
                   pos = "before") %>% # add number for table
  body_bookmark('ft') %>%   # add bookmark on the number
  slip_in_text("Table ", 
               style = 'Default Paragraph Font', 
               pos = "before") %>% # add the word 'table'
  body_add_flextable(value = ft, align = 'left') %>% # add flextable
  body_add_break() %>%  # insert a break (optional)
  slip_in_text('As you can see in Table', 
               style = 'Default Paragraph Font', 
               pos = 'after') %>% # add the text you want before the table reference
  slip_in_seqfield(str = str,  
                   style = 'Default Paragraph Font', 
                   pos = 'after') %>% # add the reference to the table you just added
  slip_in_text(', there are a lot of iris flowers.', 
               style = 'Default Paragraph Font', 
               pos = 'after') %>% # add the rest of the text 
  print('Iris_test.docx') # print

Hope this helps :)

Macur answered 17/4, 2019 at 23:37 Comment(4)
Thanks so much! I hadn't found an answer till now. This seems to do the trick :)!Outfit
I can get this to work if I am only interested in the table being printed in a word doc alone, but how would I adapt this to work within a much larger Rmd file? If I remove the 'Iris_test.docx' I can get it to print within a Rmd-knitted word doc, but the table output I get is a jumbled mess of internal table structure.Boyne
honestly I have never gotten tables to print for me in Rmarkdown to word. They are always jumbled messes for me :( if you find a solution could you post it here, or edit my answer and add it?Macur
Thanks! Is there a chunk/officedown version for this?Substituent
I
3

Just for the record, you can do this a bit easier now by using some helper functions from the {crosstable} package.

Disclaimer: I am the developer of that package and these functions were highly inspired by @morgan121's answer. Thanks Morgan!

Here is an example:

library(officer)
library(crosstable)
library(ggplot2)
options(crosstable_units="cm")

ft = regulartable(head(iris)) 
my_plot = ggplot(data = iris ) +
  geom_point(mapping = aes(Sepal.Length, Petal.Length))

doc = read_docx() %>% 
  body_add_title("Dataset iris", 1) %>%
  body_add_normal("Table \\@ref(table_iris) displays the 6 first rows of the iris dataset.") %>%
  body_add_flextable(ft) %>%
  body_add_table_legend("Iris head", bookmark="table_iris") %>%
  body_add_normal("Let's add a figure as well. You can see in Figure \\@ref(fig_iris) that sepal length is somehow correlated with petal length.") %>%
  body_add_figure_legend("Relation between Petal length and Sepal length", bookmark="fig_iris") %>% 
  body_add_gg2(my_plot, w=14, h=10, scale=1.5)

print(doc , 'Iris_test.docx')    

More info on https://danchaltiel.github.io/crosstable/articles/crosstable-report.html.

As with morgan121's code, you have to select all the text in MS Word and press F9 twice for the numbers to update properly.

Insincerity answered 18/3, 2021 at 12:1 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.