1

I am using the package Knitr to write a report in latex. I have written the following function in my snippet:

sum <- function(){
  n <- as.numeric(readline("Enter any positive integer"))
  i <- 1:n; s <- sum(i)
  return(s)
}

When I execute it inside the Latex document as:

<<>>
sum()
@

I get this error:

## Enter any positive integer ## 
Error in 1:n: NA/NaN argument

How do I fix the snippet?

Yihui Xie
  • 28,913
  • 23
  • 193
  • 419
SMath
  • 137
  • 6
  • what is the desired output of the function sum() – user12256545 Apr 09 '20 at 22:10
  • 1
    Just curious, is it normal to be able to provide user interaction (`readline`) when a document is being rendered with `knitr`? I thought it was done in a separate process and not really meant for interactive use. (When I run just `readline` within Rscript, it does not prompt me, instead immediately returning an empty string. And `sum(1:"")` provides that error.) – r2evans Apr 09 '20 at 22:16
  • SMath, if you need `any positive integer` to be determined at the time of rendering, you might consider [parameterized rmarkdown](https://rmarkdown.rstudio.com/lesson-6.html) (I wonder if there's a Sweave variant of that concept, sorry I'm not a sweave-regular). – r2evans Apr 09 '20 at 22:18
  • The function returns the sum of the first $n$ positive integers. r2evans, it worked removing user interaction, however, I am going to read the article you sent. Thank you – SMath Apr 09 '20 at 22:26

1 Answers1

1

To be able to input anything interactively, readline() has to be used in an interactive R session, but your Rnw document is compiled in a non-interactive R session (why?)---this is only my guess, since you didn't mention how you compiled the document, and most people probably click the "Knit" button in RStudio, which means the document is compiled in a separate non-interactive R session.

In a non-interactive R session, readline() doesn't allow interactive input, and returns "" immediately, which leads to the error you saw:

> 1:""
Error in 1:"" : NA/NaN argument

If you have any code that requires human interaction (such as inputting numbers), the document has to be compiled in an interactive R session, and the way to do it is to run knitr::knit('your-document.Rnw') in the R console. (For R Markdown users, run rmarkdown::render() instead.)

That said, I don't recommend putting code that requires interaction in a knitr document, because it will make it harder to be reproducible (the result depends on interactive input, which is not predictable).

You may define your function so it doesn't absolutely require human interaction, e.g.,

sum2 <- function(n = as.numeric(readline("Enter any positive integer"))) {
  i <- 1:n; s <- sum(i)
  return(s)
}

Then if you want to call the function in a non-interactive R session, you can pass a value to the argument n, e.g.,

sum2(10)
Yihui Xie
  • 28,913
  • 23
  • 193
  • 419