18

What I want is to print nice crosstabulations, either in a pdf file, or in a html file, from RStudio, using R, Markdown and knitr. I suspect I am missing something really obvious, because I cannot believe this is so hard. I make cross-tabs with either xtabs or ftable.

What I want is something like a nicely printed version of the R console output.

> x
   Col
Row  A  B  C
  D 15  9  7
  E 13 14  9
  F  8  8 17
> f
    Col  A  B  C
Row             
D       15  9  7
E       13 14  9
F        8  8 17

I've tried several different solutions, none of which really works, and are shown in the attached .Rmd file. (I've tried pdf and html outputs.)

---
title: "trial"
author: "Anthony Staines"
date: "26/08/2014"
output: html_document
---
# Make the data
```{r, echo=TRUE,results='asis',message=FALSE}
library(knitr)
library(memisc)
library(xtable)
library(stargazer)
library(texreg)

set.seed(893)
Col <- sample(c('A','B','C'),100,replace=TRUE)
Row <- sample(c('D','E','F'),100,replace=TRUE)
```

```{r, echo=TRUE,results='asis',message=FALSE}
x <- xtabs(~Row+Col)
x
kable(x)
kable(x,format='html')
kable(x,format='html',output = TRUE)
xx <- xtable(format(x))
print(xx,type='html')
stargazer(x)

f <-ftable(Row,Col)
f
kable(f,format='html')
kable(f,format='html',output = TRUE)
xf <- xtable(format(f))
print(xf,type='html')
stargazer(f)
```

kable comes closest, but does not seem to support row or column names, both of which are essential to me :-

|   |  A|  B|  C|
|:--|--:|--:|--:|
|D  | 15|  9|  7|
|E  | 13| 14|  9|
|F  |  8|  8| 17|

Help appreciated, and my apologies if this is a really stupid question with an obvious and well known answer!

Anthony Staines

astaines
  • 872
  • 2
  • 9
  • 20
  • `kable()` does support column names; regarding row names, it does not seem to be a standard component of a table in either HTML or LaTeX, so it is unclear what "support" really means. – Yihui Xie Aug 27 '14 at 05:26
  • I agree that neither html nor latex directly support such labels, but for cross-tabs to make sense both are needed. The requirement is to produce a table usable to put into a journal article.What I actually do now is take the R console output, and turn into a table using the Table -> Convert -> Text to Table functions in Libre-Office, but this is not terribly repeatable! – astaines Sep 01 '14 at 18:50

4 Answers4

8

An alternative to kable is pander from the package with the same name, which provides an easy way of generating markdown tables with bunch of options (like style) and a generic S3 method:

> pander(x)

-------------------
&nbsp;   A   B   C 
------- --- --- ---
 **D**  15   9   7 

 **E**  13  14   9 

 **F**   8   8  17 
-------------------

> pander(f)

----- ----- --- --- ---
      "Col" "A" "B" "C"

"Row"                  

 "D"        15   9   7 

 "E"        13  14   9 

 "F"         8   8  17 
----- ----- --- --- ---

If you want to generate the old rmarkdown-style pipe tables, add stlye='rmarkdown' parameter, although AFAIK Pandoc is the new standard there as well, which supports the above multi-line table.

daroczig
  • 28,004
  • 7
  • 90
  • 124
7

I suggest you use stargazer as follows:

  • Use quote=FALSE
  • Make sure to specify type="html"

Try this:

# stargazer

```{r, echo=TRUE, results='asis'}
stargazer(format(f, quote=FALSE, justify="right"), type="html")
```

enter image description here

Andrie
  • 176,377
  • 47
  • 447
  • 496
3

Further digging led me to this question.

The answer is embarrassingly obvious - the 'tables' package!

I thought there had to be a simpler way to do this. Many thanks nonetheless to Andrie and daroczig for their helpful responses.

astaines
  • 872
  • 2
  • 9
  • 20
  • 1
    If you know your output is going to be LaTeX only, it is relatively easy to produce a sophisticated table, otherwise this is not a trivial problem. It is difficult to achieve portability (a complicated table that works in Markdown, HTML, LaTeX, and other formats). – Yihui Xie Sep 02 '14 at 00:33
  • I'm beginning to appreciate this! What you've done already is very impressive, so please accept my thanks for all your work. – astaines Sep 17 '14 at 19:17
1

Consider tbl_cross from the gtsummary package:

library(gtsummary)

set.seed(893)
adf <- data.frame(Col = sample(c('A','B','C'),100,replace=TRUE),
                  Row = sample(c('D','E','F'),100,replace=TRUE))
tbl_cross(adf, row=Row, col=Col, percent="row")

gtsummary tbl_cross HTML crosstab example

patrickmdnet
  • 3,332
  • 1
  • 29
  • 34