I am using the huxtable package to create tables in a PDF rendered in bookdown. The table is formatted exactly the way I want it, up until I run the print_md command, after which a border is moved up row from underneath the column names to underneath the header. Also, the header is moved from a centered position to right-aligned. Check it out:
df <- data.frame(
"colname1" = c("something indicator"),
"colname2" = "[Something](http://www.overleaf.com)",
"colname3" = "[Something again](http://www.overleaf.com)")
df <- df %>%
as_hux() %>%
theme_basic() %>%
set_tb_padding(2)
df <- df %>%
set_contents(1, 2:3, c("colname2", "colname3")) %>%
insert_row("", "Header", "Header", after = 0) %>%
merge_cells(1, 2:3) %>%
set_align(1, everywhere, "center") %>%
set_tb_padding(1, everywhere, 0) %>%
set_bold(1, everywhere)
df
Which gives:
Table is formatted correctly. But. You'll notice that the URLs are not formatted correctly. It should only be showing the part within the brackets, which when clicked will take you to the site in parentheses.
This can be remedied with the following code:
df %>% print_md()
Which gives:
Now the URLs look like they should, but the border has erroneously moved up a row, and "Header" is now right-aligned instead of center-aligned. How do I stop that from happening?
Don't ask me why it works. But changing print_md() to set_markdown() fixed both the border and alignment problems.
EDIT: I'm adding #dash2's comment to this answer.
The reason print_md() was causing problems is because it converts the table to markdown format, which R Markdown then reads and produces a table from. So some features (alignment) get lost in translation. It'd be better to print the table in the intended output format, be it Latex, HTML or whatever you're using, instead of markdown.
But the cells with markdown hyperlinks need to be respected still - print_md() is just the wrong way to go about it. Instead, use set_markdown(). This will ensure that, within huxtable itself, cells with markdown code are interpreted as markdown before the table is printed. The printed table will then retain the intended format.
Thank you #dash2 for creating such a powerful package!
Related
I am trying to use the Export -> Copy to Clipboard option after making a kable() or gt() table. When I go to paste elsewhere, the clipboard image taken is a weird mix of my RStudio background with only part of the table. It is like my computer is clipping the wrong part of my screen. I have double checked and this does not happen when I try to do the same thing with ggplot(). I've attached my code as an example and what I receive as my output. I have instead been saving these plots as images (and this works fine!) but I really don't need these plots/just would like to copy them.
hectare <- PlantGrowth %>%
mutate(hectare = weight/10000)
partbtab <- hectare %>%
group_by(group) %>%
summarise("Mean/Yr" = mean(hectare),
"25 Year Average" = `Mean/Yr`*25)
kable(partbtab) %>%
kableExtra::kable_styling()
#this also does the weird screenshot
gt(partbtab)
This is what the copied "plot" ends up as:
I've been knitting to a Word Document from an .rmd file using papaja. I have found that when there is a blank cell in a row, that particular row's height is disproportionately taller than rows without. I've set up my .rmd using the provided template from papaja.
This table produces a normal looking table in a word document:
data <- mtcars
table_1 <- data %>%
group_by(vs) %>%
summarise("Mean cyl" = mean(cyl), "Mean wt" = mean(wt))
apa_table(table_1, caption = "Table 1 with no blank space")
However, if I remove one of the column headers and replace it with just an empty character string, like this:
table_2 <- table_1
colnames(table_2) <- c("","Mean cyl","Mean wt")
apa_table(table_2, caption = "Table 2 with a blank space")
The row that the blank space is in is much taller than the table without the blank space. I've played around with it and it also happens when I just use kable() to knit a table, so it might have something to do with kable. I'll attach a screenshot of what the two tables look like. Oh, bonus question, is there any way to put "Table X:" and the table caption on the same line? Tables rendered in a word doc
I can confirm that this happens in Word. However, the this doesn't seem to be caused by apa_table() or papaja. If you create a table in pandoc-syntax by hand, you get the same behavior, both with apa6_docx() and the standard word_document()-output format, albeit less pronounced in the latter because of the tighter line spacing.
Table: Table 2 with a blank space
Mean cyl Mean wt
--- --------- ---------
0 7.444444 3.688556
1 4.571429 2.611286
So, this may be unintended behavior in pandoc and you could try opening an issue on GitHub.
As workaround you can use non-breaking space as column header:
colnames(table_2) <- c("\\ ","dsfasdf","Mean wt")
apa_table(table_2, caption = "Table 2 with a blank space")
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
I have a flextable object called html_table which I want to directly put in a word document, in horizontal layout with narrow margins.
I face 2 problems:
1) The approach suggested in the vignette produces extra pages (one before, one after the table). I think this is a known issue but not clear how to solve it.
2) I would like to have narrow margins and the resulting table on horizontal pages to be automatically fitted to the page. I want this so that I can print the table using as much page as I can. My current approach is to manually open the document, change the layout and select "autofit" on Word.
Here's the code I'm using to produce the document. For illustrative purposes, I will use mtcars for my table, but the real one has more rows than mtcars.
html_table <- regulartable(mtcars)
doc <- read_docx() %>%
# Make it landscape
body_end_section_continuous() %>%
# Add the table
body_add_flextable(value = html_table,
split = TRUE
) %>%
body_end_section_landscape()
# Write the .docx
print( doc, target = "my_table.docx" )
In Word document, sections are only defined when they stop (I can not explain why it has been made that way but this is how the underlying xml is...). Also a landscape oriented section need a page break if the preceding section is not landscape oriented.
To autofit a flextable, use function autofit.
library(flextable)
library(officer)
library(magrittr)
html_table <- regulartable(mtcars) %>%
autofit()
doc <- read_docx() %>%
body_add_flextable(value = html_table, split = TRUE) %>%
body_end_section_landscape() %>% # a landscape section is ending here
print( target = "my_table.docx" )
If you don't want extra page, you will need a template with a default page orientation as landscape. Also, you would not need any code to manage orientation nor margins.
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")