After writing some more for a manuscript I decided to formalise my workflow where I output numerical variables from R for use in LaTeX, so if the values change they update automatically in the manuscript. Below is a collection of functions which make the process easier:
Formatting a number with the correct number of decimal points or significant figures:
num_format <- function(x, digits = 2, method = "round"){
sprintf(paste0("%.",digits,"f"),
if(method == "round"){
round(x, digits = digits)
}else if(method == "signif"){
signif(x, digits = digits)
})
}
Formatting a p-value:
p_format <- function(p, digits = 2){
dplyr::case_when(p < 0.01 ~ "p<0.01",
p < 0.05 ~ "p<0.05",
TRUE ~ paste0("p = ", as.character(num_format(p, digits = digits)))
)
}
p_format(1.1)
= “p = 1.10”p_format(0.025)
= “p<0.05”p_format(0.494, digits = 1)
= “p = 0.5”
Extracting the slope and standard error from a linear regression:
lm_format <- function(x, digits = 2){
paste0("F(",
summary(x)$fstatistic[2],
",",
summary(x)$fstatistic[3],
") = ",
num_format(summary(x)$fstatistic[1], digits = digits),
", ",
p_format(anova(x)$`Pr(>F)`[1])
)
}
mod1 <- lm(mtcars$mpg ~ mtcars$hp
lm_format(mod1)
= “F(1,30) = 45.46, p<0.01”
Formatting two arbitrary numbers as x plus/minus y:
pm_format <- function(x, y, dx = 2, dy = dx + 1, pm = "$\\pm$"){
paste0(num_format(x, digits = dx),
pm,
num_format(y, digits = dy)
)
}
pm_format(0.3332, 0.4673)
= “0.33$\pm$0.467”pm_format(0.3332, 0.4673, dx = 1, dy = 3)
= “0.3$\pm$0.467”
Output the value of a variable as a LaTeX variable:
command_output <- function(x, name){
paste0("\\newcommand{\\",
ifelse(missing(name), deparse(substitute(x)), name),
"}{",
x,
"}"
)
}
x <- 0.4367
command_output(x)
= “\newcommand{\x}{0.4367}”command_output(x, "test")
= “\newcommand{\test}{0.4367}”
Notice that all the backslashes have to be duplicated to escape them when they are written to a file.
Write a list of commands to a .tex file:
latex_write <- function(list, path){
fileConn <- file(path)
writeLines(
unlist(list, use.names = FALSE), fileConn)
close(fileConn)
}
Full example:
val1 <- 0.55
val2 <- 0.2477
val3 <- 0.044
values_list <- list(val1 = val1, val2 = val2, val3 = val3)
command_list <- list()
for(i in 1:length(values_list)){
command_list[[i]] <- command_output(
num_format(
values_list[[i]]
),
names(values_list[i])
)
}
latex_write(command_list, "test.tex")