81

I'd like to print nicely-formatted data frames to paper, ideally from within a script. (I am trying to collect data using an instrument and automatically process and print it using an R script).

Right now I can write a data frame to a text file using write.table(), but this has two problems:

  1. The resulting text file is poorly formatted (columns do not necessarily line up with their headings) and
  2. I don't know how to print a text file from within R.

I'm looking more for general strategies than for specific code (although code would be great too!). Would Sweave be the most convenient solution? In principle can I use socketConnection() to print to a printer - and if so, where can I learn about how to use it (I didn't find the documentation to be very helpful).

Frank
  • 66,179
  • 8
  • 96
  • 180
Drew Steen
  • 16,045
  • 12
  • 62
  • 90
  • Are we talking MS Word I assume or is it a LaTeX paper? – Tyler Rinker May 14 '12 at 16:51
  • Do you have LaTeX installed on your computer? I'm thinking a combination of xtable, sweave (or knitr), and possibly this: http://livedocs.adobe.com/acrobat_sdk/10/Acrobat10_HTMLHelp/wwhelp/wwhimpl/common/html/wwhelp.htm?context=Acrobat10_SDK_HTMLHelp&file=DevFAQ_UnderstandingSDK.22.31.html might help. But that does seem a little complex. I'm interested in seeing what others come up with for this. – Dason May 14 '12 at 16:53
  • I actually don't want to place the data frame into a larger document - I just want to have a printed out piece of paper with a legible data frame, which I will then put into my lab notebook as a hard-copy record of the instrument output. – Drew Steen May 14 '12 at 16:59
  • I don't have LaTeX installed on the machine, but I can do it easily enough I suppose. – Drew Steen May 14 '12 at 17:00
  • 1
    `% System(lpr [filename])` , at least in the *nix world, may let you fire up the printer from within R. – Carl Witthoft May 14 '12 at 18:13

10 Answers10

109

Here is a quick and easy possibility using grid.table from the gridExtra package:

library(gridExtra)
pdf("data_output.pdf", height=11, width=8.5)
grid.table(mtcars)
dev.off()

enter image description here

If your data doesn't fit on the page, you can reduce the text size grid.table(mtcars, gp=gpar(fontsize=8)). This may not be very flexible, nor easy to generalize or automate.

bdemarest
  • 14,397
  • 3
  • 53
  • 56
  • @bdemarest, how do you put a title to this graph in pdf? – user1471980 Jan 14 '13 at 17:56
  • @user1471980, One way to do this is `grid.arrange(tableGrob(mtcars, gp=gpar(fontsize=6)), main="Main Title Here.")`. – bdemarest Jan 19 '13 at 20:35
  • Is there a way to print a data frame has a very large number of rows that don't fit in just one page? – Nanami Mar 20 '13 at 23:26
  • 10
    @Nanami, Try something like this: `library(gridExtra); maxrow = 30; npages = ceiling(nrow(iris)/maxrow); pdf("iris_pages.pdf", height=11, width=8.5); for (i in 1:npages) {idx = seq(1+((i-1)*maxrow), i*maxrow); grid.newpage(); grid.table(iris[idx, ])}; dev.off()` – bdemarest Mar 21 '13 at 02:48
  • Trying to set the fontsize gives `Error in gtable_table(d, name = "core", fg_fun = theme$core$fg_fun, bg_fun = theme$core$bg_fun, : unused argument (gp = list(fontsize = 8)` – posdef Aug 03 '16 at 08:59
  • I have this error: Error in gtable_table(d, name = "core", fg_fun = theme$core$fg_fun, bg_fun = theme$core$bg_fun, : could not find function "gpar" any idea? – Medhat Aug 30 '16 at 12:08
  • @MedhatHelmy, @posdef, To access the `gpar` function you can either explicitly load the grid package `library(grid)`, or you can call `grid:::gpar()`. This is caused by changes in the way packages are imported in R in the 4 years since the question was posted. – bdemarest Aug 31 '16 at 18:00
  • @bdemarest I fixed like that t <- ttheme_default(base_size = 5) pdf("data_output.pdf", height=11, width=8.5) grid.table(head(s, n = 20), theme=t) – Medhat Sep 01 '16 at 12:43
  • It would be great if you can include example data for `mtcars` to make your code reproducible. At least, some minimum example. – Léo Léopold Hertz 준영 Oct 30 '16 at 10:12
  • 1
    @Masi, `mtcars` is included in the `datasets` package in a standard R installation. It is loaded by default when you start a new R session. Try typing `?mtcars` and `mtcars` at the R prompt to see what I mean. – bdemarest Oct 31 '16 at 05:04
  • Is there a similar solution for Python? – Harsh Khad Aug 17 '20 at 05:05
16

I would suggest xtable in combination with LaTeX documents. Have a look at the examples in this pdf:

You could also directly combine this with Sweave or knitr.

MERose
  • 4,048
  • 7
  • 53
  • 79
smu
  • 8,757
  • 2
  • 19
  • 14
  • 5
    Please, no link only answer. It would be great to have a minimum code example with reproducible data and example output. – Léo Léopold Hertz 준영 Oct 30 '16 at 10:15
  • I think the criticism should ahve been directed at the questioner. He offered no [MCVE]. The usual justification for not accepting link only answers doesn't seem to apply here. This question is 7 years old and the link to a CRAN-sited vignette appears quite stable. – IRTFM Sep 17 '19 at 01:04
11

Surprised nobody has mentioned the stargazer package for nice printing of data.

You can output a nice-looking text file:

stargazer(mtcars, type = 'text', out = 'out.txt')

============================================
Statistic N   Mean   St. Dev.  Min     Max  
--------------------------------------------
mpg       32 20.091   6.027   10.400 33.900 
cyl       32  6.188   1.786     4       8   
disp      32 230.722 123.939  71.100 472.000
hp        32 146.688  68.563    52     335  
drat      32  3.597   0.535   2.760   4.930 
wt        32  3.217   0.978   1.513   5.424 
qsec      32 17.849   1.787   14.500 22.900 
vs        32  0.438   0.504     0       1   
am        32  0.406   0.499     0       1   
gear      32  3.688   0.738     3       5   
carb      32  2.812   1.615     1       8   
--------------------------------------------

Or even HTML:

stargazer(mtcars, type = 'html', out = 'out.html')

<table style="text-align:center"><tr><td colspan="6" style="border-bottom: 1px solid black"></td></tr><tr><td style="text-align:left">Statistic</td><td>N</td><td>Mean</td><td>St. Dev.</td><td>Min</td><td>Max</td></tr>
<tr><td colspan="6" style="border-bottom: 1px solid black"></td></tr><tr><td style="text-align:left">mpg</td><td>32</td><td>20.091</td><td>6.027</td><td>10.400</td><td>33.900</td></tr>
<tr><td style="text-align:left">cyl</td><td>32</td><td>6.188</td><td>1.786</td><td>4</td><td>8</td></tr>
<tr><td style="text-align:left">disp</td><td>32</td><td>230.722</td><td>123.939</td><td>71.100</td><td>472.000</td></tr>
<tr><td style="text-align:left">hp</td><td>32</td><td>146.688</td><td>68.563</td><td>52</td><td>335</td></tr>
<tr><td style="text-align:left">drat</td><td>32</td><td>3.597</td><td>0.535</td><td>2.760</td><td>4.930</td></tr>
<tr><td style="text-align:left">wt</td><td>32</td><td>3.217</td><td>0.978</td><td>1.513</td><td>5.424</td></tr>
<tr><td style="text-align:left">qsec</td><td>32</td><td>17.849</td><td>1.787</td><td>14.500</td><td>22.900</td></tr>
<tr><td style="text-align:left">vs</td><td>32</td><td>0.438</td><td>0.504</td><td>0</td><td>1</td></tr>
<tr><td style="text-align:left">am</td><td>32</td><td>0.406</td><td>0.499</td><td>0</td><td>1</td></tr>
<tr><td style="text-align:left">gear</td><td>32</td><td>3.688</td><td>0.738</td><td>3</td><td>5</td></tr>
<tr><td style="text-align:left">carb</td><td>32</td><td>2.812</td><td>1.615</td><td>1</td><td>8</td></tr>
<tr><td colspan="6" style="border-bottom: 1px solid black"></td></tr></table>
BLT
  • 2,492
  • 1
  • 24
  • 33
8

The printr package is a good option for printing data.frames, help pages, vignette listings, and dataset listings in knitr documents.

From the documentation page:

options(digits = 4)
set.seed(123)
x = matrix(rnorm(40), 5)
dimnames(x) = list(NULL, head(LETTERS, ncol(x)))
knitr::kable(x, digits = 2, caption = "A table produced by printr.")
jsta
  • 3,216
  • 25
  • 35
  • 1
    I've found this is the best option among all of the answers, if you're looking for printing a dataframe in a knitr-produced pdf. – userABC123 Jan 14 '18 at 16:52
6

The grid.table solution will indeed be the quickest way to create PDF, but this may not be the optimal solution if you have a fairly long table. RStudio + knitr + longtable make it quite easy to create nicely formatted PDFs. What you'll need is something like:

\documentclass{article}
\usepackage{longtable}
\begin{document}

<<results='asis'>>=
library(xtable)

df = data.frame(matrix(rnorm(400), nrow=100))
xt = xtable(df)
print(xt, 
      tabular.environment = "longtable",
      floating = FALSE
      )
@
\end{document}

Pls see this post for more details.

Thusi
  • 929
  • 7
  • 5
5

Not as fancy, but very utilitarian:

print.data.frame(iris)
jclouse
  • 2,289
  • 1
  • 20
  • 25
5

For long/wide tables you could use pander.

It will automatically split long tables into shorter parts that fit the page, e.g. using knitr insert this chunk into your Rmd file:

pander::pander(mtcars)

enter image description here

If you want something that looks more like Excel tables (even with editing options in html) then use rhandsontable. More info about usage and formatting in the vignette. You will need to knit your Rmd into an html file:

library(rhandsontable)
rhandsontable(mtcars, rowHeaders = NULL)

enter image description here

epo3
  • 2,991
  • 2
  • 33
  • 60
4

The RStudio IDE gives another nice option to print out a data.table:

  1. Open the data in the viewer, e.g. View(data_table) or via the GUI
  2. Open the view in a seperate window (icon at the top left corner: "Show in new window")
  3. The seperate window now supports a print dialog (incl. preview)

This works in RStudio V0.98.1103 (and probably newer versions)

kirk
  • 125
  • 1
  • 5
  • It looks like the print dialog for separate windows is gone with RStudio V0.99. – kirk Nov 13 '15 at 07:32
  • 1
    You can still get it by right-clicking the view and selecting "Open Frame" (v0.99.887). – mpe Apr 14 '16 at 15:25
2

I came across this question when looking to do something similar. I found mention of the sink command elsewhere on stackoverflow that was useful in this context:

sink('myfile.txt')
print(mytable,right=F)
sink()
Community
  • 1
  • 1
JamesF
  • 101
  • 1
  • 3
0

If you want to export as a png, you can do like this:

library(gridExtra)
png("test.png", height = 50*nrow(df), width = 200*ncol(df))
grid.table(df)
dev.off()

If you want to export as a pdf, you can do like this:

library(gridExtra)
pdf("test.pdf", height=11, width=10)
grid.table(df)
dev.off()
Ning
  • 514
  • 5
  • 5