I would like to have a footnote in a cell of a latex table. Usually I would do it with:
... & $^{1)} $ ...
How can I get this using xtable? The following is a minimal example and I tried several ways to get what I want:
\documentclass[9pt]{article}
\begin{document}
<<echo=TRUE>>=
df0 <- data.frame(x=c(1:5), y=c('a','b','c','d','e'))
df0$y <- as.character(df0$y)
df0$y[df0$y=="a"] <- "$^{1)}$"
df0$y[df0$y=="b"] <- "$\\^{2)}$"
df0$y[df0$y=="c"] <- "$^3$"
df0$y[df0$y=="d"] <- "$\\^4$"
df0$y[df0$y=="e"] <- "\\$\\^4\\$"
df0
#
<<echo=FALSE, results="asis">>=
xtable(df0)
#
\end{document}
Any hint appreciated.
See ?print.xtable and check out the sanitize options.
Use your original LaTeX method of inclusion then something like this should work...
<<echo=FALSE, results="asis">>=
require(xtable)
tbl <- xtable(df0)
print(tbl, type="latex", sanitize.text.function=function(x){x})
#
Related
I have a 500 x 500 dataset which I would like to be represented in kables in my PDF output. I've arbitrarily chosen 50 x 50 Kables for the output.
Each kabel cell will have an image in it^. Some of these examples will work with pure text so including the image is required in the minimum code.
In the code below, there is the setup and the 3 approaches I've taken:
the 500x500 approach which is obviously too big,
the list method which I can't get to actually render the tables,
the separate, dynamically named, objects^ approach which will render a table if called by exact name but can't get to render from a dynamic name.
The generation of the kables are in different code chunks to the output for ease of positioning in the PDF.
I have tried all these with results = 'asis' and it made no difference.
---
title: "Minimum Example"
date: "2022-11-19"
output: pdf_document
---
\section*{A Bit of Setup}
\renewcommand{\arraystretch}{1.7}
```{r setup}
library(kableExtra)
library(dplyr)
library(tidyr)
library(stringr)
library(png)
library(knitr)
# Image is displayed in each cell of the Kable, creating an example image
png(file="./ExampleImage.png")
par(bg='grey')
bob <- plot.new()
dev.off()
# Define size of data which needs to be represented in a kable.
totalSize_x <- 500
totalSize_y <- 500
```
\section*{Approach 1: Way too big to be displayed}
```{r Approach 1: The Big Boy}
TheBigBoi <- matrix('\\includegraphics[scale=1]{./ExampleImage.png}',totalSize_x, totalSize_y)
kable(TheBigBoi,
format = "latex",
escape = FALSE,
longtable = FALSE) |>
column_spec(1,border_left = T) |>
column_spec(totalSize_y,border_right = T) |>
kable_styling(latex_options=c("scale_down"))
# Gives the Errors
# Error: C stack usage 12426279 is too close to the limit
# Execution halted
```
\section*{Approach 2: A Nice List}
```{r Approach 2: A Nice List}
# Personally, I want this one to work as it's the least stupid solution.
maxKableCells <- 50 # As in that looks good for the images, I understand Kables can be bigger if they want to
TheLittleOne <- matrix('\\includegraphics[scale=1]{./ExampleImage.png}', maxKableCells, maxKableCells)
num_iterations <- (totalSize_x/maxKableCells) * (totalSize_y/maxKableCells)
myList <- vector(mode = "list", length = num_iterations)
for (i in 1:(num_iterations)){
myList[i] <- kable(TheLittleOne,
format = "latex",
escape = FALSE,
longtable = FALSE) |>
column_spec(1,border_left = T) |>
column_spec(maxKableCells,border_right = T) |>
kable_styling(latex_options=c("scale_down"))
}
```
Gonna put some text here
```{r Approach 2 Output}
myList[1] # - ! Undefined control sequence.
#l.177 ``\textbackslash begin\{table\}\n
# \textbackslash centering\n\textbacksl...
```
```{r Approach 2 Output Continued}
noquote(myList[1]) # - just prints out the latex code with extra slashes
```
\section*{Approach 3: Objectively the worst way to acheive this}
```{r Approach 3: Individual Kable Objects AKA Foolishness}
# The most stupid solution but the closest to working
maxKableCells <- 50 # As in that looks good for the images, I understand Kables can be bigger if they want to
TheLittleOne <- matrix('\\includegraphics[scale=1]{./ExampleImage.png}', maxKableCells, maxKableCells)
num_iterations <- (totalSize_x/maxKableCells) * (totalSize_y/maxKableCells)
for (i in 1:(num_iterations)){
assign(paste0('kable_', i), kable(TheLittleOne,
format = "latex",
escape = FALSE,
longtable = FALSE) |>
column_spec(1,border_left = T) |>
column_spec(maxKableCells,border_right = T) |>
kable_styling(latex_options=c("scale_down")))
}
```
Some filler text
```{r Approach 3 Output}
kable_1 # - This one works!
for (i in 1:num_iterations){
paste0('kabel_', i) #Returns nothing
print(paste0('kabel_', i)) # Prints like "kabel_1"
print(noquote(paste0('kabel_', i))) #Prints like kabel_1
noquote(paste0('kabel_', i)) # Returns nothing
}
```
^ I am aware this is a stupid thing to do, this whole thing is stupid but sometimes the tools we use are not our own choice.
I am creating a document with Rmarkdown. The document will have lots of different versions and all of the text for the different versions has been written in an Excel spreadsheet, which is then read into the Rmarkdown file. Inside the text, which sometimes differs between reports, there are keywords in square brackets which need to be replaced with r code. I am having trouble getting the rcode to evaluate inside the text and print out properly in the Rmarkdown output.
# Text like that in the Excel spreadsheet
report_text <- ("There are [NumberFruit] fruits in the fruitbowl. [HighestPercent]% of the fruit are [HighestPercentType].")
#Extract variables within the square brackets
variables <- str_extract_all(report_text, "\\[[A-Z,a-z]+\\]")
# Define all varaibles - the variables are the same in each report. The data in the actual report differs and is defined from a dataframe.
for (i in unlist(variables)){
if(grepl("NumberFruit", i)){
NumberFruit <- 10
} else if(grepl("HighestPercent", i)){
HighestPercent <- 56
} else if(grepl("HighestPercentType", i)){
HighestPercentType <- "apples"
} else if (length(unlist(variables)) > 3){
stop("Additional VARIABLE:",i, "has not been assigned")
}
}
Once the variables have been defined I would normally use something like below, but as the text isn't hardcoded into the Rmarkdown file this approach isn't possible.
final_text <- paste0("There are ",NumberFruit, " fruits in the fruitbowl. ",HighestPercent, "% are ",HighestPercentType, ".")
So I have tried formatting the text as per the paste option above, but this does not produce the desired output.
report_text2 <- gsub('\\[', '",',(gsub('\\]', ', "', report_text)))
#Also tried
report_text2 <- paste0(gsub('\\[', '",',(gsub('\\]', ', "', report_text))))
I then use r final text in the Rmarkdown text to create the text in the report. Both versions of the above code have the same result shown below.
Current Rmarkdown output: There are ",NumberFruit," fruits in the fruitbowl. ",HighestPercent, "% of the fruit are ",HighestPercentType, "."
Desired Rmarkdown output: There are 10 fruits in the fruitbowl. 56% of the fruit are apples.
I have googled for clues on what else to try but have not been able to find anything and am a bit stuck on where to go from here. Any advice on how to get this working would be greatly appreciated. I do not normally deal with text strings and feel like I am missing something fundamental here.
If we need to interpolate the variables created in RMD file, an option is with glue
library(glue)
library(stringr)
final_text <- glue::glue(str_replace_all(str_replace_all(report_text,
"\\[", "{"), "\\]", "}"))
Full code in RMD file
---
title: "test"
author: "akrun"
date: "16/03/2021"
output: html_document
---
```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
## R Markdown
```{r test1}
report_text <- "There are [NumberFruit] fruits in the fruitbowl. [HighestPercent]% of the fruit are [HighestPercentType]."
NumberFruit <- 10
HighestPercent <- 56
HighestPercentType <- "apples"
```
```{r test2}
library(stringr)
final_text <- glue::glue(str_replace_all(str_replace_all(report_text, "\\[", "{"), "\\]", "}"))
```
`r final_text`
-output
The following content of a .Rmd file:
---
title: "Untitled"
output:
html_document: default
---
```{r cars}
mtcars$am <- sprintf("(%s)", as.character(mtcars$am))
knitr::kable(mtcars, format = "html")
```
Will show ordered lists <ol><li></li></ol> in the am column, instead of the numbers in brackets (as produced with the sprintf) after rendering to html.
Is this intended? How can I work around this and have numbers in brackets show as they are in the html output?
The output of knitr::kable seems to be fine, showing:
<td style="text-align:left;"> (1) </td>
Details:
Using knitr 1.20
RStudio Server 1.1.453
note that removing format = "html" does not resolve the issue as in the real-life context I would like to do advanced formatting with css e.g. based on the classes of the produced tables
A quick workaround solution based on Michael Harper's accepted answer may be a method like so:
replacechars <- function(x) UseMethod("replacechars")
replacechars.default <- function(x) x
replacechars.character <- function(x) {
x <- gsub("(", "(", x, fixed = TRUE)
x <- gsub(")", ")", x, fixed = TRUE)
x
}
replacechars.factor <- function(x) {
levels(x) <- replacechars(levels(x))
x
}
replacechars.data.frame <- function(x) {
dfnames <- names(x)
x <- data.frame(lapply(x, replacechars), stringsAsFactors = FALSE)
names(x) <- dfnames
x
}
Example use:
mtcars <- datasets::mtcars
# Create a character with issues
mtcars$am <- sprintf("(%s)", as.character(mtcars$am))
# Create a factor with issues
mtcars$hp <- as.factor(mtcars$hp)
levels(mtcars$hp) <- sprintf("(%s)", levels(mtcars$hp))
replacechars(mtcars)
If you don't want to remove the format="html" argument, you could try using the HTML character entities for the parentheses (&lpar and &rpar) and then add the argument escape = FALSE:
```{r cars}
mtcars$am <- sprintf("(%s)", as.character(mtcars$am))
knitr::kable(mtcars, format = "html", escape = FALSE)
```
Still not entirely sure of what is causing the error though. It seems that the specific combination of parentheses is being processed strangely by knitr.
An alternative solution is to escape the parentheses, e.g.,
mtcars$am <- sprintf("\\(%s)", as.character(mtcars$am))
Then you won't need escape = FALSE.
See https://pandoc.org/MANUAL.html#backslash-escapes in Pandoc's Manual.
I'm trying to get the results of the table command nicely printed on a pdf by using knitr and xtable.
As a toy example let's say I want to get the table created with
table(c(2,5,5,5,5,7,7,7,7,NA),c(1,5,2,2,2,2,7,7,NA,NA))
I would like to get something like this:
As you can see var1 is rotated 90 degrees counterclockwise.
How can I get it?
Similar results, with less or more lines are OK too.
I've being trying different methods I've found.
I've created this Rnw file,
\documentclass{article}
\usepackage{booktabs}
\usepackage{rotating}
\begin{document}
<<r table, results='asis', echo=FALSE>>=
library(knitr)
library(xtable)
var1 <- c(2,5,5,5,5,7,7,7,7,NA)
var2 <- c(1,5,2,2,2,2,7,7,NA,NA)
print(xtable(table(var1,var2)))
print.xtableFtable(xtableFtable(ftable(var1,var2),
method = "row.compact"))
print.xtableFtable(xtableFtable(ftable(var1,var2),
method = "row.compact"), rotate.rownames = TRUE)
print.xtable(xtable(table(var1,var2)), include.rownames=T,include.colnames=T)
#
\end{document}
You can see below the result of the three methods I've tried.
I can't get the expected result.
Any solution with other common package or kable it's OK too.
I guess it could be done with \rotatebox{90} but I don't know how to force xtable to use it nor how to tell xtable to place the left title on the left instead of just being on the top-right.
Here's one possibility. Disclaimer: I am the package author.
library(huxtable)
var1 <- c(2,5,5,5,5,7,7,7,7,NA)
var2 <- c(1,5,2,2,2,2,7,7,NA,NA)
tbl <- table(var1 = var1, var2 = var2)
ht <- as_hux(tbl)
ht <- cbind(rep('', 4), ht)
ht[2,1] <- 'var1'
ht <- rbind(rep('', 6), ht)
ht[2,2] <- '' # get rid of "rownames"
ht[1,3] <- 'var2'
colspan(ht)[1,3] <- 4
rowspan(ht)[3, 1] <- 3
rotation(ht)[3, 1] <- 90
right_border(ht)[,2] <- 1
bottom_border(ht)[5, -1] <- 1
bottom_border(ht)[2, -1] <- 1
ht
When used in an rmarkdown PDF document, this produces:
So my problem statement is as follows :
I have defined a data frame in my Sweave document (.Rnw extension) using the following code:
<<label=table2_1,echo=FALSE>>=
table2_1_rows <- c('Students with compulsory Evaluations',
'Teachers with compulsory evaluations1',
'Teachers without Evaluation2',
'Students without compulsory evaluations3'
)
table2_1_data <- c(1,2,3,4)
table2_1final <- data.frame(table2_1_rows,table2_1_data)
#
<<label=tab1,echo=FALSE,results=tex>>=
print(xtable(table2_1final,caption= ' ',align="|c|c|c|c|c|c|"),include.rownames=FALSE)
#
How do I make xtable print the numbers 1,2,3 (following the word Evaluation) as superscripts?
The actual superscript is quite easy. \\textsuperscript{1} in conjunction with sanitize.text.function = identity will get you there.
I had to make some other changes to your example. There are too many columns in align and the underscores in the variable names cause problems compiling tex.
<<label=table2_1,echo=FALSE>>=
require(xtable)
table2_1_rows <- c('Students with compulsory Evaluations',
'Teachers with compulsory evaluations\\textsuperscript{1}',
'Teachers without Evaluation\\textsuperscript{2}',
'Students without compulsory evaluations\\textsuperscript{3}'
)
table2_1_data <- c(1,2,3,4)
table2_1final <- data.frame(table2_1_rows,table2_1_data)
names(table2_1final) <- c("rows", "data")
#
<<label=tab1,echo=FALSE,results=tex>>=
print(xtable(table2_1final,caption= ' ',align="|c|c|c|"),include.rownames=FALSE,
sanitize.text.function = identity)
#