Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

My attempt to use a "connection" while trying to read in input causes R to freeze or crash

Tags:

r

rstudio

Sorry, but the terminology I use in the title may not be used correctly. Whenever I try to run this code, it seems like it is trying to run it but never completes the command. When I click the stop command sign (red), it doesn't do anything. I cannot close out of R. So why is this taking forever to run?

con <- file('stdin', open = 'r')

inputs <- readLines(con)
like image 916
Riley Finn Avatar asked Dec 22 '17 19:12

Riley Finn


2 Answers

When working in RStudio, you need to use readLines(stdin()) rather than readLines(file('stdin')), though you can use either if running R in the terminal.

However, there is also an issue from not specifying the number of lines of input since you are using RStudio. When reading input from stdin, Ctrl+D signals the end of input. However, if you are doing this from RStudio rather than from the terminal Ctrl+D is unavailable, so without specifying the lines of input there is no way to terminate the reading from stdin.

So, if you are running R from the terminal, your code will work, and you signal the end of input via Ctrl+D. If you must work from RStudio, you can still use readLines(stdin()) if you know the number of lines of input; e.g.,

> readLines(stdin(), n=2)
Hello
World
[1] "Hello" "World"

An alternate workaround is to use scan(), e.g.:

> scan(,'')
1: Hello
2: World
3: 
Read 2 items
[1] "Hello" "World"

(On the third line I just pressed Enter to terminate input). The advantage there is that you don't need to know the number of lines of input beforehand.

like image 128
duckmayr Avatar answered Sep 22 '22 17:09

duckmayr


RStudio has a somewhat indirect connection to R (At least 4 years ago it redirected stdin to nowhere). It is probably, for our purposes, embedded. This is probably part of why stdin() can work when paired with readLines (It creates a terminal connection rather than a file connection). @duckmayr's scan() solution is quite nice and is documented to be the kind of thing that works in this situation...

the name of a file to read data values from. If the specified file is "", then input is taken from the keyboard (or whatever stdin() reads if input is redirected or R is embedded).

In case you want to consider a blank input 'okay', you can also loop over getting the data from a single line with some sentinel value, i.e. thing that makes the loop stop (here 'EOF').

input <- function() {
  entry <- ''
  while (!any(entry == "EOF")) {
    entry <- c(readline(), entry)  
  }
  return(entry[-1])
}
like image 45
russellpierce Avatar answered Sep 26 '22 17:09

russellpierce