arsenal icon indicating copy to clipboard operation
arsenal copied to clipboard

tableby: merge tables on columns/cbind

Open konstruktur opened this issue 5 years ago • 1 comments

Hi!

Thanks for the arsenal package and especially the tableby function that makes (life and) creating large weighted summary tables much easier!

I am looking for a way to merge tables columnwise, in my case to display unweighted and weighted descriptive statistics side by side to show the effect of the weights. I think about creating the same table with(out) weights and then kind of cbind() them. Is this possible with tableby yet? I found merge() which connects tableby-objects with the same by-Variables (https://cran.r-project.org/web/packages/arsenal/vignettes/tableby.html#merge-two-tableby-objects-together), but I did not find a way to merge tables with the same rows (did I overlook it?).

I found one solution at https://github.com/eheinzen/arsenal/issues/178, but this does not work completely if we want to knit to both pdf and html with the same code (since we define text = "latex" inside summary() for knitting to pdf and this produces the necessary spacing via "~~~". If we change the code and leave out text = "latex" we can knit to html).

So I think It would be really great to have a cbind()-like function for this task that takes care of merging columnwise before summary() - do you have plans to implement such a function?

Remark: I found out that the compareGroups package has this functionality (https://cran.r-project.org/web/packages/compareGroups/vignettes/compareGroups_vignette.html#combining-tables-by-column-strata) but it seems to lack the option to use case weights (which I have to use most of the time). So tableby() seems closer to my needs.

Thanks a lot for your great work on arsenal! Best, G

---
title: "arsenal::tableby()"
subtitle: "Merge tables on columns: knit pdf"
output:
  pdf_document: default
---

```{r}
library(knitr)

# Example: unweighted and weighted statistics side by side

## Create table objects

library(arsenal)
data(mockstudy)
mockstudy$dummyby1 <- "Unweighted"  # Name the column (instead of "Overall") https://github.com/eheinzen/arsenal/issues/253
mockstudy$dummyby2 <- "Weighted"  # As above, but for the 2nd table
mockstudy$w <- rnorm(n = nrow(mockstudy), mean = 1, sd = .2)  # Create some random weights
tab1 <- tableby(dummyby1 ~ age + sex, data = mockstudy, test = FALSE, total = FALSE)  # Build tab1 (unweighted)
tab2 <- tableby(dummyby2 ~ age + sex, data = mockstudy, test = FALSE, total = FALSE, weights = w)  # Build tab2 (weighted)


## Merge tables
#Since both tables have the same rows we can merge them. 
# (Remark: In the example at  https://github.com/eheinzen/arsenal/issues/178 two tables with unequal number of rows are merged). The result looks like two tables side by side rather than one merged table. Positioning via kableExtra latex_options = c("hold_position") does not work (Error: "! LaTeX Error: Not in outer par mode.")

### Merge tables for knitting pdf without duplicated labels
# To avoid duplicated labels we can delete them.
df1 <- as.data.frame(summary(tab1, text = "latex"))
df2 <- as.data.frame(summary(tab2, text = "latex"))
df2[,1] <- NULL  #  Delete first rowname
dftotal <- cbind(df1, df2)  # Merge dfs
#str(dftotal)  # Inside dftotal
colnames(dftotal)[1] <- ""  # Delete 1st colname ("Var.1")

# Knit via kable(): visible "~~~"
kable(dftotal, escape = FALSE)


# Knit via kable() with Option booktabs = TRUE: nicer/less lines, but still visible "~~~"
kable(dftotal, escape = FALSE, booktabs = TRUE, linesep = "")


# Same with kableExtra(): gets rid of the visible "~~~"
library(kableExtra)
kable(dftotal, escape = FALSE, booktabs = TRUE, linesep = "") %>% 
  kable_styling()

konstruktur avatar Jan 05 '20 14:01 konstruktur

Upvoting. Thanks.

raheems avatar Apr 05 '21 16:04 raheems