I have a Shiny app that writes a webpage and provides both an Excel file download and a PDF, through an .Rmd because I need to parameterize by country. See my previous question for the same project on how to remove empty space in the PDF: https://stackoverflow.com/questions/64210913/how-do-i-remove-empty-space-between-code-chunks-in-rmd-output-to-pdf
The PDF output is in columns: left side for tables, blank mini middle column for white space, right side for charts. I add table titles as text (I did not add them as captions because I wanted the titles formatted a certain way and couldn't figure it out that way as I don't know LaTeX). Some of the titles are long, and wrap mid-word with a hyphen. How do I make the PDF output wrap without breaking up a word?
For example, I'd like a long title to break between "with" and "extralong", without specifically telling it to break there (because my titles are dynamic, each PDF might need to wrap at a different spot(s) in the title), and then again probably between "through" and "hyphenation". Here's the R chunk where I create a long title and the colorize function:
long_title <- paste0("This really long title continues forever with extralong words that shouldn't break through hyphenation")
## https://bookdown.org/yihui/rmarkdown-cookbook/font-color.html
colorize <- function(x, color) {
if (knitr::is_latex_output()) {
sprintf("\\textcolor[HTML]{2A64AB}{%s}", x)
} else if (knitr::is_html_output()) {
sprintf("<span style = 'color: %s;'>%s</span>", color, x)
} else x
}
The call:
**r colorize(long_title, color = "#2A64AB")**
The output, NOT the way I want it:
Related
I couldn't find any argument to adjust the text alignment in ph_add_text to justify.
Im using officer to make slide from r.
Or any suggestions to make slide from r that have text alignment argument.
Can anyone help me?
This is a year and half later, but here's what I did. First, I make the text I want into it's own object with any properties that I might have. For simplicity, I won't add any properties, like font color, etc.
my_text <- ftext("I wish this were centered!")
Next, I make another object that contains the formatting of the paragraph that the text will be in (or text box in PowerPoint) using officer's fp_par() function:
my_format <- fp_par(text.align = "center")
Now, I can put it together--here's how it could go in a slide:
slide <- ph_with(slide_object, value = fpar(my_text, fp_p = my_format), location = ph_location(left = 4.90, top = 2.3))
The trick is, within the fpar argument, to have your text first and then, within the fp_p argument, to specify for fp_par() formatting as its own object.
Here's also more information on the function in case you're interested:
https://davidgohel.github.io/officer/reference/fp_par.html
I'm writing a Shiny app in which I display text that is loaded from a database. In the database, there might be texts like so:
This is the first line
and this is the second.
There is a list of these texts that I'm loading from the database, and I want to display them all in their own box. My backend processing of these strings looks more or less like this:
format_text <- function(text) {
shinydashboard::box(text)
}
output$text_ui <- renderUI({
map(text_list, format_text) %>%
tagList()
})
When displaying, this does not respect the newlines that are in the original strings. The entire text is displayed on one line:
This is the first lineand this is the second.
I've tried fixing this by adding the following step in my custom function:
text <- str_replace_all(text, "(\r|\n)", "<br/>")
Which results in the following text:
This is the first line<br/>and this is the second
Which is obviously not what I want either.
Now, I know that I can create new lines using the shiny::br() function. However, I'm struggling to see how I could get those to work at the right points in the string.
A minimal Shiny app to fiddle with can be found here.
Ah, the solution turns out to be deceptively simple:
format_text <- function(text) {
shinydashboard::box(
HTML(text)
)
}
When using the ReporteRs package, it seems that the only way to get text into the footer of a page involves placing a numbered footnote in the body of the text, and having that footnote appear with the same number in the footer. I'd like to be able to put text in the footer of a page without any numbering in front.
library(ReporteRs)
doc1 <- docx()
doc1 <- addFlexTable(doc1,vanilla.table(head(iris)))
Foot <- Footnote()
Foot <- addParagraph(Foot,"This should not have a number in front of it")
doc <- addParagraph(doc,pot("There should be no number after this",footnote=Foot))
writeDoc(doc1, file = "footnote1.docx")
Alternatively, if it's possible to just put a paragraph at the bottom of the page, that would also solve my problem. This could be done by figuring out how many more lines will fit on the page, but if there was some way to make the vertical alignment the bottom of the page for the last paragraph, that would be ideal.
doc2 <- docx()
doc2 <- addFlexTable(doc2,vanilla.table(head(iris)))
doc2 <- addParagraph(doc2,c(rep("",33),"Text placed by dynamically finding bottom of the page"))
writeDoc(doc2, file = "footnote2.docx")
What you are trying to do doesn't match ReporteRs::Footnote as it was written, as shown in the help:
If in a docx object, footnote will be flagged by a number immediately following the portion of the text the note is in reference to.
However, what you are after is achievable if I understand your question correctly. The note in your table and the text in the footer will not be connected in any way, such as a hyperlink provided by Footnote.
There is also the issue that ReporteRs does not provide a method to place text in the footer without using bookmarks (except Footnote, which we have now discounted). That means we need to use a docx template instead of the empty document generated by the package.
Template creation
Steps:
From MS Word I have opened an empty document
Placed the cursor in the footer area
Insert => Bookmark
Enter Bookmark name, I just used FOOTER, and click Add
Save the document
Document generation with ReporteRs
With our new template, the next steps will seem more familiar.
library(ReporteRs)
doc <- docx(template = "Doc1.docx")
# do the flextable, note that I add your table footer here
ftable <- vanilla.table(head(iris))
ftable <- addFooterRow(
ftable,
value = c("There should be no number after this"),
colspan = 5
)
doc <- addFlexTable(doc, ftable)
# check for the presence of our bookmark
list_bookmarks(doc)
# [1] "FOOTER"
# now add the footer text using the bookmark
doc <- addParagraph(
doc, stylename = "footer", bookmark = "FOOTER",
pot("This should not have a number in front of it")
)
# and finally write the document
writeDoc(doc, file = "doc.docx")
End product
The table, which you can better format to suit, I have not removed the border on the added row.
The footer, in the standard footer style, which again you can modify to suit.
I am trying to include links to particular webpages in a 'kable' table in Rmarkdown, when creating a pdf.
The table has 4 columns, and I wish for the links to be in the second column, which currently includes strings. The output of the table is given below;
knitr::kable(ind_rank_table_final,row.names = FALSE,caption = "Industry Rank",align = rep("l",ncol(ind_rank_table)))
Using paste0, you can construct markdown-formatted URLs in your dataframe, and then pass that to kable, like so:
---
output: pdf_document
---
```{r}
# some urls
urls <- rep("https://stackoverflow.com/", 10)
# use paste0 to compose markdown-formatted hyperlinks
mtcars$mpg <- paste0("[", mtcars$mpg, "](", urls, ")")
# print the table, with hyperlinked text
knitr::kable(head(mtcars))
```
And you can see the result, blue text in the mpg column, and if I hover my mouse over, I see the URL:
If you want to print the URLs in the table, and have them clickable, then you'de do something like this mtcars$mpg <- paste0("[", urls, "](", urls, ")") like so:
Is that what you're after? This use of paste0 is pretty handy for doing all sorts of things to tables, for example, combining multiple values in one cell, and applying conditional formatting (like bold for significant values)
For those knitting to PDFs using bookdown, #Ben's answer will not get you fully the way there. As #mavericks pointed out, you will still see the full text ([21](https://stackoverflow.com/), to keep with #maverick's example).
To fix this, add the argument format = "pipe" or format = "simple" to kable(). The "latex" option, while generating a working link, will display like #maverick's example. The default behavior for kable() is to automatically determine the format, which I guess in the case of a bookdown document must be "latex"?
I don't know, but this should generate #Ben's first table for bookdown users:
output: bookdown::pdf_document2
# some urls
urls <- rep("https://stackoverflow.com/", 10)
# use paste0 to compose markdown-formatted hyperlinks
mtcars$mpg <- paste0("[", mtcars$mpg, "](", urls, ")")
# print the table, with hyperlinked text
knitr::kable(head(mtcars), format = "simple")
I am using knitr to generate a PDF writeup. I want to print a series of tables with section headers in between. I am doing this in an R code chunk. Unfortunately though, what happens is that the first header prints, then a figure, then the rest of the headers fit on that page and the rest of the tables come after rather than being interspersed amongst the headers as desired.
After this page there are a series of 5 more tables on their own pages.
This is the code that I am using:
dfList <- list(alc_top, alc_bottom, cpg_home_top, cpg_home_bottom, electronics_top, electronics_bottom)
labels <- c("Premium Liquor Brand - Top Performers", "Premium Liquor Brand- Bottom Performers", "CPG Home - Top Performers", "CPG Home - Bottom Performers", "Electronics - Top Performers", "CPG Home - Bottom Performers")
for (i in 1:length(dfList)) {
df <- dfList[[i]]
product = "test"
cat(paste("\\section{",labels[i],"}", sep=""))
print(xtable(df,size="\\tiny"))
}
I've tried adding a new line, cat("\\newpage") within the loop. this adds a new page for each label, but all of the graphs are after the new section again.
I think I need to specify a positioning value (H or h or something like that in LaTex) for the table, but I am not really sure how to do that with xtable and knitr.
The problem here is not the order in which the elements are written to the TEX file. The "wrong order" in the PDF is due to the fact that the tables are wrapped in floating environments and therefore the position of their TEX code in the source file does not necessarily correspond to the table's position in the PDF.
Here are three options that keep the tables at a fixed position. Each one has its pros and cons:
Option 1: Don't use floats
print.xtable has a floating argument (which defaults to TRUE). Setting this argument to FALSE results in a table that is not wrapped in a floating environment (default: table).
Pro: Simple and effective.
Con: Non-floats are not numbered, have no caption and no label. print.xtable ignores the caption and label arguments on xtable if floating = FALSE.
Option 2: Position "H"
print.xtable has a table.placement argument that can be used to pass a custom float placement specifier to the floating environment. The specifier H "places the float at precisely the location in the LaTeX code" (source: Wikibooks). Note that this requires \usepackage{float}.
Pro: Keep caption, numbering and label.
Con: Requires an additional package (hardly relevant).
Option 3: \FloatBarrier
The LaTeX package placeins offers a \FloatBarrier command which forces that all floats that are not displayed up to this point are printed.
Pros and cons: As option 2.
Besides, it clutters the code a little bit because of the \FloatBarrier commands that need to be inserted after each table – unless (at least in the specific case of this question) the following feature is used:
The package even provides an option to change the definition of \section to automatically include a \FloatBarrier. This can be set by loading the package with the option [section] (\usepackage[section]{placeins}). [source: Wikibooks]
Demo
\documentclass{article}
\usepackage{float}
\usepackage{placeins}
\begin{document}
<<results = "asis", echo = FALSE>>=
library(xtable)
# This table floats.
print(
xtable(head(cars),
caption = "Floating",
label = "tab:floating"), table.placement = "b"
)
# This table won't float but caption and label are ignored.
print(
xtable(head(cars),
caption = "Not floating",
label = "tab:not-floating"),
floating = FALSE)
# Placement "H". (requires "float" package)
print(
xtable(head(cars),
caption = "Non-floating float",
label = "tab:not-actually-floating"),
table.placement = "H")
cat("Text before the barrier. (text 1)")
# Floats won't float beyond this barrier (requires "placeins" package)
cat("\\FloatBarrier\n")
cat("Text after the barrier. (text 2)")
#
Add \texttt{table.placement = "b"} to the first table to see that it will be located at the bottom of page 1 (after `text 1') and `text 2` will come \emph{after} it (on page 2), althogh there would be plenty of space on page 1. This is because the float cannot `pass' the barrier.
\end{document}