Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Printing R data frame with column names in multiple lines

Tags:

dataframe

r

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.

like image 966
Innuo Avatar asked Feb 18 '13 19:02

Innuo


3 Answers

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
like image 159
IRTFM Avatar answered Nov 01 '22 14:11

IRTFM


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).

like image 26
Oscar de León Avatar answered Nov 01 '22 15:11

Oscar de León


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.

like image 35
venrey Avatar answered Nov 01 '22 14:11

venrey