How to display LaTeX symbols in Flextable (R) - r

I have generated the following table using the Flextable package in R. I created a conditionally formatted column with LaTeX arrow symbols in it, however the symbols aren't displayed when I generate it as a flextable. Is there a way to fix this?
library(tidyverse)
library(flextable)
data.frame(one = c(10,20,30), two = c(30,20,6)) %>%
mutate(Trend = case_when(.[,2] == .[,1] ~ "$\\rightarrow$", .[,2] > .[,1] ~ "$\\nearrow$", TRUE ~ "$\\searrow$")) %>%
flextable()

It may be easier to do this with unicode values for the symbols
library(dplyr)
library(flextable)
data.frame(one = c(10,20,30), two = c(30,20,6)) %>%
mutate(Trend = ifelse(two == one, "\U2192", "\U2190")) %>%
flextable()
-output

Related

gt table package in R produces header error

I am using the gt() table package in R and so far I love it. However for some reason when I publish the below in quarto I get an awkward table header that says "?caption" in bold. However when I run the table separately, I don't get anything.
Any thoughts?
Ignore the titles and columns names, I know it doesn't make sense with the diamonds package
library(tidyverse)
library(gt)
business_segment_summary <- diamonds %>%
group_by(cut) %>%
summarise(n=n(),
sum=sum(price),
sum_od=sum(price,na.rm=TRUE),
prop_25=quantile(price,.25,na.rm=TRUE),
prop_50=quantile(price,.5,na.rm=TRUE),
prop_75=quantile(price,.75,na.rm=TRUE),
mean=mean(price,na.rm=TRUE),
mean_aging=mean(table),
mean_rank=mean(depth),
prop_od=mean(carat),
sd=sd(price,na.rm=TRUE),
mad=mad(price,na.rm=TRUE),
.groups="drop"
) %>%
mutate(tar_prop=sum/sum(sum),
n_prop=n/sum(n))
business_segment_summary %>%
select(1,n,tar_prop,n_prop,prop_od,prop_25,prop_50,prop_75) %>%
gt::gt()
gt::cols_label(cut="Business Segment",
n="Customer #",
tar_prop="% of TAR",
n_prop="% of Customers",
prop_od=gt::html("% of Customers<br>with overdue"),
prop_25="25%",
prop_50="50%",
prop_75="75%") %>%
gt::tab_spanner(label="Customer Account Percentile ($k)",columns = c(prop_25,prop_50,prop_75)) %>%
gt::fmt_number(c(prop_25,prop_50,prop_75),decimals = 0,scale_by = 1/1e3) %>%
gt::fmt_number(n,decimals = 0) %>%
gt::fmt_percent(c(3:5),decimals = 0) %>%
gt::opt_stylize(style=1,color="red") %>%
gt::tab_header(title="Summary of TAR by business segments") %>%
gt::cols_align(align="left",columns = 1)

How to force linebreaks in kableExtra functions with escape = FALSE?

In kableExtra >= 0.8.0, the canonical way to insert a linebreak into text piped into a table from a kableExtra function such as add_header_above or pack_rows is to add an \n directly.
However, this appears not to work with the escape = FALSE argument, which is required if the text also contains LaTeX code.
How can one force linebreaks in kableExtra functions with escape = FALSE?
library(dplyr)
library(knitr)
library(kableExtra)
starwars %>%
filter(species == 'Gungan' | species == 'Droid') %>%
arrange(species) %>%
select(name, eye_color) %>%
kbl(booktabs = TRUE) %>%
pack_rows(
index = c(
'The droids: everybody\'s favourite' = 6,
'The Gungans: only beloved of \nthose aged under $3^2$' = 3),
escape = FALSE)
ISSUE
The issue at hand is that you wish to escape part of your header (i.e., the break) and not escape another part (i.e., the math code).
Further Complications
This core issue is further complicated by a number of factors:
when and how kableExtra is programmed to deal with escaping
a desire to have a solution that works for both html and LaTeX output
when and how R evaluates code
A SOLUTION
Here is a solution that will work for both html and LaTeX output, but it is not as clean and straight forward as your original code:
# a new version of `kableExtra::linebreak()` that takes into account what type
# of output is desired as well as how much escaping is necessary
linebreak2 <- function(x, double_escape = TRUE, ...) {
# if LaTeX insert text into a `\makecell[]{}` command and double escape
if(knitr::is_latex_output())
return(linebreak(x, double_escape = double_escape, ...))
# if html output just replace `\n`s with `<br/>`s
if(knitr::is_html_output())
return(gsub("\n", "<br/>", x))
# let x pass through for other types of output
return(x)
}
# build the index named vector outside the pipe flow
# in order to set the names using `linebreak2()`
index <- c(6, 3)
names(index) <- c(
'The droids: everybody\'s favourite',
linebreak2('The Gungans: only beloved of \nthose aged under $3^2$')
)
# proceed as before
starwars %>%
filter(species == 'Gungan' | species == 'Droid') %>%
arrange(species) %>%
select(name, eye_color) %>%
kbl(booktabs = TRUE) %>%
pack_rows(index = index, escape = FALSE)
PDF Output
HTML Output
You could use html line break tag <br/>:
starwars %>%
filter(species == 'Gungan' | species == 'Droid') %>%
arrange(species) %>%
select(name, eye_color) %>%
kbl(booktabs = TRUE) %>%
pack_rows(
index = c(
'The droids: everybody\'s favourite' = 6,
'The Gungans: only beloved of <br/> those aged under $3^2$' = 3),
escape = FALSE)

How to generate "pretty" output from the str() function in R

I have a moderate-sized data set that is 1000 rows by 81 columns. I'd like to use the output from str(), but I'd like to present it in a "prettier" way. I've tried things like this:
df %>% str() %>% kableExtra::kbl() %>% kableExtra::kable_minimal()
and
tbl_summary(as.data.frame(str(df)))
but neither works. I'm not married to str() or to any specific package, but that's the kind of summary I'm going for.
In the end, this is intended to generate an HTML file, but I'd like it to work with PDF output as well.
Any ideas on how to do this?
Update II:
This can be achieved making use of this gist devtools::source_gist('4a0a5ab9fe7e1cf3be0e')
<devtools::source_gist('4a0a5ab9fe7e1cf3be0e')>
print(strtable(iris, factor.values=as.integer), na.print='') %>%
kable() %>%
htmlTable()
Update I:
you could extend:
data.frame(variable = names(iris),
class = sapply(iris, typeof),
levels = sapply(iris, class),
first_values = sapply(iris, function(x) paste0(head(x), collapse = ", ")),
levels_values = sapply(iris, function(x) paste0(unique(x), collapse =", ")),
row.names = NULL) %>%
kable() %>%
htmlTable()
First answer:
Something like this using iris dataset:
library(knitr)
library(magrittr)
library(htmlTable)
data.frame(variable = names(iris),
classe = sapply(iris, typeof),
first_values = sapply(iris, function(x) paste0(head(x), collapse = ", ")),
row.names = NULL) %>%
kable() %>%
htmlTable()
skimr and gt (or kable, or flextable, or DT, or many other table packages) could also work here:
mtcars |>
skimr::skim() |>
gt::gt()

Rows not grouping in LaTeX rendering with pander

When I render the following table as HTML, I get expected row grouping:
library(expss)
library(dplyr)
library(pander)
library(knitr)
test_data =
data.table(
division = c(rep("A",5),rep("B",5)),
group = rep(c(rep("alpha",2),rep("beta",3)),2),
subgroup = c("red","orange","yellow","green","blue",
"indigo","violet","black","white","brown"),
ins = rnorm(10),
outs = runif(10),
overs = seq(1,100,10)
)
test_data = apply_labels(test_data,
division = "Department",
group = "Center",
subgroup = "Team",
ins = "In-flow",
outs = "Out-flow",
overs = "Throughput")
test_table =
test_data %>%
tab_cells(ins,
outs,
overs) %>%
tab_cols(division %nest% group %nest% subgroup) %>%
tab_stat_fun(identity) %>%
tab_pivot() %>%
drop_rc() %>%
tab_transpose()
test_table
However, when I render it as a PDF, the row grouping fails, replaced with long strings of pipe-delimited characters.
pander(test_table)
I think this is more of a LaTeX than R problem, but I'm not sure if it doesn't lie in the middle with pander. I would prefer to output this as a PDF, given preferences from folks "up the ladder".
Default output of the expss doesn't support pdf/latex. But there is an excellent package huxtable which works with pdf:
So you need to use as_huxtable:
library(huxtable)
as_huxtable(test_table)

Mathematical units in gt table with Rmarkdown

I have this dataframe:
df = data.frame(a = c("$B_{a}$", "$m^{a}$"))
When I make a table using kable in Rmarkdown like so:
df %>% knitr::kable()
and knit it to a pdf_document, I get this:
which is what I expected.
Now, I want to reproduce the same table, but using the package gt. When I do:
library(gt)
df %>% gt()
I get this:
What else do I have to do that so that gt table "understands" these are mathematical notations?
The <sub></sub> and <sup></sup> works with gt. One option is to replace the characters in the original dataset column with html syntax using str_remove/str_replace from stringr
library(gt)
library(stringr)
library(dplyr)
df %>%
mutate(a = str_remove_all(a, "[{}$]") %>%
str_replace_all( c('(.)_(.)', "(.)\\^(.)"),
c("\\1<sub>\\2</sub>", "\\1<sup>\\2</sup>"))) %>%
gt() %>%
fmt_markdown(columns = everything())
-output

Resources