Rapporter / pander

An R Pandoc Writer: Convert arbitrary R objects into markdown
http://rapporter.github.io/pander/
Open Software License 3.0
294 stars 66 forks source link

Support for sjPlot #298

Open FrauH0lle opened 7 years ago

FrauH0lle commented 7 years ago

I would like to ask if it would be possible to support the sjPlot package, more specifically the sjtable function (http://www.strengejacke.de/sjPlot/sjtbasics/ and https://github.com/strengejacke/sjPlot). The reason is, that sjPlot seems to support the widest range of R models for printing summary tables (e.g. lme4 objects) and generates a very pleasant table style. However, it only generates HTML output which does not render correctly when trying to knit to pdf. Would it be possible to develop a wrapper around sjPlot which translates the html into proper latex?

gorkang commented 4 years ago

Same here. The sjPlot tables are great, but I am not sure how to "easily" convert them to latex (e.g. to use them in Overleaf).

My very hacky approach has been the following. I am posting it here in case it helps someone.

library(lme4)
library(sjPlot)
library(XML)
library(RCurl)
library(rlist)
library(janitor)
library(dplyr)
library(knitr)

# This is a terrible model
model = lmer(mpg ~ cyl * disp + (1|vs), mtcars)

# We save the sjPlot table to an .html file (see the table below)
sjPlot::tab_model(
  model,
  show.r2 = TRUE,
  show.icc = FALSE,
  show.re.var = FALSE,
  p.style = "scientific",
  emph.p = TRUE,
  file = "Downloads/temp.html")
mpg
Predictors Estimates CI p
(Intercept) 49.04 39.23 – 58.85 1.144e-22
cyl \-3.41 \-5.05 – -1.76 5.058e-05
disp \-0.15 \-0.22 – -0.07 2.748e-04
cyl \* disp 0.02 0.01 – 0.03 1.354e-03
N vs 2
Observations 32
Marginal R2 / Conditional R2 0.809 / NA

Now we can read the .html file and clean it up a bit:


tables <- list.clean(readHTMLTable("~/Downloads/xxx.html"), fun = is.null, recursive = FALSE)
tables2 = tables[[1]] %>% janitor::row_to_names(row_number = 1)
tables2 <- as.matrix(tables2) %>% as_tibble()
tables2[is.na(tables2)] <- ""

So now we have the html table in a "clean" dataframe, and we can use kable() to see it in the terminal


knitr::kable(tables2, format = "pipe")
Predictors Estimates CI p
(Intercept) 49.04 39.23 – 58.85 1.144e-22
cyl -3.41 -5.05 – -1.76 5.058e-05
disp -0.15 -0.22 – -0.07 2.748e-04
cyl * disp 0.02 0.01 – 0.03 1.354e-03
N vs 2
Observations 32
Marginal R2 / Conditional R2 0.809 / NA

With this last kable() call we can create the latex code below, which is a reasonable approximation to the initial table... any improvements would be greatly welcome.


kable(
  tables2,
  format = "latex",
  booktabs = TRUE,
  col.names = names(tables2),
  align = c("l", rep("c", length(names(tables2)) - 1)),
  caption = "Means and Standard Deviations of Scores on Baseline Measures"
)
\begin{table}

\caption{\label{tab:}Means and Standard Deviations of Scores on Baseline Measures}
\centering
\begin{tabular}[t]{lccc}
\toprule
Predictors & Estimates & CI & p\\
\midrule
(Intercept) & 49.04 & 39.23 – 58.85 & 1.144e-22\\
cyl & -3.41 & -5.05 – -1.76 & 5.058e-05\\
disp & -0.15 & -0.22 – -0.07 & 2.748e-04\\
cyl * disp & 0.02 & 0.01 – 0.03 & 1.354e-03\\
N vs & 2 &  & \\
\addlinespace
Observations & 32 &  & \\
Marginal R2 / Conditional R2 & 0.809 / NA &  & \\
\bottomrule
\end{tabular}
\end{table}