Including links within Rmarkdown tables (pdf) - r

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")

Related

Format R Markdown output so that it can be copied and pasted to twitter

Trying to do daily reports with Rmarkdown on covid-19 data. Want to tweet top 10 values from tables, but the options tried so far leave no spaces - tabs are erased when the tweet button is pushed. Have tried {kableExtra} with html output and {flextable} with word output, but when copied and pasted, the column separations are 'disappearing' tabs.
Does anyone have any recommendations on how to obtain a table with spaces or commas between columns?
Example Rmarkdown script is here, if interested, but the question is meant to be general and not require looking at the script.
How about creating a picture of the table (which looks quite good then).
You could do this like this:
library("knitr")
library(kableExtra")
knitr::kable(mtcars, "latex") %>%
kableExtra::kable_styling(latex_options = "striped") %>%
kableExtra::save_kable("test.png")
Or does this have any downsides you don't want?
Addition:
Alright, I didn't look at your file - seems you want to add 4 tables but not copy 4 images.
Short question here - isn't this then quite hard with the 280 char limit of twitter...?
But what you could do is the following:
```{r, echo = F}
aa <- knitr::kable(head(mtcars[, 1:4]), "pipe")
for (i in 1:length(aa)) {
aa[i] <- gsub(" ", ",", aa[i])
aa[i] <- paste(aa[i], "\n")
}
aa
```
In your code chunk save the table to a variable. This will then just be a table in markdown format. Now you can parse through and replace and alter chars how you need it.

kable produces malformed reference links within lapply function in blogdown

I am using blogdown to to create a blogpost that has a series of tables. Creating a single table using the kable function works fine. If you do
blogdown::new_site()
blogdown::new_post("test", ext = ".rmd")
A new rmd file will be created within the content/post directory of the project. If you open that file and create a single table by doing
```{r test1}
library(knitr)
library(magrittr)
library(shiny)
data.frame(a= c(1,2,3)) %>% kable(caption = 'test',format = 'html')
```
A correctly formatted table will be generated. The caption will read "
Table 1: test" If you look at the code of the generated site, the caption will look like this.
<caption>
<span id="tab:test1">Table 1: </span>test
</caption>
Ideally I don't have any desire to label the table as Table 1 in the first place but that is another question. If formatting of captions by kable can be disabled entirely, I'd also be happy.
However if I use lapply to generate 2 tables instead
```{r test2}
lapply(1:2,function(x){
data.frame(a= c(1,2,3)) %>% kable(caption = 'test2',format = 'html') %>% HTML()
}) -> tables
tables[[1]]
tables[[2]]
```
The captions will have the prefix \#tab:test2. If you look at the caption of these tables, you'll see
<caption>(\#tab:test2)test2</caption>
The question is, why kable behaves differently when its called from a lapply compared to its behaviour outside? Note that both of these behaviours are different that its behaviour when simply knitting the file as an html_document.
I did some digging into the kable's code and found that the caption link is created by the knitr:::create_label function. Looking into this function, I saw the part that is responsible for the wrong behaviour seen with the multiple tables.
if (isTRUE(opts_knit$get("bookdown.internal.label"))) {
lab1 = "(\\#"
lab2 = ")"
}
I could not find the code, responsible for the "correct" behaviour with the single table but it seems like knitr internal options are responsible.
Ultimately the behaviour that I want is simply
<caption>test</caption>
which is the behaviour when simply knitting an html document. But I am yet to find a way to set the relevant knitr options and why are they different within the same document.
Edit: Further examination suggests that the issue isn't lapply specific. It can be replicated using a for loop or even { by itself. A complete post with all the problematic examples can be acquired from this issue on knitr's github page. This github repo includes the basic blogdown site that replicates the issue
Turns out the responsible party is not the lapply call but the HTML call at the end. It seems like the regular process by knitr in blogdown and bookdown is to have a temporary marker for the table references in the form of (\#tab:label) and replace it with the appropriate syntax later in the processing.
I was using the HTML call to be able to use the tags object in shiny/htmltools to bind the tables together. This approach seems to make the process of replacing the temporary marker impossible for reasons outside my understanding. For my own purposes I was able to remove the temporary marker all together to get rid of both malformed captions and the working-as-intended table numbers by doing
remove_table_numbers = function(table){
old_attributes = attributes(table)
table %<>% as.character() %>% gsub("\\(\\\\#tab:.*?\\)","",.)
attributes(table) = old_attributes
return(table)
}
data.frame(a= c(1,2,3)) %>% kable(caption = 'test',format = 'html') %>% remove_table_numbers
This question still would benefit from a proper explanation of the reference link placement process and if its possible to apply it to tables in HTML calls as well. But for know this solves my issue. I'll gladly switch the accepted answer if a more complete explanation appears

Use loop to generate section of text in rmarkdown

I need to produce a report that is composed of several sections, all sections look similar, with only some differences in data. The number of sections is also dependent on the data. What I ultimately want to have is something like this:
```{r}
section_names = c("A","B","C")
section_data = c(13,14,16)
```
# some looping mechanism here with variable i
This is section `r section_names[i]`
This section's data is `r section_data[i]`
#more things go here for the section
#end of loop should go here
The result should be a single html/document with all the sections one after the other.
Can you point me to a way for producing such an Rmd file with the loop?
Ideally I would have hoped to see something like in PHP:
<$php for(i=0;i<10;i++) { ?>
## some html template + code chunks here
<$php } ?>
This question is similar to that one, although it is LateX/RNW based. Besides, this answer demonstrates how to generate a rmarkdown document dynamically. However, neither of the questions is a exact duplicate of this one.
Basically, there are two mental steps to take:
Figure out the markdown markup needed per section. This could be something along the lines of
## This is section <section_name>
Section data is `<section_data>`.
Additional section text is: <section_text>.
Write R code that generates this markup, replacing the placeholders with the appropriate values.
For step 2, using sprintf is a natural candidate to combine static and dynamic text. Don't forget to use the chunk options results = "asis" to prevent knitr from adding formatting to your output and use cat (instead of print) to prevent R from adding additional stuff like quotes and element numbers.
I changed the input data structure a little bit for the sake of clarity (using a data.frame instead of independent vectors section_names and section_data).
```{r echo = FALSE, results = "asis"}
input <- data.frame(
name = LETTERS[1:4],
data = runif(n = 4),
text = replicate(4, paste(sample(x = LETTERS, size = 100, replace = TRUE), collapse = "")),
stringsAsFactors = FALSE)
template <- "## This is section %s
Section data is `%0.2f`.
Additional section text is: %s.
" # dont't forget the newline
for (i in seq(nrow(input))) {
current <- input[i, ]
cat(sprintf(template, current$name, current$data, current$text))
}
```
Output:
This is section A
Section data is 0.83.
Additional section text is: PUFTZQFCYJFNENMAAUDPTWIKLBSVKWMJWODFHSPRJRROTVDGNEROBVQPLLMVNPOUUHGVGRPMKAOAOMVYXKMGMUHNYWZGPRAWPYLU.
This is section B
Section data is 0.49.
Additional section text is: PFTYCGFSGSMAYSSCZXWLNLDOQEBJYEVSJIYDJPEPSWQBNWJVRUKBTYIUSTOICFKJFEJCWCAYBCQSRTXUDEQLLXCZNPUKNLJIQJXE.
This is section C
Section data is 0.58.
Additional section text is: FCJDDDMNLBUSJMCZVSBPYWCKSFJEARBXXFPAGBTKCWKHPEDGYWYTNGLVGQGJAFZRUMNSDCHKTTMGRFNSUZKFLOUGNWHUBNLVMGDB.
This is section D
Section data is 0.52.
Additional section text is: YQIXHABFVQUAAYZNWTZXJDISSLTZJJAZOLJMJSXEENFTUOFOTYKDNNUMFDXLJSWZEVDLCLSYCTSMEXFLBVQYRTBEVZLCTEBPUGTT.
Just sharing the approach I've used eventually.
I wrote a markdown file for the section. prepared the data for each section in the master document, and looped over all the sections I needed, each time calling to knit_child() with the section Rmd.
I know this is late, but I used this in my code to make numbered sections and it works a treat.
for (k in 1:length(listcsv)){ #Begin Loop at pdf file one and continue until all have been completed
subsection <- paste("5", k, sep = ".")}
this uses the loop number (k) to create the subsection number and then paste it against the section number. This happens to be in section 5, but you could use the same principle to make sections and subsections ad infinitum.

highlight all inline \Sexpr{} outputs in the generated pdf

I am using knitr for a report wherein I have a lot of inline output text, mostly numeric values, using \Sexpr{}. I want to highlight All these inline outputs in my generated pdf.
Example code:
\documentclass[12pt]{article}
\begin{document}
<<echo=FALSE, include=FALSE>>=
N <- 100 # Total
N_f <- 60 # Women
#
There were \Sexpr{N} people in the company, \Sexpr{N_f} women and \Sexpr{N - N_f} men.
\end{document}
Hence, in the output all the number should be highlighted, i.e. with a shaded background (similar to using with \hl{} with the \usepackage{soul}).
It seems to me that the solution would use one of the inline output hooks. Another possibility might be to write a LaTeX function which search all the \Sexpr{...} expressions in the entire document and highlights them in the generated pdf. I am still learning and can not figure out how to implement these.
Thanks for any help or hints.
Note: The knitr page by yihui talks about manipulation of the numeric value (scientific notation, digits after decimal points) which I have got covered.
The output hook inline can be used to style output from \Sexpr{}. This is as simple as
knit_hooks$set(inline = function(x) { sprintf("\\textbf{%s}", x)})
Just define an arbitrary function that takes an argument x and returns the string to be printed. In this example I used \textbf to make the output bold, but this can be extended to any LaTeX commands.
In this answer, Yihui suggests an improvement that still takes the default inline hook into account. This ensures rounding as usually performed by the default hook:
hook_inline <- knit_hooks$get('inline')
knit_hooks$set(inline = function(x) { sprintf("\\textbf{%s}", hook_inline(x))})

xtable italics format for a column

I need to insert the species names in a table created by xtable in my Rnw file and I want to convert the relative column to italics format. Is it possible without any manual intervention?
My call is:
xtable(cklist, caption="Checklist...", align='lllc',label = 'tab:ckzygo')
To typeset a column in italics (or any other non-standard font shape), you should use the >{\cmd} syntax for column specification.
Assigning the column type >{\itshape}l generates a left-justified column in italics.
This is a better solution than iris$Species <- paste0("\\textit{", iris$Species, "}") as suggested in the comments because you neither have to modify your data nor you need to disable text sanitizing.
Small illustration:
\documentclass{article}
\usepackage{array}
\begin{document}
<<xtableItalics, results = "asis">>=
library(xtable)
print(xtable(head(iris), align = c(rep("l", 5), ">{\\itshape}l")))
#
\end{document}
The PDF looks like:
Please note that you need to use the array package for this to work.
EDIT: To show the flexibility of this approach, two more examples:
print(xtable(head(iris), align = c(rep("l", 5), ">{\\textit\\bgroup}l<{\\egroup}")))
print(xtable(head(iris), align = c(rep("l", 5), ">{\\textcolor{red}\\bgroup}l<{\\egroup}")))
The first line uses \textit{} instead of \itshape to typeset the italics. As \textit{} requires the text to modify as an argument, we need a slightly more complex syntax. (It's described in the wikibooks.org article linked above.)
This syntax can also be used to change for example the color of the text. In more complex cases, lrbox is required, as described in the linked article.

Resources