Function for simple navigation of dataframe in console
Without changing the interface too much, your code could use the following changes. Note that I am fixing three bugs regarding corner cases:


if your data has fewer than n rows to start with (see where I used min)
if your data has a single column (see where I used drop = FALSE)
make sure that the last page will always show


I avoided duplicating the statements  where begin and end are reset, by creating an increment variable. The code computing the increment (of +n or -n) has been moved to its own function. One improvement I've made is that the function will call itself again via Recall() in case the user entered something other than the expected . or /, i.e. it will prompt the user again.

less &lt;- function(x, n = 10) {
  begin &lt;- 1
  end   &lt;- n

  get_increment &lt;- function() {
    input &lt;- readline("Type . to scroll up, type / to scroll down: ")
    if (input == ".") -n else if (input == "/") +n else Recall()
  }

  repeat {
    print(x[begin:min(end, nrow(x)), , drop = FALSE])

    increment &lt;- get_increment()
    begin     &lt;- begin + increment
    end       &lt;- end   + increment

    if(begin &gt; nrow(x) | end &lt; 1) break
  }
}


Now regarding your design in general, I feel it would be nice to pre-split your data.frame every n rows, and let the user know that there are for example 12 pages and that he is currently looking at page 4/12. In the prompt, also allow the user to jump to a specific page in addition to the next or previous page. Finally, make it easier to exit via a specific code like "q" rather than wait for the user to go beyond the first or last page. Here is my attempt:

less &lt;- function(x, n = 10) {

   N &lt;- nrow(x)
   if (N == 0) {
      message("input has no rows")
      return(NULL)
   }

   row_page_idx &lt;- (seq_len(N) - 1) %/% n
   pages &lt;- split(x, row_page_idx)
   num_pages &lt;- length(pages)
   page_idx &lt;- 1

   get_new_page_idx &lt;- function() {
      input &lt;- readline('Type a page number, "&gt;" for next, "&lt;" for previous, or "q" to quit: ')
      if (input == "q") return(0)
      if (input == "&gt;") return(min(num_pages, page_idx + 1))
      if (input == "&lt;") return(max(1, page_idx - 1))
      integer &lt;- suppressWarnings(as.integer(input))
      if (!is.na(integer) &amp; integer %in% 1:num_pages) return(integer)
      Recall() # if all fails
   }

   repeat {
      print(pages[[page_idx]])
      message("Page ", page_idx, " of ", num_pages)
      page_idx &lt;- get_new_page_idx()
      if(page_idx == 0) break
   }
}