Kable footnotes with math equation and alphabetic notes - r

I'm having trouble with kable and R Markdown. I would like to create a table with footnotes:
1. a bit of math formula (),
2. with alphabetical notes,
3. and I would like the notes a and b to also show up next to var_a and var_b in superscript.
I can make the table, but the moment I add the footnotes I get an error msg.
var_a <- rep(0, 3)
var_b <- rep(1,3)
var_c <- rep(2, 3)
df <- data.frame(var_a=var_a, var_b=var_b, var_c=var_c)
kable(df, "latex", caption = "title", booktabs = T) %>%
kable_styling() %>%
add_footnote("Standard errors in parenthesis. P-values in brackets.", "P-values from Wald-test for $H_0$ Hazard Ratio = 1.",
footnote_order = c("alphabet", "alphabet"))
EDIT:
This is the error msg I get:
Error in add_footnote(., "Standard errors in parenthesis. P-values in brackets.", :
unused argument (footnote_order = c("alphabet", "alphabet"))

To begin with, I'm not a big fan of the pipe operator, when you make complex functions you tend to miss some tiny issues, like putting your footnotes in a vector:
mytable <- kable(df, "latex", caption = "title", booktabs = T)
mytable <- kable_styling(mytable)
add_footnote(mytable,c("Standard errors in parenthesis. P-values in brackets.",
"P-values from Wald-test for $H_0$ Hazard Ratio = 1.") )
I delete footnote_order I don't understand why you use it? And I'm not able to make it work...
I you want footnote to generate $H_0$ instead of \$H\_0\$, you have to write:
add_footnote(mytable,c("Standard errors in parenthesis. P-values in brackets.",
"P-values from Wald-test for $H_0$ Hazard Ratio = 1."), escape = FALSE )

Related

knitr: how to print the visible parts of the expression in a custom code chunk using engine_output()?

I am creating a custom code chunk which rewrites the expressions that a user passes into the code block into valid R code, and then execute the analysis. Aside from the rewriting of the R expression that the user inputs, the goal is for the code chunk to work as a regular code chunk
I then execute the result and store it in a variable, which I am trying to output. I am running into two issues here:
It prints invisible variables
knit_print and engine_output do not seem to work with each other i.e. I want the output such as dataframes to be printed in the table format but I am not able to get it to work.
An example of what I am trying to do would be something like:
```{r}
custom_engine <- function(options) {
c = options$code
pasted <- paste(c, collapse = "\n")
code <- parse(text = pasted)
result = lapply(code, eval, envir = .GlobalEnv)
knit_print(result)
engine_output( options, code = c, out = NULL )
}
knitr::knit_engines$set(mmm = custom_engine)
```
```{r}
speed_data <- data.frame(
speed = rlnorm(100, log(200), 1),
device = sample(c("smartphone", "laptop", "tablet"), 100, TRUE, prob= c(0.1, 0.65, 0.25))
)
median = median(speed_data$speed)
iqr = IQR(speed_data$speed, na.rm=TRUE)
```
```{mmm}
result_analysis <- speed_data %>%
filter(speed < median + 3 * iqr & speed > 10) %>%
filter(device != "smartphone")
result_analysis
```
I would like the code above to print the table once, and in the default knit_print() format that RMarkdown does.
Any suggestions would be much appreciated.

knitr kable horizontal line not appearing in second last line pdf

library(knitr)
library(kableExtra)
df <- data.frame("r1" = c(1,2,3,4), "r2"=c(4,5,6,6), "r3"=c(7,8,9,8), "r4"=c(11,12,13,89))
kable(df, format = "latex", booktabs = T, linesep = c('','','\\hline'))
actually this code should get a horizontal line at the second last line
But, i am not getting it. Is this a bug in kable or anything else?
I am trying to get a line above the last line for total. I am using Knitr Kable for this and knitting to pdf. Please Help
As far as I know, this is not how linesep works for kable. Instead you could use xtable:
library(xtable)
df <- data.frame("r1" = c(1,2,3,4), "r2"=c(4,5,6,6), "r3"=c(7,8,9,8), "r4"=c(11,12,13,89))
print(xtable(df), hline.after = c(0,3))
Why it does not work
This is the internal code in kable that produces the linesep:
linesep = if (nrow(x) > 1) {
c(rep(linesep, length.out = nrow(x) - 2), linesep[[1L]], '')
} else rep('', nrow(x))
linesep = ifelse(linesep == "", linesep, paste0('\n', linesep))
In line 2 you can see that your linesep argument is going to be repeated nrow(x)-2 times. So if you pass linesep = c("", "", "\\hline") to kable and you only have 4 rows, then this vector will be repeated 2 times. But since the vectors length is greater than 2, it only uses the first 2 elements which are empty. At the end of the snippet you have an empty character vector with 4 elements and therefore no horizontal ruler appears.

How can I subscript names in a table from kable()?

Given a data.frame A, how can I use subscripted rows and columns names? Eventually I want produce a table through kable() in rmarkdown (output: word document).
A <- data.frame(round(replicate(3, runif(2)),2))
rownames(A) <- c("Hola123", "Hola234")
A
X1 X2 X3
Hola123 0.47 0.55 0.66
Hola234 0.89 0.45 0.20
How could I make all numbers from row and column names subscripted when creating a table through kable(A)?
I have tried:
rownames(A) <- c(expression(Hola["123"]), expression(Hola["234"]))
names(A) <- c(expression(X["1"]), expression(X["2"]), expression(X["3"]))
But it does not appears subscripted when creating the table through kable() in the .rmd file.
To add subscripts in a rmarkdown document, you can embed your text between two tilde: text~sub~.
When using function kable, any text in the table is recognized as markdown syntax. So that your rmarkdown code should be:
```{r}
A <- data.frame(round(replicate(3, runif(2)),2))
rownames(A) <- c("Hola~123~", "Hola~234~")
names(A) <- c("X~1~", "X~2~", "X~3~")
knitr::kable(A)
```
Just one note about bamphe's response is that the correct code is misspelled. It should be \\textsubscript{}. It is missing the second "t".
And completing the answer, you might choose to use the arguments row.names and col.names inside kable, in this way:
A <- data.frame(round(replicate(3, runif(2)),2))
rownames(A) <- c("Hola\\textsubscript{123}", "Hola\\textsubscript{234}")
knitr::kable(A,
row.names = T,
col.names = c("X\\textsubscript{1}", "X\\textsubscript{2}", "X\\textsubscript{3}"),
escape = F)
I, too, was looking for a method that would allow for subscript and superscript in both html and pdf formats in markdown tables with kable. After a bit of searching, I finally found the text reference method explained here by #yihui-xie : bookdownguide
(ref:foo) H~2~O where foo is the reference and H~2~O the text.
My code example shows how the text reference can be used. Make sure to follow the cardinal rules:
The reference needs to be unique throughout the document
The reference should not have a white space following the "to be inserted stuff"
The reference needs to be in its own paragraph and have an empty line both above and below it
Note that only the referenced "foo" and "fo" will give the subscripts while the ~[]~ method will only work in html but not pdf.
(ref:foo) CO~2~/CO~2~
(ref:fo) CO~2~
```{r chunk-to-show-the-text-reference-method, echo = FALSE }
library(dplyr)
library(knitr)
library(kableExtra)
# Make lists
dtmin_name <- c("ref/ref","refrigerant/CO2","(ref:foo)",paste0("ground/","(ref:fo)"),"ground/water","air/refrigerant","water/refrigerant","water/CO2")
temp_diff <- c( 2.3, 1.4, 0.8, 6.8, 14, 6, 4, 3.46)
# Make dataframe and column names
dtmin_df <- data.frame(dtmin_name,temp_diff, stringsAsFactors = FALSE)
colnames <- data.frame("Interface Type ", "dT~min~ Interval [K]", stringsAsFactors = FALSE)
colnames(dtmin_df) <- colnames
# Make Table
kable(dtmin_df, caption = "Typical dT~min~ Temperature Intervals", booktabs = TRUE, format.args = list(big.mark = ",")) %>%
kable_styling(bootstrap_options = c("striped", "hover"),latex_options = c("striped","scale_down"))```

Knitting an HTML file wont publish the inference command

I am currently doing a R course and I struggle with knitting an HTML file.
All the code works fine within RStudio. The file also knits properly, however it wont plot an output for the last command, when I run the inference. I added the code.
Any input is much appreciated.
Thanks
Markus
Firstly, we filter for the religions and the year of interest:
```{r filter}
gss2012 = gss %>%
filter(year =="2012")
gssCatPro2012 = gss2012 %>%
filter(relig=="Catholic" | relig=="Protestant")
```
Now we create a first histogram of both religions to get a first idea of the distributions:
{r plot both rel}
ggplot(data=gssCatPro2012, aes(x=childs))+geom_histogram()
Calculate ratio and represent in pie chart:
{r ratio}
gssCatPro2012 %>%
summarise(Catholicratio = sum(relig =="Catholic")/n())
percent <- c(32.64,67.36)
lbls <- c("Catholics", "Protestants")
pct <- round(percent/sum(percent)*100)
lbls <- paste(lbls, pct)
lbls <- paste(lbls,"%", sep="")
pie(percent, labels=lbls, col=rainbow(length(lbls)), main="Pie chart Catholics/Protestants")
Split data between religions:
{r split}
gssCat2012 = gssCatPro2012 %>%
filter(relig=="Catholic")
gssPro2012 = gssCatPro2012 %>%
filter(relig=="Protestant")
Plot first distribution of Catholics, then Protestants:
{r plot per religion}
ggplot(data=gssCat2012, aes(x=childs))+geom_histogram()
ggplot(data=gssPro2012, aes(x=childs))+geom_histogram()
Check if any NAs to clean:
{r NA}
anyNA(gssCatPro2012$childs)
completeFun <- function(data, desiredCols) {
completeVec <- complete.cases(data[, desiredCols])
return(data[completeVec, ])
}
gssCatPro2012=completeFun(gssCatPro2012,"childs")
anyNA(gssCatPro2012$childs)
Calculate means for both religions:
{r metrics}
gssCatPro2012 %>%
group_by(relig) %>%
summarise(mean_kids=mean(childs), med_kids=median(childs), sd_kids=sd(childs),n=n())
Inference
We are going to create a new variable in order to overwrite the content of the old variable relig:
{create new variable}
gssCatPro2012new <- gssCatPro2012 %>%
mutate(relignew = ifelse(relig == "Catholic", "Catholic", "Protestant"))
Now, we can run the inference function and see whether we can reject the 0 Hypothesis or not:
{hypothesis test}
inference(y = childs, x = relignew, data = gssCatPro2012new, statistic = "mean", type = "ht", null = 0, alternative = "twosided", method = "theoretical")
Modify the chunk names to use underscores instead of spaces and make sure each chunk begins with a leading "r".
For example:
{r create_new_variable}
instead of:
{create new variable}

knitr xtable highlight and add horizontal lines for the same row,

I am using knitr and xtable to automate my reporting procedure. I want to highlight a few rows of a table and have a horizontal line right above each row highlighted. The .Rnw file I am using reads as below:
\usepackage{colortbl, xcolor}
\usepackage{longtable}
\begin{document}
<<do_table, results = "asis">>=
library(xtable)
mydf <- data.frame(id = 1:10, var1 = rnorm(10), var2 = runif(10))
print(xtable(mydf), add.to.row = list(pos = list(0,2), command = rep("\\rowcolor[gray]{0.75}",2)),hline.after=c(0,2))
#
\end{document}
This works just fine, however, the table I am working with should be a longtable, if I adjust the last line of code to
print(xtable(mydf), add.to.row = list(pos = list(0,2), command = rep("\\rowcolor[gray]{0.75}",2)),hline.after=c(0,2),tabular.environment="longtable",floating=FALSE)
the output is quite ugly, and the rows are not highlighted as expected. Anyone might know an answer to this question?
thanks,
David
Sorry, slightly offtopic, but demonstrating a markdown-only solution for highlighting cells/rows easily:
> mydf <- data.frame(id = 1:10, var1 = rnorm(10), var2 = runif(10))
> library(pander)
> emphasize.strong.rows(c(1, 3))
> pander(mydf)
---------------------------
id var1 var2
----- ---------- ----------
**1** **0.7194** **0.6199**
2 0.8094 0.1392
**3** **-1.254** **0.5308**
4 0.4505 0.8235
5 -0.3779 0.7534
6 -0.3518 0.3055
7 1.759 0.5366
8 0.9822 0.9938
9 1.549 0.3589
10 -1.077 0.5153
---------------------------
That can be converted to LaTeX or pdf directly.
You are on the right track, but I am a bit confused: do you want the selected rows highlighted by hline and rowcolor? In my experience, rowcolor alone looks better, so I will assume that in my answer below (but you could easily use both, just append the \\hline command).
As a bonus, all code below assumes you use the LaTeX booktabs package, which gives correctly weighted rules (unlike hline). To be honest, I always work with booktabs, and I couldn't bother to adjust the code to use hline -- but if you prefer hline, replace all \toprule, \midrule and \bottomrule macros with \hline.
You seem to have missed that LaTeX longtables require a special header, and we need to supply that too as an element to the command vector of the add.to.row list (this may be the reason your typeset table looks bad).
longtable.xheader <-
paste("\\caption{Set your table caption.}",
"\\label{tab:setyourlabel}\\\\ ",
"\\toprule ",
attr(xtable(mydf), "names")[1],
paste(" &", attr(xtable(mydf), "names")[2:length(attr(xtable(mydf), "names"))], collapse = ""),
"\\\\\\midrule ",
"\\endfirsthead ",
paste0("\\multicolumn{", ncol(xtable(mydf)), "}{c}{{\\tablename\\ \\thetable{} -- continued from previous page}}\\\\ "),
"\\toprule ",
attr(xtable(mydf), "names")[1],
paste("&", attr(xtable(mydf), "names")[2:length(attr(xtable(mydf), "names"))], collapse = ""),
"\\\\\\midrule ",
"\\endhead ",
"\\midrule ",
paste0("\\multicolumn{", as.character(ncol(xtable(mydf))), "}{r}{{Continued on next page}}\\\\ "),
"\\bottomrule \\endfoot ",
"\\bottomrule \\endlastfoot ",
collapse = "")
With that taken care of, go ahead and print the xtable:
print(xtable(mydf),
floating = FALSE, % since longtable never floats
hline.after = NULL, % hline off since I use booktabs
add.to.row = list(pos = list(-1,
c(0, 2),
nrow(xtable(mydf))),
command = c(longtable.xheader,
"\\rowcolor[gray]{0.75}\n",
"%")), % comments out a spurious \hline by xtable
include.rownames = FALSE, % depends on your preference
include.colnames = FALSE, % depends on your preference
type = "latex",
tabular.environment = "longtable",
% xtable tries to escape TeX special chars, can be annoying sometimes
sanitize.text.function = function(x){x},
% not all dashes are meant to be math negative sign, set according to your data
math.style.negative = FALSE)
I hope my use of booktabs in the answer did not confuse you too much.
Keep knitting!
You might have more luck posting this on a latex forum. You should note that xcolor/longtable are not compatible: http://www.ukern.de/tex/xcolor.html.

Resources