noqqe
noqqe

Reputation: 172

How to get width of dataframe being printed in terminal in R

Im looking for a way to put a bottom line under a dataframe that I print out in R

The Output looks like

R DataFrame Output

I want to print out the bottom line as long as the dataframe output is. But the width is varying.

Any Idea?

EDIT

I'm trying to get rid of

cat("---------------------------------------\n")

and want to make that dynamic to the output size of a given dataframe. The "-----" line should be not longer or shorter then the dataframe.

Upvotes: 1

Views: 2310

Answers (2)

vaettchen
vaettchen

Reputation: 7659

See how this works. Very simple counting of characters, no bells and whistles, but should do the expected job:

EDIT: Printing of the data.frame and the line done in the function.

# create a function that prints the data.frame with the line we want
lineLength <- function( testDF )
{
  # start with the characters in the row names, 
  #   plus empty space between columns
  dashes <- max( nchar( rownames( testDF ) ) ) + length ( testDF )
  # loop finding the longest string in each column, including header
  for( i in 1 : length ( testDF ) )
  {
    x <- nchar( colnames( testDF ) )[ i ]
    y <- max( nchar( testDF[ , i ] ) )
    if( x > y ) dashes <- dashes + x else dashes <- dashes + y
  }
  myLine <- paste( rep( "-", dashes ),  collapse = "" )
  print( testDF )
  cat( myLine, "\n" )
}

# sample data
data( mtcars )

# see how it works
lineLength( head( mtcars ) )
                   mpg cyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1
-------------------------------------------------------------------- 

Upvotes: 1

Gavin Simpson
Gavin Simpson

Reputation: 174803

Use getOption("width"):

> getOption("width")
[1] 80

You can see a description of this option via ?options which states

‘width’: controls the maximum number of columns on a line used in
     printing vectors, matrices and arrays, and when filling by
     ‘cat’.

That doesn't mean that the entire 80 (in my case) characters are used, but R's printing shouldn't extend beyond that so it should be an upper limit.

You should probably also check this in IDE or other front-ends to R. For example, RStudio might do something different depending on the width of the console widget in their app.

To actually format exactly the correct width for the data frame, you'll need to process the data frame into character strings for each line (much as print.data.frame does via its format method. Something like:

df <- data.frame(Price = round(runif(10), 2),
                 Date = Sys.Date() + 0:9,
                 Subject = rep(c("Foo", "Bar", "DJGHSJIBIBFUIBSFIUBFUIS"),
                               length.out = 10),
                 Category = rep("Media", 10))
class(df) <- c("MyDF", "data.frame")

print.MyDF <- function(x, ...) {
  fdf <- format(x)
  strings <- apply(x, 2, function(x) unlist(format(x)))[1, ]
  rowname <- format(rownames(fdf))[[1]]
  strings <- c(rowname, strings)
  widths <- nchar(strings)
  names <- c("", colnames(x))
  widths <- pmax(nchar(strings), nchar(names))
  csum <- sum(widths + 1) - 1
  print.data.frame(df)
  writeLines(paste(rep("-", csum), collapse = ""))
  writeLines("Balance: 48") ## FIXME !!
  invisible(x)
}

which gives:

> df
   Price       Date                 Subject Category
1   0.73 2015-06-29                     Foo    Media
2   0.11 2015-06-30                     Bar    Media
3   0.19 2015-07-01 DJGHSJIBIBFUIBSFIUBFUIS    Media
4   0.54 2015-07-02                     Foo    Media
5   0.04 2015-07-03                     Bar    Media
6   0.37 2015-07-04 DJGHSJIBIBFUIBSFIUBFUIS    Media
7   0.59 2015-07-05                     Foo    Media
8   0.85 2015-07-06                     Bar    Media
9   0.15 2015-07-07 DJGHSJIBIBFUIBSFIUBFUIS    Media
10  0.05 2015-07-08                     Foo    Media
----------------------------------------------------
Balance: 48

Upvotes: 2

Related Questions