8

I have an R data frame with long column names. So when I print the data frame it is too wide. Is there an easy way to print the data frame to screen with the colnames appearing in multiple lines?

I know that I can shorten the names, but would like not to.

Innuo
  • 436
  • 5
  • 11
  • I don't think there is a way of doing this. I might regret for writing this (as everything seems possible in R). – Arun Feb 18 '13 at 20:30
  • 1
    It's certainly possible but there are a variety of defaults that throw up serious barriers. I would need to see a compelling use case presented (or a really big bounty) to continue the searches and preliminary work I have already wasted, er, expended. – IRTFM Feb 18 '13 at 20:36
  • 1
    make shorter column names. – N8TRO Feb 19 '13 at 00:28
  • @NathanG 's comment was humorous but really is the right answer. Printing "to screen" is not where you want to get into fancy formatting. Use a page layout software tool on the file created by `write.table(your_dataframe,..)` if you want visually appealing results. – Carl Witthoft Feb 19 '13 at 02:07
  • What you can do to make Nathan G comment useful is indeed shorten the column names and maintain a named list (a hash) with newColumnName - realColumnName so than you can get the realName doing `hash["shortName"]` – statquant Feb 19 '13 at 19:57

3 Answers3

2

You could create a custom format.data.frame function, with modifications in the behavior when R finds "long" names:

long <- nchar(cn, "bytes") > 256L
cn[long] <- paste(substr(cn[long], 1L, 250L), "...")
names(rval) <- cn

And since dataframes are printed as matrices after all that pre-processing, lets hope that print.default (actually, the generic print.default) handles escape characters as cat does (printing as is, to get a new line when printing \n).

Edit Actually, print.default escapes unprintable characters (cat online help page)

Character strings are output ‘as is’ (unlike print.default which escapes non-printable characters and backslash [...])

So you should start preparing your own method (also, check options on converting R objects to $$\LaTeX$$ tables, possibly there is an option).

Oscar de León
  • 2,331
  • 16
  • 18
  • I commented above to make shorter column names. I meant it. Abbreviate the column names to a reasonable 6-8 characters and have a key on the side explaining what it is. That way you can manipulate your data much easier, and if necessary, you can change the column names back when you're ready to publish. – N8TRO Feb 20 '13 at 07:59
  • 1
    And I totally agree :) I just wanted to humor Innuo (and show the potential difficulty of the task, should he venture into it). – Oscar de León Feb 20 '13 at 08:02
  • 1
    Ok. +1 for the effort, but Innuo said nothing about LaTeX in the question and reconfiguring R's defaults is almost always a bad idea. – N8TRO Feb 20 '13 at 08:11
  • 1
    Thanks to all for your answers and comments. I suspected it might be a can of worms and I will take the sanity-preserving way out and shorten my column names. – Innuo Feb 20 '13 at 13:42
2

When Oscar's answer was accepted, I thought it might actually have been an answer. Unfortunately all it was was copying the code from format.daa.frame and saying "do some unspecified magic about here". Here is some code that actually does something, although I considered it too rough to post at the time. It still prints the matrix row and column headers. I don't know how to suppress that. Maybe need a hacked print method for matrices?

dfrm <- data.frame(reallly_long.nameeeeeeeeeeeeeeeeeeeeeeee=letters[1:5],
                  secondreallly_long.nameeeeeeeeeeeeeeeeeeeeeeee=letters[1:5], short=2)

pdfrm <- function(dfrm) { # first print the names broken into sections
         print(  unname(t(sapply( 1:(max(nchar(names(dfrm))) %/% 12), 
                   # first construct break points to be passed to `substr`
             function(rr) sapply(names(dfrm), 
                         substr, 1+(rr-1)*10, 9+(rr-1)*10) ) )) ,quote=FALSE, 
                   # then print with sufficient gap
                 print.gap=8)
                   # Now print a headerless data.frame with wider spacing
         print( setNames(dfrm, rep(" ", length(dfrm))), print.gap = 15  )}
 pdfrm(dfrm)
#------------------------------
            [,1]             [,2]             [,3] 
[1,]        reallly_l        secondrea        short
[2,]        ng.nameee        lly_long.             
[3,]        eeeeeeeee        ameeeeeee             

1               a               a               2
2               b               b               2
3               c               c               2
4               d               d               2
5               e               e               2
IRTFM
  • 258,963
  • 21
  • 364
  • 487
1

REMOVING THE MATRIX ROW AND COLUMNS

I somehow edited the code of 42- above to address the problem of removing the matrix row and column indices by creating a modification of the print function. Here's the code:

pdfrm <- function(dfrm) { # first print the names broken into sections
  mprint <- function(Mn){
    rownames(Mn) <- rep("",nrow(Mn))
    colnames(Mn) <- rep("",ncol(M))
    print(as.table(Mn),quote=FALSE,print.gap=8)
  }
  mprint(unname(
    t(sapply( 1:(max(nchar(names(dfrm))) %/% 12), 
              # first construct break points to be passed to `substr`
              function(rr) sapply(names(dfrm), substr, 1+(rr-1)*10, 9+(rr-1)*10) ) )))
  # Now print a headerless data.frame with wider spacing
  print( setNames(dfrm, rep(" ", length(dfrm))), print.gap = 15  )
}
pdfrm(dfrm)

and it ouputs the following:

        reallly_l        secondrea        short
        ng.nameee        lly_long.             
        eeeeeeeee        ameeeeeee             

1               a               a               2
2               b               b               2
3               c               c               2
4               d               d               2
5               e               e               2

The above code could be modified so that it can take care of arbitrary and adaptive spacing.

venrey
  • 175
  • 9