4

Say I want to print a large object in R, such as

x <- 1:2e3

When I print x, the R console fills the screen with its elements and, since it doesn't fit all in the screen, it will scroll down. Then I have to scroll back up to see everything that went off screen.

What I would like is to have a command that would print x and stop when the screen fills, requiring the user to do something (like press enter) in order to have another screen full of data displayed. What I have in mind is something similar to MS DOS's dir /p command. Is there such a thing?

As suggested by @baptiste, this solution, page(x, method = 'print'), doesn't really solve my problem. To be more clear, what I would like is a solution that wouldn't involve printing the object in another window, as this would disrupt my workflow. If I didn't care for this, I'd just use View() or something similar.

Community
  • 1
  • 1
Waldir Leoncio
  • 10,853
  • 19
  • 77
  • 107
  • @baptiste, thanks for the tip, but unfortunately `print(1:2e3, method="print"` doesn't really do what I want, especially considering it doesn't seem to work in RStudio. It's a good workaround for the plain R console, though. – Waldir Leoncio Feb 06 '14 at 18:03
  • The advice in the other page was not to use `print` but to use `page`. – IRTFM Feb 06 '14 at 18:44
  • @IShouldBuyABoat, you're right, and I did use `page`. I mistakenly wrote `print` just here. ;) – Waldir Leoncio Feb 06 '14 at 19:01
  • So you should describe what _does_ happen. "Doesn't seem to work" is incredibly vague, you will agree? (In an R.app GUI session I get a new window with an R expression rather than the output I would have expected. Something similar happens in RStudio on a Mac.) – IRTFM Feb 06 '14 at 19:11
  • @IShouldBuyABoat, fair enough. In RStudio, what happens with `page(x, method = "print")` is that it creates a text file that is opened outside of RStudio (e.g., in Windows' Notepad). In my case, this creates more problems than it solves. My ideal solution would have the object printed in R's console output window. – Waldir Leoncio Feb 06 '14 at 19:16
  • Did you realize there is an option setting?: `getOption("pager") # [1] "/Library/Frameworks/R.framework/Resources/bin/pager"`. I suspect RStudio remaps that option. – IRTFM Feb 06 '14 at 19:41
  • After looking at the code for `page` and `print.default`, I'm seeing this as a woefully underspecified request. The print function is tightly connected with the width option and it's not clear what sort of objects this needs to handle, either. `print` is generic. Type `methods(print)` to see what I mean. – IRTFM Feb 06 '14 at 19:51
  • @IShouldBuyABoat, I've tried to set `options(pager = "console")` and `"internal"`; `"console"` just gives me the unpaused output in the console, and "internal" forces RStudio to print the object in a new internal window (as opposed to outsourcing the task to Notepad). I will take another look at other print methods, but so far I don't see any one that fits. Thank you for the help! – Waldir Leoncio Feb 06 '14 at 20:07

1 Answers1

7

Here is a quick and dirty more function:

more <- function(expr, lines=20) {
    out <- capture.output(expr)
    n <- length(out)
    i <- 1
    while( i < n ) {
        j <- 0
        while( j < lines && i <= n ) {
            cat(out[i],"\n")
            j <- j + 1
            i <- i + 1
        }
        if(i<n) readline()
    }
    invisible(out)
}

It will evaluate the expression and print chunks of lines (default to 20, but you can change that). You need to press 'enter' to move on to the next chunk. Only 'Enter' will work, you can't just use the space bar or other keys like other programs and it does not have options for searching, going back, etc.

You can try it with a command like:

more( rnorm(250) )

Here is an expanded version that will quit if you type 'q' or 'Q' (or anything starting with either) then press 'Enter', it will print out the last lines rows of the output if you type 'T' then enter, and if you type a number it will jump to that decile through the output (e.g. typing 5 will jump to half way through, 8 will be 80% of the way through). Anything else and it will continue.

more <- function(expr, lines=20) {
    out <- capture.output(expr)
    n <- length(out)
    i <- 1
    while( i < n ) {
        j <- 0
        while( j < lines && i <= n ) {
            cat(out[i],"\n")
            j <- j + 1
            i <- i + 1
        }
        if(i<n){
            rl <- readline()
            if( grepl('^ *q', rl, ignore.case=TRUE) ) i <- n
            if( grepl('^ *t', rl, ignore.case=TRUE) ) i <- n - lines + 1
            if( grepl('^ *[0-9]', rl) ) i <- as.numeric(rl)/10*n + 1
        }
    }
    invisible(out)
}
Greg Snow
  • 48,497
  • 6
  • 83
  • 110
  • This is great, but is there a way to insert an escape button? I'm stuck printing a 300k-line data.frame. XD – Waldir Leoncio Feb 06 '14 at 20:10
  • @WaldirLeoncio, The regular methods for interrupting running code should work (clicking the little stop sign in the Windows GUI worked for me). We could expand the functionality by saving the result of `readline` and doing something based on that, e.g. if it is a 'Q' then stop, a 'T' then print the last chunk (Tail), etc. – Greg Snow Feb 06 '14 at 20:22